[pkg-boost-commits] r13935 - in boost-jam: . boost-build boost-build/branches boost-build/branches/upstream boost-build/branches/upstream/current boost-build/branches/upstream/current/build boost-build/branches/upstream/current/debian boost-build/branches/upstream/current/doc boost-build/branches/upstream/current/doc/html boost-build/branches/upstream/current/doc/html/bbv2 boost-build/branches/upstream/current/doc/html/bbv2/advanced boost-build/branches/upstream/current/doc/html/bbv2/advanced/builtins boost-build/branches/upstream/current/doc/html/bbv2/arch boost-build/branches/upstream/current/doc/html/bbv2/extending boost-build/branches/upstream/current/doc/html/bbv2/faq boost-build/branches/upstream/current/doc/html/bbv2/recipies boost-build/branches/upstream/current/doc/html/bbv2/reference boost-build/branches/upstream/current/doc/html/bbv2/tutorial boost-build/branches/upstream/current/doc/html/images boost-build/branches/upstream/current/doc/src boost-build/branches/upstream/current/example boost-build/branches/upstream/current/example/customization boost-build/branches/upstream/current/example/gettext boost-build/branches/upstream/current/example/hello boost-build/branches/upstream/current/example/libraries boost-build/branches/upstream/current/example/libraries/app boost-build/branches/upstream/current/example/libraries/lib1 boost-build/branches/upstream/current/example/libraries/lib1/include boost-build/branches/upstream/current/example/qt boost-build/branches/upstream/current/example/qt-ui boost-build/branches/upstream/current/example/variant boost-build/branches/upstream/current/example/variant/libs boost-build/branches/upstream/current/jam_src boost-build/branches/upstream/current/jam_src/debian boost-build/branches/upstream/current/jam_src/modules boost-build/branches/upstream/current/kernel boost-build/branches/upstream/current/options boost-build/branches/upstream/current/test boost-build/branches/upstream/current/test/dependency-test boost-build/branches/upstream/current/test/dependency-test/src1 boost-build/branches/upstream/current/test/dependency-test/src2 boost-build/branches/upstream/current/test/direct-request-test boost-build/branches/upstream/current/test/generators-test boost-build/branches/upstream/current/test/generators-test/lib boost-build/branches/upstream/current/test/module-actions boost-build/branches/upstream/current/test/prebuilt boost-build/branches/upstream/current/test/prebuilt/ext boost-build/branches/upstream/current/test/prebuilt/ext/debug boost-build/branches/upstream/current/test/prebuilt/ext/release boost-build/branches/upstream/current/test/project-test1 boost-build/branches/upstream/current/test/project-test1/dir boost-build/branches/upstream/current/test/project-test1/dir2 boost-build/branches/upstream/current/test/project-test3 boost-build/branches/upstream/current/test/project-test3/lib boost-build/branches/upstream/current/test/project-test3/lib2 boost-build/branches/upstream/current/test/project-test3/lib2/helper boost-build/branches/upstream/current/test/project-test3/lib3 boost-build/branches/upstream/current/test/project-test4 boost-build/branches/upstream/current/test/project-test4/lib boost-build/branches/upstream/current/test/project-test4/lib2 boost-build/branches/upstream/current/test/railsys boost-build/branches/upstream/current/test/railsys/libx boost-build/branches/upstream/current/test/railsys/libx/include boost-build/branches/upstream/current/test/railsys/libx/src boost-build/branches/upstream/current/test/railsys/program boost-build/branches/upstream/current/test/railsys/program/include boost-build/branches/upstream/current/test/railsys/program/liba boost-build/branches/upstream/current/test/railsys/program/main boost-build/branches/upstream/current/test/startup boost-build/branches/upstream/current/test/startup/boost-root boost-build/branches/upstream/current/test/startup/boost-root/build boost-build/branches/upstream/current/test/startup/bootstrap-env boost-build/branches/upstream/current/test/startup/bootstrap-explicit boost-build/branches/upstream/current/test/startup/bootstrap-implicit boost-build/branches/upstream/current/test/startup/no-bootstrap1 boost-build/branches/upstream/current/test/startup/no-bootstrap1/subdir boost-build/branches/upstream/current/test/startup/no-bootstrap2 boost-build/branches/upstream/current/test/startup/no-bootstrap3 boost-build/branches/upstream/current/test/subdir1 boost-build/branches/upstream/current/test/test2 boost-build/branches/upstream/current/test/testing-primitives boost-build/branches/upstream/current/test/unused boost-build/branches/upstream/current/test/v1-testing boost-build/branches/upstream/current/test/v1_testing boost-build/branches/upstream/current/tools boost-build/branches/upstream/current/util

Domenico Andreoli cavok at costa.debian.org
Thu Dec 22 14:00:20 UTC 2005


Author: cavok
Date: 2005-12-22 14:00:13 +0000 (Thu, 22 Dec 2005)
New Revision: 13935

Added:
   boost-jam/boost-build/
   boost-jam/boost-build/branches/
   boost-jam/boost-build/branches/upstream/
   boost-jam/boost-build/branches/upstream/current/
   boost-jam/boost-build/branches/upstream/current/boost-build.jam
   boost-jam/boost-build/branches/upstream/current/boost.png
   boost-jam/boost-build/branches/upstream/current/bootstrap.jam
   boost-jam/boost-build/branches/upstream/current/build-system.jam
   boost-jam/boost-build/branches/upstream/current/build/
   boost-jam/boost-build/branches/upstream/current/build/alias.jam
   boost-jam/boost-build/branches/upstream/current/build/build-request.jam
   boost-jam/boost-build/branches/upstream/current/build/feature.jam
   boost-jam/boost-build/branches/upstream/current/build/generators.jam
   boost-jam/boost-build/branches/upstream/current/build/modifiers.jam
   boost-jam/boost-build/branches/upstream/current/build/project-roots.jam
   boost-jam/boost-build/branches/upstream/current/build/project.jam
   boost-jam/boost-build/branches/upstream/current/build/property-set.jam
   boost-jam/boost-build/branches/upstream/current/build/property.jam
   boost-jam/boost-build/branches/upstream/current/build/readme.txt
   boost-jam/boost-build/branches/upstream/current/build/scanner.jam
   boost-jam/boost-build/branches/upstream/current/build/targets.jam
   boost-jam/boost-build/branches/upstream/current/build/toolset.jam
   boost-jam/boost-build/branches/upstream/current/build/type.jam
   boost-jam/boost-build/branches/upstream/current/build/version.jam
   boost-jam/boost-build/branches/upstream/current/build/virtual-target.jam
   boost-jam/boost-build/branches/upstream/current/debian/
   boost-jam/boost-build/branches/upstream/current/debian/boost-build.docs
   boost-jam/boost-build/branches/upstream/current/debian/boost-build.examples
   boost-jam/boost-build/branches/upstream/current/debian/changelog
   boost-jam/boost-build/branches/upstream/current/debian/conffiles
   boost-jam/boost-build/branches/upstream/current/debian/control
   boost-jam/boost-build/branches/upstream/current/debian/copyright
   boost-jam/boost-build/branches/upstream/current/debian/excludes
   boost-jam/boost-build/branches/upstream/current/debian/rules
   boost-jam/boost-build/branches/upstream/current/doc/
   boost-jam/boost-build/branches/upstream/current/doc/Jamfile.v2
   boost-jam/boost-build/branches/upstream/current/doc/catalog.xml
   boost-jam/boost-build/branches/upstream/current/doc/development_plan.html
   boost-jam/boost-build/branches/upstream/current/doc/html/
   boost-jam/boost-build/branches/upstream/current/doc/html/HTML.manifest
   boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/
   boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/advanced.html
   boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/advanced/
   boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/advanced/build_process.html
   boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/advanced/builtins/
   boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/advanced/builtins/features.html
   boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/advanced/builtins/targets.html
   boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/advanced/differences_to_v1.html
   boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/advanced/jamfiles.html
   boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/arch.html
   boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/arch/
   boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/arch/build.html
   boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/arch/targets.html
   boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/arch/tools.html
   boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/extender.html
   boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/extending/
   boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/extending/features.html
   boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/extending/rules.html
   boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/extending/targets.html
   boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/extending/tools.html
   boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/extending/toolset_modules.html
   boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/faq.html
   boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/faq/
   boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/faq/dll-path.html
   boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/faq/external.html
   boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/faq/s02.html
   boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/faq/s03.html
   boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/faq/s04.html
   boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/faq/s06.html
   boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/faq/s07.html
   boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/howto.html
   boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/installation.html
   boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/recipies/
   boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/recipies/site-config.html
   boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/reference.html
   boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/reference/
   boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/reference/buildprocess.html
   boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/reference/definitions.html
   boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/reference/generators.html
   boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/reference/jamfiles.html
   boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/tutorial.html
   boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/tutorial/
   boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/tutorial/conditions.html
   boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/tutorial/depends.html
   boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/tutorial/hierarchy.html
   boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/tutorial/libs.html
   boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/tutorial/linkage.html
   boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/tutorial/prebuilt.html
   boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/tutorial/properties.html
   boost-jam/boost-build/branches/upstream/current/doc/html/boostbook.css
   boost-jam/boost-build/branches/upstream/current/doc/html/images/
   boost-jam/boost-build/branches/upstream/current/doc/html/images/blank.png
   boost-jam/boost-build/branches/upstream/current/doc/html/images/caution.png
   boost-jam/boost-build/branches/upstream/current/doc/html/images/draft.png
   boost-jam/boost-build/branches/upstream/current/doc/html/images/home.png
   boost-jam/boost-build/branches/upstream/current/doc/html/images/important.png
   boost-jam/boost-build/branches/upstream/current/doc/html/images/next.png
   boost-jam/boost-build/branches/upstream/current/doc/html/images/note.png
   boost-jam/boost-build/branches/upstream/current/doc/html/images/prev.png
   boost-jam/boost-build/branches/upstream/current/doc/html/images/tip.png
   boost-jam/boost-build/branches/upstream/current/doc/html/images/toc-blank.png
   boost-jam/boost-build/branches/upstream/current/doc/html/images/toc-minus.png
   boost-jam/boost-build/branches/upstream/current/doc/html/images/toc-plus.png
   boost-jam/boost-build/branches/upstream/current/doc/html/images/up.png
   boost-jam/boost-build/branches/upstream/current/doc/html/images/warning.png
   boost-jam/boost-build/branches/upstream/current/doc/html/index.html
   boost-jam/boost-build/branches/upstream/current/doc/project-root.jam
   boost-jam/boost-build/branches/upstream/current/doc/src/
   boost-jam/boost-build/branches/upstream/current/doc/src/advanced.xml
   boost-jam/boost-build/branches/upstream/current/doc/src/architecture.xml
   boost-jam/boost-build/branches/upstream/current/doc/src/catalog.xml
   boost-jam/boost-build/branches/upstream/current/doc/src/extending.xml
   boost-jam/boost-build/branches/upstream/current/doc/src/faq.xml
   boost-jam/boost-build/branches/upstream/current/doc/src/howto.xml
   boost-jam/boost-build/branches/upstream/current/doc/src/install.xml
   boost-jam/boost-build/branches/upstream/current/doc/src/recipes.xml
   boost-jam/boost-build/branches/upstream/current/doc/src/reference.xml
   boost-jam/boost-build/branches/upstream/current/doc/src/tutorial.xml
   boost-jam/boost-build/branches/upstream/current/doc/src/userman.xml
   boost-jam/boost-build/branches/upstream/current/doc/tools.html
   boost-jam/boost-build/branches/upstream/current/doc/tracker.html
   boost-jam/boost-build/branches/upstream/current/example/
   boost-jam/boost-build/branches/upstream/current/example/boost-build.jam
   boost-jam/boost-build/branches/upstream/current/example/customization/
   boost-jam/boost-build/branches/upstream/current/example/customization/Jamfile
   boost-jam/boost-build/branches/upstream/current/example/customization/class.verbatim
   boost-jam/boost-build/branches/upstream/current/example/customization/codegen.cpp
   boost-jam/boost-build/branches/upstream/current/example/customization/inline_file.py
   boost-jam/boost-build/branches/upstream/current/example/customization/project-root.jam
   boost-jam/boost-build/branches/upstream/current/example/customization/readme.txt
   boost-jam/boost-build/branches/upstream/current/example/customization/t1.verbatim
   boost-jam/boost-build/branches/upstream/current/example/customization/t2.verbatim
   boost-jam/boost-build/branches/upstream/current/example/customization/usage.verbatim
   boost-jam/boost-build/branches/upstream/current/example/customization/verbatim.jam
   boost-jam/boost-build/branches/upstream/current/example/gettext/
   boost-jam/boost-build/branches/upstream/current/example/gettext/Jamfile
   boost-jam/boost-build/branches/upstream/current/example/gettext/main.cpp
   boost-jam/boost-build/branches/upstream/current/example/gettext/project-root.jam
   boost-jam/boost-build/branches/upstream/current/example/gettext/readme.txt
   boost-jam/boost-build/branches/upstream/current/example/gettext/russian.po
   boost-jam/boost-build/branches/upstream/current/example/hello/
   boost-jam/boost-build/branches/upstream/current/example/hello/Jamfile
   boost-jam/boost-build/branches/upstream/current/example/hello/hello.cpp
   boost-jam/boost-build/branches/upstream/current/example/hello/project-root.jam
   boost-jam/boost-build/branches/upstream/current/example/libraries/
   boost-jam/boost-build/branches/upstream/current/example/libraries/Jamfile
   boost-jam/boost-build/branches/upstream/current/example/libraries/app/
   boost-jam/boost-build/branches/upstream/current/example/libraries/app/Jamfile
   boost-jam/boost-build/branches/upstream/current/example/libraries/app/app.cpp
   boost-jam/boost-build/branches/upstream/current/example/libraries/lib1/
   boost-jam/boost-build/branches/upstream/current/example/libraries/lib1/Jamfile
   boost-jam/boost-build/branches/upstream/current/example/libraries/lib1/include/
   boost-jam/boost-build/branches/upstream/current/example/libraries/lib1/include/lib1.h
   boost-jam/boost-build/branches/upstream/current/example/libraries/lib1/lib1.cpp
   boost-jam/boost-build/branches/upstream/current/example/libraries/project-root.jam
   boost-jam/boost-build/branches/upstream/current/example/qt-ui/
   boost-jam/boost-build/branches/upstream/current/example/qt-ui/Jamfile
   boost-jam/boost-build/branches/upstream/current/example/qt-ui/hello_world_widget.ui
   boost-jam/boost-build/branches/upstream/current/example/qt-ui/main.cpp
   boost-jam/boost-build/branches/upstream/current/example/qt-ui/project-root.jam
   boost-jam/boost-build/branches/upstream/current/example/qt/
   boost-jam/boost-build/branches/upstream/current/example/qt/Jamfile
   boost-jam/boost-build/branches/upstream/current/example/qt/canvas.cpp
   boost-jam/boost-build/branches/upstream/current/example/qt/canvas.h
   boost-jam/boost-build/branches/upstream/current/example/qt/main.cpp
   boost-jam/boost-build/branches/upstream/current/example/qt/project-root.jam
   boost-jam/boost-build/branches/upstream/current/example/variant/
   boost-jam/boost-build/branches/upstream/current/example/variant/Jamfile
   boost-jam/boost-build/branches/upstream/current/example/variant/a.cpp
   boost-jam/boost-build/branches/upstream/current/example/variant/libs/
   boost-jam/boost-build/branches/upstream/current/example/variant/libs/Jamfile
   boost-jam/boost-build/branches/upstream/current/example/variant/libs/l.cpp
   boost-jam/boost-build/branches/upstream/current/example/variant/project-root.jam
   boost-jam/boost-build/branches/upstream/current/example/variant/readme.txt
   boost-jam/boost-build/branches/upstream/current/hacking.txt
   boost-jam/boost-build/branches/upstream/current/index.html
   boost-jam/boost-build/branches/upstream/current/jam_src/
   boost-jam/boost-build/branches/upstream/current/jam_src/Jam.html
   boost-jam/boost-build/branches/upstream/current/jam_src/Jambase
   boost-jam/boost-build/branches/upstream/current/jam_src/Jambase.html
   boost-jam/boost-build/branches/upstream/current/jam_src/Jamfile.html
   boost-jam/boost-build/branches/upstream/current/jam_src/Porting
   boost-jam/boost-build/branches/upstream/current/jam_src/README
   boost-jam/boost-build/branches/upstream/current/jam_src/RELNOTES
   boost-jam/boost-build/branches/upstream/current/jam_src/boost-jam.spec
   boost-jam/boost-build/branches/upstream/current/jam_src/build.bat
   boost-jam/boost-build/branches/upstream/current/jam_src/build.jam
   boost-jam/boost-build/branches/upstream/current/jam_src/build.sh
   boost-jam/boost-build/branches/upstream/current/jam_src/build_vms.com
   boost-jam/boost-build/branches/upstream/current/jam_src/builtins.c
   boost-jam/boost-build/branches/upstream/current/jam_src/builtins.h
   boost-jam/boost-build/branches/upstream/current/jam_src/bump_version.py
   boost-jam/boost-build/branches/upstream/current/jam_src/class.c
   boost-jam/boost-build/branches/upstream/current/jam_src/class.h
   boost-jam/boost-build/branches/upstream/current/jam_src/command.c
   boost-jam/boost-build/branches/upstream/current/jam_src/command.h
   boost-jam/boost-build/branches/upstream/current/jam_src/compile.c
   boost-jam/boost-build/branches/upstream/current/jam_src/compile.h
   boost-jam/boost-build/branches/upstream/current/jam_src/debian/
   boost-jam/boost-build/branches/upstream/current/jam_src/debian/changelog
   boost-jam/boost-build/branches/upstream/current/jam_src/debian/control
   boost-jam/boost-build/branches/upstream/current/jam_src/debian/copyright
   boost-jam/boost-build/branches/upstream/current/jam_src/debian/jam.man.sgml
   boost-jam/boost-build/branches/upstream/current/jam_src/debian/rules
   boost-jam/boost-build/branches/upstream/current/jam_src/execcmd.h
   boost-jam/boost-build/branches/upstream/current/jam_src/execmac.c
   boost-jam/boost-build/branches/upstream/current/jam_src/execnt.c
   boost-jam/boost-build/branches/upstream/current/jam_src/execunix.c
   boost-jam/boost-build/branches/upstream/current/jam_src/execvms.c
   boost-jam/boost-build/branches/upstream/current/jam_src/expand.c
   boost-jam/boost-build/branches/upstream/current/jam_src/expand.h
   boost-jam/boost-build/branches/upstream/current/jam_src/filemac.c
   boost-jam/boost-build/branches/upstream/current/jam_src/filent.c
   boost-jam/boost-build/branches/upstream/current/jam_src/fileos2.c
   boost-jam/boost-build/branches/upstream/current/jam_src/filesys.c
   boost-jam/boost-build/branches/upstream/current/jam_src/filesys.h
   boost-jam/boost-build/branches/upstream/current/jam_src/fileunix.c
   boost-jam/boost-build/branches/upstream/current/jam_src/filevms.c
   boost-jam/boost-build/branches/upstream/current/jam_src/frames.c
   boost-jam/boost-build/branches/upstream/current/jam_src/frames.h
   boost-jam/boost-build/branches/upstream/current/jam_src/glob.c
   boost-jam/boost-build/branches/upstream/current/jam_src/hash.c
   boost-jam/boost-build/branches/upstream/current/jam_src/hash.h
   boost-jam/boost-build/branches/upstream/current/jam_src/hcache.c
   boost-jam/boost-build/branches/upstream/current/jam_src/hcache.h
   boost-jam/boost-build/branches/upstream/current/jam_src/hdrmacro.c
   boost-jam/boost-build/branches/upstream/current/jam_src/hdrmacro.h
   boost-jam/boost-build/branches/upstream/current/jam_src/headers.c
   boost-jam/boost-build/branches/upstream/current/jam_src/headers.h
   boost-jam/boost-build/branches/upstream/current/jam_src/index.html
   boost-jam/boost-build/branches/upstream/current/jam_src/jam.c
   boost-jam/boost-build/branches/upstream/current/jam_src/jam.h
   boost-jam/boost-build/branches/upstream/current/jam_src/jambase.c
   boost-jam/boost-build/branches/upstream/current/jam_src/jambase.h
   boost-jam/boost-build/branches/upstream/current/jam_src/jamgram.c
   boost-jam/boost-build/branches/upstream/current/jam_src/jamgram.h
   boost-jam/boost-build/branches/upstream/current/jam_src/jamgram.y
   boost-jam/boost-build/branches/upstream/current/jam_src/jamgram.yy
   boost-jam/boost-build/branches/upstream/current/jam_src/jamgramtab.h
   boost-jam/boost-build/branches/upstream/current/jam_src/lists.c
   boost-jam/boost-build/branches/upstream/current/jam_src/lists.h
   boost-jam/boost-build/branches/upstream/current/jam_src/make.c
   boost-jam/boost-build/branches/upstream/current/jam_src/make.h
   boost-jam/boost-build/branches/upstream/current/jam_src/make1.c
   boost-jam/boost-build/branches/upstream/current/jam_src/mkjambase.c
   boost-jam/boost-build/branches/upstream/current/jam_src/modules.c
   boost-jam/boost-build/branches/upstream/current/jam_src/modules.h
   boost-jam/boost-build/branches/upstream/current/jam_src/modules/
   boost-jam/boost-build/branches/upstream/current/jam_src/modules/order.c
   boost-jam/boost-build/branches/upstream/current/jam_src/modules/path.c
   boost-jam/boost-build/branches/upstream/current/jam_src/modules/property-set.c
   boost-jam/boost-build/branches/upstream/current/jam_src/modules/readme.txt
   boost-jam/boost-build/branches/upstream/current/jam_src/modules/regex.c
   boost-jam/boost-build/branches/upstream/current/jam_src/modules/sequence.c
   boost-jam/boost-build/branches/upstream/current/jam_src/modules/set.c
   boost-jam/boost-build/branches/upstream/current/jam_src/native.c
   boost-jam/boost-build/branches/upstream/current/jam_src/native.h
   boost-jam/boost-build/branches/upstream/current/jam_src/newstr.c
   boost-jam/boost-build/branches/upstream/current/jam_src/newstr.h
   boost-jam/boost-build/branches/upstream/current/jam_src/option.c
   boost-jam/boost-build/branches/upstream/current/jam_src/option.h
   boost-jam/boost-build/branches/upstream/current/jam_src/parse.c
   boost-jam/boost-build/branches/upstream/current/jam_src/parse.h
   boost-jam/boost-build/branches/upstream/current/jam_src/patchlevel.h
   boost-jam/boost-build/branches/upstream/current/jam_src/pathmac.c
   boost-jam/boost-build/branches/upstream/current/jam_src/pathsys.h
   boost-jam/boost-build/branches/upstream/current/jam_src/pathunix.c
   boost-jam/boost-build/branches/upstream/current/jam_src/pathvms.c
   boost-jam/boost-build/branches/upstream/current/jam_src/pwd.c
   boost-jam/boost-build/branches/upstream/current/jam_src/pwd.h
   boost-jam/boost-build/branches/upstream/current/jam_src/regexp.c
   boost-jam/boost-build/branches/upstream/current/jam_src/regexp.h
   boost-jam/boost-build/branches/upstream/current/jam_src/rules.c
   boost-jam/boost-build/branches/upstream/current/jam_src/rules.h
   boost-jam/boost-build/branches/upstream/current/jam_src/scan.c
   boost-jam/boost-build/branches/upstream/current/jam_src/scan.h
   boost-jam/boost-build/branches/upstream/current/jam_src/search.c
   boost-jam/boost-build/branches/upstream/current/jam_src/search.h
   boost-jam/boost-build/branches/upstream/current/jam_src/strings.c
   boost-jam/boost-build/branches/upstream/current/jam_src/strings.h
   boost-jam/boost-build/branches/upstream/current/jam_src/subst.c
   boost-jam/boost-build/branches/upstream/current/jam_src/timestamp.c
   boost-jam/boost-build/branches/upstream/current/jam_src/timestamp.h
   boost-jam/boost-build/branches/upstream/current/jam_src/variable.c
   boost-jam/boost-build/branches/upstream/current/jam_src/variable.h
   boost-jam/boost-build/branches/upstream/current/jam_src/w32_getreg.c
   boost-jam/boost-build/branches/upstream/current/jam_src/yyacc.c
   boost-jam/boost-build/branches/upstream/current/kernel/
   boost-jam/boost-build/branches/upstream/current/kernel/boost-build.jam
   boost-jam/boost-build/branches/upstream/current/kernel/bootstrap.jam
   boost-jam/boost-build/branches/upstream/current/kernel/class.jam
   boost-jam/boost-build/branches/upstream/current/kernel/errors.jam
   boost-jam/boost-build/branches/upstream/current/kernel/modules.jam
   boost-jam/boost-build/branches/upstream/current/options/
   boost-jam/boost-build/branches/upstream/current/options/help.jam
   boost-jam/boost-build/branches/upstream/current/site-config.jam
   boost-jam/boost-build/branches/upstream/current/test/
   boost-jam/boost-build/branches/upstream/current/test/BoostBuild.py
   boost-jam/boost-build/branches/upstream/current/test/Jamfile
   boost-jam/boost-build/branches/upstream/current/test/Jamrules
   boost-jam/boost-build/branches/upstream/current/test/TestCmd.py
   boost-jam/boost-build/branches/upstream/current/test/absolute_sources.py
   boost-jam/boost-build/branches/upstream/current/test/alias.py
   boost-jam/boost-build/branches/upstream/current/test/alternatives.py
   boost-jam/boost-build/branches/upstream/current/test/assert-equal.jam
   boost-jam/boost-build/branches/upstream/current/test/bad_dirname.py
   boost-jam/boost-build/branches/upstream/current/test/boost-build.jam
   boost-jam/boost-build/branches/upstream/current/test/build_dir.py
   boost-jam/boost-build/branches/upstream/current/test/c_file.py
   boost-jam/boost-build/branches/upstream/current/test/chain.py
   boost-jam/boost-build/branches/upstream/current/test/check-arguments.jam
   boost-jam/boost-build/branches/upstream/current/test/check-bindrule.jam
   boost-jam/boost-build/branches/upstream/current/test/check-jam-patches.jam
   boost-jam/boost-build/branches/upstream/current/test/check-test-tools.jam
   boost-jam/boost-build/branches/upstream/current/test/composite.py
   boost-jam/boost-build/branches/upstream/current/test/conditionals.py
   boost-jam/boost-build/branches/upstream/current/test/conditionals2.py
   boost-jam/boost-build/branches/upstream/current/test/conditionals3.py
   boost-jam/boost-build/branches/upstream/current/test/core_d12.py
   boost-jam/boost-build/branches/upstream/current/test/core_delete_module.py
   boost-jam/boost-build/branches/upstream/current/test/core_dependencies.py
   boost-jam/boost-build/branches/upstream/current/test/core_import_module.py
   boost-jam/boost-build/branches/upstream/current/test/core_modifiers.py
   boost-jam/boost-build/branches/upstream/current/test/core_typecheck.py
   boost-jam/boost-build/branches/upstream/current/test/core_varnames.py
   boost-jam/boost-build/branches/upstream/current/test/custom_generator.py
   boost-jam/boost-build/branches/upstream/current/test/default_build.py
   boost-jam/boost-build/branches/upstream/current/test/default_features.py
   boost-jam/boost-build/branches/upstream/current/test/dependency-test/
   boost-jam/boost-build/branches/upstream/current/test/dependency-test/Jamfile
   boost-jam/boost-build/branches/upstream/current/test/dependency-test/a.cpp
   boost-jam/boost-build/branches/upstream/current/test/dependency-test/a.h
   boost-jam/boost-build/branches/upstream/current/test/dependency-test/b.cpp
   boost-jam/boost-build/branches/upstream/current/test/dependency-test/b.h
   boost-jam/boost-build/branches/upstream/current/test/dependency-test/c.cpp
   boost-jam/boost-build/branches/upstream/current/test/dependency-test/e.cpp
   boost-jam/boost-build/branches/upstream/current/test/dependency-test/foo.jam
   boost-jam/boost-build/branches/upstream/current/test/dependency-test/project-root.jam
   boost-jam/boost-build/branches/upstream/current/test/dependency-test/src1/
   boost-jam/boost-build/branches/upstream/current/test/dependency-test/src1/a.h
   boost-jam/boost-build/branches/upstream/current/test/dependency-test/src1/b.h
   boost-jam/boost-build/branches/upstream/current/test/dependency-test/src1/c.h
   boost-jam/boost-build/branches/upstream/current/test/dependency-test/src1/z.h
   boost-jam/boost-build/branches/upstream/current/test/dependency-test/src2/
   boost-jam/boost-build/branches/upstream/current/test/dependency-test/src2/b.h
   boost-jam/boost-build/branches/upstream/current/test/dependency-test/x.foo
   boost-jam/boost-build/branches/upstream/current/test/dependency-test/y.foo
   boost-jam/boost-build/branches/upstream/current/test/dependency_property.py
   boost-jam/boost-build/branches/upstream/current/test/dependency_test.py
   boost-jam/boost-build/branches/upstream/current/test/direct-request-test/
   boost-jam/boost-build/branches/upstream/current/test/direct-request-test/Jamfile
   boost-jam/boost-build/branches/upstream/current/test/direct-request-test/Jamfile2
   boost-jam/boost-build/branches/upstream/current/test/direct-request-test/a.cpp
   boost-jam/boost-build/branches/upstream/current/test/direct-request-test/b.cpp
   boost-jam/boost-build/branches/upstream/current/test/direct-request-test/b_inverse.cpp
   boost-jam/boost-build/branches/upstream/current/test/direct-request-test/project-root.jam
   boost-jam/boost-build/branches/upstream/current/test/direct_request_test.py
   boost-jam/boost-build/branches/upstream/current/test/dll_path.py
   boost-jam/boost-build/branches/upstream/current/test/double_loading.py
   boost-jam/boost-build/branches/upstream/current/test/duplicate.py
   boost-jam/boost-build/branches/upstream/current/test/echo_args.jam
   boost-jam/boost-build/branches/upstream/current/test/empty.jam
   boost-jam/boost-build/branches/upstream/current/test/expansion.py
   boost-jam/boost-build/branches/upstream/current/test/explicit.py
   boost-jam/boost-build/branches/upstream/current/test/gcc_runtime.py
   boost-jam/boost-build/branches/upstream/current/test/generators-test/
   boost-jam/boost-build/branches/upstream/current/test/generators-test/Jamfile
   boost-jam/boost-build/branches/upstream/current/test/generators-test/a.cpp
   boost-jam/boost-build/branches/upstream/current/test/generators-test/b.cxx
   boost-jam/boost-build/branches/upstream/current/test/generators-test/c.ui
   boost-jam/boost-build/branches/upstream/current/test/generators-test/d.wd
   boost-jam/boost-build/branches/upstream/current/test/generators-test/e.cpp
   boost-jam/boost-build/branches/upstream/current/test/generators-test/extra.jam
   boost-jam/boost-build/branches/upstream/current/test/generators-test/lex.jam
   boost-jam/boost-build/branches/upstream/current/test/generators-test/lib/
   boost-jam/boost-build/branches/upstream/current/test/generators-test/lib/Jamfile
   boost-jam/boost-build/branches/upstream/current/test/generators-test/lib/c.cpp
   boost-jam/boost-build/branches/upstream/current/test/generators-test/nm.jam
   boost-jam/boost-build/branches/upstream/current/test/generators-test/project-root.jam
   boost-jam/boost-build/branches/upstream/current/test/generators-test/qt.jam
   boost-jam/boost-build/branches/upstream/current/test/generators-test/x.l
   boost-jam/boost-build/branches/upstream/current/test/generators-test/y.x_pro
   boost-jam/boost-build/branches/upstream/current/test/generators-test/z.cpp
   boost-jam/boost-build/branches/upstream/current/test/generators_test.py
   boost-jam/boost-build/branches/upstream/current/test/glob.py
   boost-jam/boost-build/branches/upstream/current/test/inherit_toolset.py
   boost-jam/boost-build/branches/upstream/current/test/inline.py
   boost-jam/boost-build/branches/upstream/current/test/library_chain.py
   boost-jam/boost-build/branches/upstream/current/test/library_order.py
   boost-jam/boost-build/branches/upstream/current/test/library_property.py
   boost-jam/boost-build/branches/upstream/current/test/load_dir.py
   boost-jam/boost-build/branches/upstream/current/test/loop.py
   boost-jam/boost-build/branches/upstream/current/test/m1-01.py
   boost-jam/boost-build/branches/upstream/current/test/m1-02.py
   boost-jam/boost-build/branches/upstream/current/test/m1-03.py
   boost-jam/boost-build/branches/upstream/current/test/make_rule.py
   boost-jam/boost-build/branches/upstream/current/test/module-actions/
   boost-jam/boost-build/branches/upstream/current/test/module-actions/boost-build.jam
   boost-jam/boost-build/branches/upstream/current/test/module-actions/bootstrap.jam
   boost-jam/boost-build/branches/upstream/current/test/module_actions.py
   boost-jam/boost-build/branches/upstream/current/test/ndebug.py
   boost-jam/boost-build/branches/upstream/current/test/no_type.py
   boost-jam/boost-build/branches/upstream/current/test/ordered_properties.py
   boost-jam/boost-build/branches/upstream/current/test/path_features.py
   boost-jam/boost-build/branches/upstream/current/test/prebuilt.py
   boost-jam/boost-build/branches/upstream/current/test/prebuilt/
   boost-jam/boost-build/branches/upstream/current/test/prebuilt/Jamfile
   boost-jam/boost-build/branches/upstream/current/test/prebuilt/ext/
   boost-jam/boost-build/branches/upstream/current/test/prebuilt/ext/Jamfile
   boost-jam/boost-build/branches/upstream/current/test/prebuilt/ext/Jamfile2
   boost-jam/boost-build/branches/upstream/current/test/prebuilt/ext/Jamfile3
   boost-jam/boost-build/branches/upstream/current/test/prebuilt/ext/a.cpp
   boost-jam/boost-build/branches/upstream/current/test/prebuilt/ext/debug/
   boost-jam/boost-build/branches/upstream/current/test/prebuilt/ext/debug/a.h
   boost-jam/boost-build/branches/upstream/current/test/prebuilt/ext/project-root.jam
   boost-jam/boost-build/branches/upstream/current/test/prebuilt/ext/release/
   boost-jam/boost-build/branches/upstream/current/test/prebuilt/ext/release/a.h
   boost-jam/boost-build/branches/upstream/current/test/prebuilt/hello.cpp
   boost-jam/boost-build/branches/upstream/current/test/prebuilt/project-root.jam
   boost-jam/boost-build/branches/upstream/current/test/print.py
   boost-jam/boost-build/branches/upstream/current/test/project-test1.jam
   boost-jam/boost-build/branches/upstream/current/test/project-test1/
   boost-jam/boost-build/branches/upstream/current/test/project-test1/Jamfile
   boost-jam/boost-build/branches/upstream/current/test/project-test1/dir/
   boost-jam/boost-build/branches/upstream/current/test/project-test1/dir/Jamfile
   boost-jam/boost-build/branches/upstream/current/test/project-test1/dir2/
   boost-jam/boost-build/branches/upstream/current/test/project-test1/dir2/Jamfile
   boost-jam/boost-build/branches/upstream/current/test/project-test1/dir2/project-root.jam
   boost-jam/boost-build/branches/upstream/current/test/project-test1/project-root.jam
   boost-jam/boost-build/branches/upstream/current/test/project-test1/project-test1.jam
   boost-jam/boost-build/branches/upstream/current/test/project-test1/readme.txt
   boost-jam/boost-build/branches/upstream/current/test/project-test1/standalone-project.jam
   boost-jam/boost-build/branches/upstream/current/test/project-test3/
   boost-jam/boost-build/branches/upstream/current/test/project-test3/Jamfile
   boost-jam/boost-build/branches/upstream/current/test/project-test3/a.cpp
   boost-jam/boost-build/branches/upstream/current/test/project-test3/lib/
   boost-jam/boost-build/branches/upstream/current/test/project-test3/lib/Jamfile
   boost-jam/boost-build/branches/upstream/current/test/project-test3/lib/b.cpp
   boost-jam/boost-build/branches/upstream/current/test/project-test3/lib2/
   boost-jam/boost-build/branches/upstream/current/test/project-test3/lib2/Jamfile
   boost-jam/boost-build/branches/upstream/current/test/project-test3/lib2/c.cpp
   boost-jam/boost-build/branches/upstream/current/test/project-test3/lib2/d.cpp
   boost-jam/boost-build/branches/upstream/current/test/project-test3/lib2/helper/
   boost-jam/boost-build/branches/upstream/current/test/project-test3/lib2/helper/Jamfile
   boost-jam/boost-build/branches/upstream/current/test/project-test3/lib2/helper/e.cpp
   boost-jam/boost-build/branches/upstream/current/test/project-test3/lib3/
   boost-jam/boost-build/branches/upstream/current/test/project-test3/lib3/Jamfile
   boost-jam/boost-build/branches/upstream/current/test/project-test3/lib3/f.cpp
   boost-jam/boost-build/branches/upstream/current/test/project-test3/lib3/project-root.jam
   boost-jam/boost-build/branches/upstream/current/test/project-test3/project-root.jam
   boost-jam/boost-build/branches/upstream/current/test/project-test3/readme.txt
   boost-jam/boost-build/branches/upstream/current/test/project-test4/
   boost-jam/boost-build/branches/upstream/current/test/project-test4/Jamfile
   boost-jam/boost-build/branches/upstream/current/test/project-test4/Jamfile3
   boost-jam/boost-build/branches/upstream/current/test/project-test4/Jamfile4
   boost-jam/boost-build/branches/upstream/current/test/project-test4/Jamfile5
   boost-jam/boost-build/branches/upstream/current/test/project-test4/a.cpp
   boost-jam/boost-build/branches/upstream/current/test/project-test4/a_gcc.cpp
   boost-jam/boost-build/branches/upstream/current/test/project-test4/lib/
   boost-jam/boost-build/branches/upstream/current/test/project-test4/lib/Jamfile
   boost-jam/boost-build/branches/upstream/current/test/project-test4/lib/Jamfile1
   boost-jam/boost-build/branches/upstream/current/test/project-test4/lib/Jamfile2
   boost-jam/boost-build/branches/upstream/current/test/project-test4/lib/Jamfile3
   boost-jam/boost-build/branches/upstream/current/test/project-test4/lib/b.cpp
   boost-jam/boost-build/branches/upstream/current/test/project-test4/lib2/
   boost-jam/boost-build/branches/upstream/current/test/project-test4/lib2/Jamfile
   boost-jam/boost-build/branches/upstream/current/test/project-test4/lib2/Jamfile2
   boost-jam/boost-build/branches/upstream/current/test/project-test4/project-root.jam
   boost-jam/boost-build/branches/upstream/current/test/project-test4/readme.txt
   boost-jam/boost-build/branches/upstream/current/test/project_dependencies.py
   boost-jam/boost-build/branches/upstream/current/test/project_root.py
   boost-jam/boost-build/branches/upstream/current/test/project_root_constants.py
   boost-jam/boost-build/branches/upstream/current/test/project_test1.py
   boost-jam/boost-build/branches/upstream/current/test/project_test3.py
   boost-jam/boost-build/branches/upstream/current/test/project_test4.py
   boost-jam/boost-build/branches/upstream/current/test/property_expansion.py
   boost-jam/boost-build/branches/upstream/current/test/railsys.py
   boost-jam/boost-build/branches/upstream/current/test/railsys/
   boost-jam/boost-build/branches/upstream/current/test/railsys/libx/
   boost-jam/boost-build/branches/upstream/current/test/railsys/libx/include/
   boost-jam/boost-build/branches/upstream/current/test/railsys/libx/include/test_libx.h
   boost-jam/boost-build/branches/upstream/current/test/railsys/libx/project-root.jam
   boost-jam/boost-build/branches/upstream/current/test/railsys/libx/src/
   boost-jam/boost-build/branches/upstream/current/test/railsys/libx/src/Jamfile
   boost-jam/boost-build/branches/upstream/current/test/railsys/libx/src/test_libx.cpp
   boost-jam/boost-build/branches/upstream/current/test/railsys/program/
   boost-jam/boost-build/branches/upstream/current/test/railsys/program/Jamfile
   boost-jam/boost-build/branches/upstream/current/test/railsys/program/include/
   boost-jam/boost-build/branches/upstream/current/test/railsys/program/include/test_a.h
   boost-jam/boost-build/branches/upstream/current/test/railsys/program/liba/
   boost-jam/boost-build/branches/upstream/current/test/railsys/program/liba/Jamfile
   boost-jam/boost-build/branches/upstream/current/test/railsys/program/liba/test_a.cpp
   boost-jam/boost-build/branches/upstream/current/test/railsys/program/main/
   boost-jam/boost-build/branches/upstream/current/test/railsys/program/main/Jamfile
   boost-jam/boost-build/branches/upstream/current/test/railsys/program/main/main.cpp
   boost-jam/boost-build/branches/upstream/current/test/railsys/program/project-root.jam
   boost-jam/boost-build/branches/upstream/current/test/readme.txt
   boost-jam/boost-build/branches/upstream/current/test/recursive.jam
   boost-jam/boost-build/branches/upstream/current/test/regression.py
   boost-jam/boost-build/branches/upstream/current/test/relative_sources.py
   boost-jam/boost-build/branches/upstream/current/test/searched_lib.py
   boost-jam/boost-build/branches/upstream/current/test/skipping.py
   boost-jam/boost-build/branches/upstream/current/test/stage.py
   boost-jam/boost-build/branches/upstream/current/test/standalone.py
   boost-jam/boost-build/branches/upstream/current/test/startup/
   boost-jam/boost-build/branches/upstream/current/test/startup/boost-root/
   boost-jam/boost-build/branches/upstream/current/test/startup/boost-root/boost-build.jam
   boost-jam/boost-build/branches/upstream/current/test/startup/boost-root/build/
   boost-jam/boost-build/branches/upstream/current/test/startup/boost-root/build/boost-build.jam
   boost-jam/boost-build/branches/upstream/current/test/startup/boost-root/build/bootstrap.jam
   boost-jam/boost-build/branches/upstream/current/test/startup/bootstrap-env/
   boost-jam/boost-build/branches/upstream/current/test/startup/bootstrap-env/boost-build.jam
   boost-jam/boost-build/branches/upstream/current/test/startup/bootstrap-explicit/
   boost-jam/boost-build/branches/upstream/current/test/startup/bootstrap-explicit/boost-build.jam
   boost-jam/boost-build/branches/upstream/current/test/startup/bootstrap-implicit/
   boost-jam/boost-build/branches/upstream/current/test/startup/bootstrap-implicit/readme.txt
   boost-jam/boost-build/branches/upstream/current/test/startup/no-bootstrap1/
   boost-jam/boost-build/branches/upstream/current/test/startup/no-bootstrap1/boost-build.jam
   boost-jam/boost-build/branches/upstream/current/test/startup/no-bootstrap1/subdir/
   boost-jam/boost-build/branches/upstream/current/test/startup/no-bootstrap1/subdir/readme.txt
   boost-jam/boost-build/branches/upstream/current/test/startup/no-bootstrap2/
   boost-jam/boost-build/branches/upstream/current/test/startup/no-bootstrap2/boost-build.jam
   boost-jam/boost-build/branches/upstream/current/test/startup/no-bootstrap3/
   boost-jam/boost-build/branches/upstream/current/test/startup/no-bootstrap3/boost-build.jam
   boost-jam/boost-build/branches/upstream/current/test/startup_v1.py
   boost-jam/boost-build/branches/upstream/current/test/startup_v2.py
   boost-jam/boost-build/branches/upstream/current/test/subdir1/
   boost-jam/boost-build/branches/upstream/current/test/subdir1/file-to-bind
   boost-jam/boost-build/branches/upstream/current/test/suffix.py
   boost-jam/boost-build/branches/upstream/current/test/svn_tree.py
   boost-jam/boost-build/branches/upstream/current/test/symlink.py
   boost-jam/boost-build/branches/upstream/current/test/tag.py
   boost-jam/boost-build/branches/upstream/current/test/template.py
   boost-jam/boost-build/branches/upstream/current/test/test-config-example.jam
   boost-jam/boost-build/branches/upstream/current/test/test.jam
   boost-jam/boost-build/branches/upstream/current/test/test1.py
   boost-jam/boost-build/branches/upstream/current/test/test2.py
   boost-jam/boost-build/branches/upstream/current/test/test2/
   boost-jam/boost-build/branches/upstream/current/test/test2/Jamfile
   boost-jam/boost-build/branches/upstream/current/test/test2/Jamrules
   boost-jam/boost-build/branches/upstream/current/test/test2/foo.cpp
   boost-jam/boost-build/branches/upstream/current/test/test_all.py
   boost-jam/boost-build/branches/upstream/current/test/test_nt_line_length.jam
   boost-jam/boost-build/branches/upstream/current/test/test_system.html
   boost-jam/boost-build/branches/upstream/current/test/testing-primitives/
   boost-jam/boost-build/branches/upstream/current/test/testing-primitives/boost-build.jam
   boost-jam/boost-build/branches/upstream/current/test/testing-primitives/bootstrap.jam
   boost-jam/boost-build/branches/upstream/current/test/testing_primitives.py
   boost-jam/boost-build/branches/upstream/current/test/tree.py
   boost-jam/boost-build/branches/upstream/current/test/unit-tests.jam
   boost-jam/boost-build/branches/upstream/current/test/unit_test.py
   boost-jam/boost-build/branches/upstream/current/test/unit_tests.py
   boost-jam/boost-build/branches/upstream/current/test/unused.py
   boost-jam/boost-build/branches/upstream/current/test/unused/
   boost-jam/boost-build/branches/upstream/current/test/unused/Jamfile
   boost-jam/boost-build/branches/upstream/current/test/unused/a.cpp
   boost-jam/boost-build/branches/upstream/current/test/unused/b.cpp
   boost-jam/boost-build/branches/upstream/current/test/unused/b.x
   boost-jam/boost-build/branches/upstream/current/test/unused/project-root.jam
   boost-jam/boost-build/branches/upstream/current/test/use_requirements.py
   boost-jam/boost-build/branches/upstream/current/test/v1-testing/
   boost-jam/boost-build/branches/upstream/current/test/v1-testing/Jamfile
   boost-jam/boost-build/branches/upstream/current/test/v1-testing/a.cpp
   boost-jam/boost-build/branches/upstream/current/test/v1-testing/b.cpp
   boost-jam/boost-build/branches/upstream/current/test/v1-testing/boost-build.jam
   boost-jam/boost-build/branches/upstream/current/test/v1-testing/c.cpp
   boost-jam/boost-build/branches/upstream/current/test/v1_testing.py
   boost-jam/boost-build/branches/upstream/current/test/v1_testing/
   boost-jam/boost-build/branches/upstream/current/test/v1_testing/Jamfile
   boost-jam/boost-build/branches/upstream/current/test/v1_testing/Jamrules
   boost-jam/boost-build/branches/upstream/current/test/v1_testing/boost-build.jam
   boost-jam/boost-build/branches/upstream/current/test/v1_testing/foo.cpp
   boost-jam/boost-build/branches/upstream/current/test/v1_testing/lib-err.cpp
   boost-jam/boost-build/branches/upstream/current/test/v1_testing/lib.cpp
   boost-jam/boost-build/branches/upstream/current/test/v1_testing/project-root.jam
   boost-jam/boost-build/branches/upstream/current/test/wrapper.py
   boost-jam/boost-build/branches/upstream/current/tools/
   boost-jam/boost-build/branches/upstream/current/tools/bison.jam
   boost-jam/boost-build/branches/upstream/current/tools/boostbook.jam
   boost-jam/boost-build/branches/upstream/current/tools/borland.jam
   boost-jam/boost-build/branches/upstream/current/tools/builtin.jam
   boost-jam/boost-build/branches/upstream/current/tools/common.jam
   boost-jam/boost-build/branches/upstream/current/tools/como-linux.jam
   boost-jam/boost-build/branches/upstream/current/tools/como-win.jam
   boost-jam/boost-build/branches/upstream/current/tools/como.jam
   boost-jam/boost-build/branches/upstream/current/tools/cw.jam
   boost-jam/boost-build/branches/upstream/current/tools/darwin.jam
   boost-jam/boost-build/branches/upstream/current/tools/doxygen.jam
   boost-jam/boost-build/branches/upstream/current/tools/fop.jam
   boost-jam/boost-build/branches/upstream/current/tools/gcc.jam
   boost-jam/boost-build/branches/upstream/current/tools/gettext.jam
   boost-jam/boost-build/branches/upstream/current/tools/intel-linux.jam
   boost-jam/boost-build/branches/upstream/current/tools/intel-win.jam
   boost-jam/boost-build/branches/upstream/current/tools/intel.jam
   boost-jam/boost-build/branches/upstream/current/tools/kylix.jam
   boost-jam/boost-build/branches/upstream/current/tools/lex.jam
   boost-jam/boost-build/branches/upstream/current/tools/make.jam
   boost-jam/boost-build/branches/upstream/current/tools/msvc.jam
   boost-jam/boost-build/branches/upstream/current/tools/qt.jam
   boost-jam/boost-build/branches/upstream/current/tools/rc.jam
   boost-jam/boost-build/branches/upstream/current/tools/stage.jam
   boost-jam/boost-build/branches/upstream/current/tools/stlport.jam
   boost-jam/boost-build/branches/upstream/current/tools/sun.jam
   boost-jam/boost-build/branches/upstream/current/tools/symlink.jam
   boost-jam/boost-build/branches/upstream/current/tools/testing.jam
   boost-jam/boost-build/branches/upstream/current/tools/unix.jam
   boost-jam/boost-build/branches/upstream/current/tools/vacpp.jam
   boost-jam/boost-build/branches/upstream/current/tools/xsltproc.jam
   boost-jam/boost-build/branches/upstream/current/user-config.jam
   boost-jam/boost-build/branches/upstream/current/util/
   boost-jam/boost-build/branches/upstream/current/util/assert.jam
   boost-jam/boost-build/branches/upstream/current/util/container.jam
   boost-jam/boost-build/branches/upstream/current/util/doc.jam
   boost-jam/boost-build/branches/upstream/current/util/indirect.jam
   boost-jam/boost-build/branches/upstream/current/util/numbers.jam
   boost-jam/boost-build/branches/upstream/current/util/order.jam
   boost-jam/boost-build/branches/upstream/current/util/os.jam
   boost-jam/boost-build/branches/upstream/current/util/path.jam
   boost-jam/boost-build/branches/upstream/current/util/print.jam
   boost-jam/boost-build/branches/upstream/current/util/regex.jam
   boost-jam/boost-build/branches/upstream/current/util/sequence.jam
   boost-jam/boost-build/branches/upstream/current/util/set.jam
   boost-jam/boost-build/branches/upstream/current/util/string.jam
   boost-jam/boost-build/branches/upstream/current/util/utility.jam
   boost-jam/boost-build/tags/
Log:
[svn-inject] Installing original source of boost-build

Added: boost-jam/boost-build/branches/upstream/current/boost-build.jam
===================================================================
--- boost-jam/boost-build/branches/upstream/current/boost-build.jam	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/boost-build.jam	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,2 @@
+boost-build kernel ;
+

Added: boost-jam/boost-build/branches/upstream/current/boost.png
===================================================================
(Binary files differ)


Property changes on: boost-jam/boost-build/branches/upstream/current/boost.png
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: boost-jam/boost-build/branches/upstream/current/bootstrap.jam
===================================================================
--- boost-jam/boost-build/branches/upstream/current/bootstrap.jam	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/bootstrap.jam	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,18 @@
+#  Copyright (c) 2003 Vladimir Prus.
+#
+#  Use, modification and distribution is subject to the Boost Software
+#  License Version 1.0. (See accompanying file LICENSE_1_0.txt or
+#  http://www.boost.org/LICENSE_1_0.txt)
+
+# This file handles initial phase of Boost.Build loading.
+# Boost.Jam has already figured out where Boost.Build is
+# and loads this file, which is responsible for initialization
+# of basic facilities such a module system and loading the
+# main Boost.Build module, build-system.jam.
+#
+# Exact operation of this module is not interesting, it makes
+# sense to look at build-system.jam right away.
+
+# Load the kernel/bootstrap.jam, which does all the work.
+.bootstrap-file = $(.bootstrap-file:D)/kernel/bootstrap.jam ;
+include $(.bootstrap-file) ;
\ No newline at end of file

Added: boost-jam/boost-build/branches/upstream/current/build/alias.jam
===================================================================
--- boost-jam/boost-build/branches/upstream/current/build/alias.jam	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/build/alias.jam	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,81 @@
+#  Copyright (C) Vladimir Prus 2003. Permission to copy, use, modify, sell and
+#  distribute this software is granted provided this copyright notice appears in
+#  all copies. This software is provided "as is" without express or implied
+#  warranty, and with no claim as to its suitability for any purpose.
+
+#  This module defines the 'alias' rule and associated class.
+#
+#  Alias is just a main target which returns its source targets without any 
+#  processing. For example::
+#
+#    alias bin : hello test_hello ;
+#    alias lib : helpers xml_parser ;
+#
+#  Another important use of 'alias' is to conveniently group source files::
+#
+#    alias platform-src : win.cpp : <os>NT ;
+#    alias platform-src : linux.cpp : <os>LINUX ;
+#    exe main : main.cpp platform-src ;
+# 
+#  Lastly, it's possible to create local alias for some target, with different
+#  properties::
+#
+#    alias big_lib : : @/external_project/big_lib/<link>static ;
+#
+
+import targets ;
+import "class" : new ;
+import property ;
+import errors : error ;
+import type : type ;
+import regex ;
+import project ;
+
+class alias-target-class : basic-target 
+{
+    rule __init__ ( name : project : sources * : requirements * 
+        : default-build * : usage-requirements * )
+    {
+        basic-target.__init__ $(name) : $(project) : $(sources) : $(requirements) 
+          : $(default-build) : $(usage-requirements) ;
+    }
+        
+    rule construct ( source-targets * : property-set )
+    {
+        return $(source-targets) ;
+    }   
+    
+    # This check makes no sense for 'alias', so just
+    # disable it.
+    rule check-for-link-compatibility ( * : * )
+    {
+    }
+            
+    rule compute-usage-requirements ( subvariant ) 
+    {
+        local base = [ basic-target.compute-usage-requirements $(subvariant) ] ;
+        # Add source's usage requirement. If we don't do this, "alias" does not
+        # look like 100% alias.
+        return [ $(base).add [ $(subvariant).sources-usage-requirements ] ] ;
+    }
+    
+}
+
+# Declares the 'alias' target. It will build sources, and return them unaltered.
+rule alias ( name : sources * : requirements * : default-build * : usage-requirements * )
+{
+    local project = [ project.current ] ;
+    
+    targets.main-target-alternative
+      [ new alias-target-class $(name) : $(project) 
+        : [ targets.main-target-sources $(sources) : $(name) ] 
+        : [ targets.main-target-requirements $(requirements) : $(project) ] 
+        : [ targets.main-target-default-build $(default-build) : $(project) ] 
+        : [ targets.main-target-usage-requirements $(usage-requirements) : $(project) ]           
+      ] ;
+}
+
+IMPORT $(__name__) : alias : : alias ;
+
+
+

Added: boost-jam/boost-build/branches/upstream/current/build/build-request.jam
===================================================================
--- boost-jam/boost-build/branches/upstream/current/build/build-request.jam	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/build/build-request.jam	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,292 @@
+#  (C) Copyright David Abrahams 2002. Permission to copy, use, modify, sell and
+#  distribute this software is granted provided this copyright notice appears in
+#  all copies. This software is provided "as is" without express or implied
+#  warranty, and with no claim as to its suitability for any purpose.
+
+import sequence ;
+import set ;
+import regex ;
+import feature ;
+import property ;
+import numbers ;
+import container ;
+import "class" : new ;
+import string ;
+
+# Transform property-set by applying f to each component property.
+local rule apply-to-property-set ( f property-set )
+{
+    local properties = [ feature.split $(property-set) ] ;
+    return [ string.join [ $(f) $(properties) ] : / ] ;
+}
+
+# expand the given build request by combining all property-sets which don't
+# specify conflicting non-free features.
+rule expand-no-defaults ( property-sets * )
+{
+    # First make all features and subfeatures explicit
+    local expanded-property-sets = [ 
+      sequence.transform apply-to-property-set feature.expand-subfeatures
+        : $(property-sets) ] ;
+    
+    # Now combine all of the expanded property-sets
+    local product = [ x-product $(expanded-property-sets) : $(feature-space) ] ;
+    
+    return $(product) ;
+}
+
+# implementaiton of x-product, below
+local rule x-product-aux ( property-sets + )
+{
+    local result ;
+    local p = [ feature.split $(property-sets[1]) ] ;
+    local f = [ set.difference $(p:G) : [ feature.free-features ] ] ;
+    local seen ;
+    # No conflict with things used at a higher level?
+    if ! [ set.intersection $(f) : $(x-product-used) ]
+    {
+        local x-product-seen ;
+        {
+            # don't mix in any conflicting features
+            local x-product-used = $(x-product-used) $(f) ;
+            
+            if $(property-sets[2])
+            {
+                local rest = [ x-product-aux $(property-sets[2-]) : $(feature-space) ] ;
+                result = $(property-sets[1])/$(rest) ;
+            }
+            
+            result ?= $(property-sets[1]) ;
+        }
+        
+        # If we didn't encounter a conflicting feature lower down,
+        # don't recurse again.
+        if ! [ set.intersection $(f) : $(x-product-seen) ]
+        {
+            property-sets = ;
+        }
+        
+        seen = $(x-product-seen) ;
+    }
+    
+    if $(property-sets[2])
+    {
+        result += [ x-product-aux $(property-sets[2-]) : $(feature-space) ] ;
+    }
+    
+    # Note that we've seen these features so that higher levels will
+    # recurse again without them set.
+    x-product-seen += $(f) $(seen) ;
+    return $(result) ;
+}
+
+# Return the cross-product of all elements of property-sets, less any
+# that would contain conflicting values for single-valued features.
+local rule x-product ( property-sets * )
+{
+    if $(property-sets).non-empty
+    {
+        # prepare some "scoped globals" that can be used by the
+        # implementation function, x-product-aux.
+        local x-product-seen x-product-used ;
+        return [ x-product-aux $(property-sets) : $(feature-space) ] ;
+    }
+    # otherwise return empty
+}
+
+# Returns true if 'v' is either implicit value, or
+# the part before the first '-' symbol is implicit value
+local rule looks-like-implicit-value ( v )
+{
+    
+    if [ feature.is-implicit-value $(v) ]
+    {
+        return true ;
+    }
+    else
+    {
+        local split = [ regex.split $(v) - ] ;
+        if [ feature.is-implicit-value $(split[1]) ]
+        {
+            return true ;
+        }        
+    }
+}
+
+
+# Takes the command line tokens (such as taken from ARGV rule) and constructs
+# build request from it.
+# Returns a vector of two vectors (where "vector" means container.jam's "vector"). 
+# First is the set of targets specified in the command line, and second is
+# the set of requested build properties. 
+rule from-command-line ( command-line * )
+{
+    local targets ;
+    local properties ;
+
+    command-line = $(command-line[2-]) ;
+    for local e in $(command-line)
+    {
+        if ! [ MATCH "^(-).*" : $(e) ] 
+        {
+            # Build request spec either has "=" in it, or completely
+            # consists of implicit feature values.
+            local fs = feature-space ;
+            if [ MATCH "(.*=.*)" : $(e) ] 
+               || [ looks-like-implicit-value $(e:D=) : $(feature-space) ] 
+            {
+                properties += [ convert-command-line-element $(e) : $(feature-space) ] ;
+            }
+            else
+            {
+                targets += $(e) ;
+            }
+        }
+    }
+    return [ new vector [ new vector $(targets) ] [ new vector $(properties) ] ] ;
+}
+
+# Converts one element of command line build request specification into
+# internal form.
+local rule convert-command-line-element ( e )
+{
+    local result ;
+    local parts = [ regex.split $(e) "/" ] ;
+    for local p in $(parts) 
+    {
+        local m = [ MATCH "([^=]*)=(.*)" : $(p) ] ;
+        local lresult ;
+        if $(m) 
+        {
+            local feature = $(m[1]) ;
+            local values = [ regex.split $(m[2]) "," ] ;            
+            lresult = <$(feature)>$(values) ;            
+        }
+        else
+        {
+            lresult = [ regex.split $(p) "," ] ;
+        }
+
+        if ! [ MATCH (.*-.*) : $(p) ]
+        {          
+            # property.validate cannot handle subfeatures,
+            # so we avoid the check here.
+            for local p in $(lresult)
+            {
+                property.validate $(p) : $(feature-space) ;
+            }
+        }
+        
+
+        if ! $(result) 
+        {
+            result = $(lresult) ;
+        }
+        else
+        {
+            result = $(result)/$(lresult) ;
+        }
+    }  
+    
+    return $(result) ;
+}
+
+rule __test__ ( )
+{
+    import assert feature ;
+    
+    feature.prepare-test build-request-test-temp ;
+    
+    import build-request ;
+    import build-request : expand-no-defaults : build-request.expand-no-defaults ;
+    import errors : try catch ;
+    import feature : feature subfeature ;
+
+    feature toolset : gcc msvc borland : implicit ;
+    subfeature toolset gcc : version : 2.95.2 2.95.3 2.95.4
+      3.0 3.0.1 3.0.2 : optional ;
+
+    feature variant : debug release : implicit composite ;
+    feature inlining : on off ;
+    feature "include" : : free ;
+
+    feature stdlib : native stlport : implicit ;
+
+    feature runtime-link : dynamic static : symmetric ;
+
+    # empty build requests should expand to empty.
+    assert.result
+      : build-request.expand-no-defaults
+      ;
+
+    assert.result
+      <toolset>gcc/<toolset-gcc:version>3.0.1/<stdlib>stlport/<variant>debug
+      <toolset>msvc/<stdlib>stlport/<variant>debug
+      <toolset>msvc/<variant>debug 
+
+      : build-request.expand-no-defaults gcc-3.0.1/stlport msvc/stlport msvc debug
+      ;
+
+    assert.result
+      <toolset>gcc/<toolset-gcc:version>3.0.1/<stdlib>stlport/<variant>debug
+      <toolset>msvc/<variant>debug 
+      <variant>debug/<toolset>msvc/<stdlib>stlport
+
+      : build-request.expand-no-defaults gcc-3.0.1/stlport msvc debug msvc/stlport
+      ;
+
+    assert.result
+      <toolset>gcc/<toolset-gcc:version>3.0.1/<stdlib>stlport/<variant>debug/<inlining>off
+      <toolset>gcc/<toolset-gcc:version>3.0.1/<stdlib>stlport/<variant>release/<inlining>off
+
+      : build-request.expand-no-defaults gcc-3.0.1/stlport debug release <inlining>off
+      ;        
+
+    assert.result
+      <include>a/b/c/<toolset>gcc/<toolset-gcc:version>3.0.1/<stdlib>stlport/<variant>debug/<include>x/y/z
+      <include>a/b/c/<toolset>msvc/<stdlib>stlport/<variant>debug/<include>x/y/z
+      <include>a/b/c/<toolset>msvc/<variant>debug/<include>x/y/z 
+
+      : build-request.expand-no-defaults <include>a/b/c gcc-3.0.1/stlport msvc/stlport msvc debug  <include>x/y/z
+      ;
+
+    local r ;
+
+    r = [ build-request.from-command-line bjam debug runtime-link=dynamic ] ;              
+    assert.equal [ $(r).get-at 1 ] : ;
+    assert.equal [ $(r).get-at 2 ] : debug <runtime-link>dynamic ;
+
+    try ;
+    {
+
+        build-request.from-command-line bjam gcc/debug runtime-link=dynamic/static ;
+    }
+    catch \"static\" is not a value of an implicit feature ;
+
+
+    r = [ build-request.from-command-line bjam -d2 --debug debug target runtime-link=dynamic ] ;
+    assert.equal [ $(r).get-at 1 ] : target ;
+    assert.equal [ $(r).get-at 2 ] : debug <runtime-link>dynamic ;
+
+    r = [ build-request.from-command-line bjam debug runtime-link=dynamic,static ] ;
+    assert.equal [ $(r).get-at 1 ] : ;
+    assert.equal [ $(r).get-at 2 ] : debug <runtime-link>dynamic <runtime-link>static ;
+
+    r = [ build-request.from-command-line bjam debug gcc/runtime-link=dynamic,static ] ;
+    assert.equal [ $(r).get-at 1 ] : ;
+    assert.equal [ $(r).get-at 2 ] : debug gcc/<runtime-link>dynamic 
+                 gcc/<runtime-link>static ;
+
+    r = [ build-request.from-command-line bjam msvc gcc,borland/runtime-link=static ] ;
+    assert.equal [ $(r).get-at 1 ] : ;
+    assert.equal [ $(r).get-at 2 ] : msvc gcc/<runtime-link>static 
+                    borland/<runtime-link>static ;
+
+    r = [ build-request.from-command-line bjam gcc-3.0 ] ;
+    assert.equal [ $(r).get-at 1 ] : ;
+    assert.equal [ $(r).get-at 2 ] : gcc-3.0 ;
+
+    feature.finish-test build-request-test-temp ;
+}
+
+

Added: boost-jam/boost-build/branches/upstream/current/build/feature.jam
===================================================================
--- boost-jam/boost-build/branches/upstream/current/build/feature.jam	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/build/feature.jam	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,1218 @@
+#  (C) Copyright David Abrahams 2001. Permission to copy, use, modify, sell and
+#  distribute this software is granted provided this copyright notice appears in
+#  all copies. This software is provided "as is" without express or implied
+#  warranty, and with no claim as to its suitability for any purpose.
+
+import "class" : * ;
+
+import errors : error lol->list ;
+import sequence ;
+import regex ;
+import set ;
+import utility ;
+import modules indirect ;
+import assert : * ;
+
+local rule setup ( )
+{
+    .all-attributes =
+
+      implicit 
+      executed 
+      composite
+      optional 
+      symmetric
+      free      
+      incidental  
+      path  
+      dependency  
+      propagated 
+      link-incompatible
+      subfeature
+      order-sensitive
+      ;
+
+    .all-features = ;
+    .all-subfeatures = ; # non-subfeatures
+    .all-top-features = ; # non-subfeatures
+    .all-implicit-values = ;
+}
+setup ;
+
+# prepare a fresh space to test in by moving all global variable
+# settings into the given temporary module and erasing them here.
+rule prepare-test ( temp-module )
+{
+    DELETE_MODULE $(temp-module) ;
+    
+    # transfer globals to temp-module
+    for local v in [ VARNAMES feature ]
+    {
+        if [ MATCH (\\.) : $(v) ]
+        {
+            modules.poke $(temp-module) : $(v) : $($(v)) ;
+            $(v) = ;
+        }
+    }
+    setup ;
+}
+
+# clear out all global variables and recover all variables from the
+# given temporary module
+rule finish-test ( temp-module )
+{
+    # clear globals
+    for local v in [ VARNAMES feature ]
+    {
+        if [ MATCH (\\.) : $(v) ]
+        {
+            $(v) = ;
+        }
+    }
+    
+    for local v in [ VARNAMES $(temp-module) ]
+    {
+        $(v) = [ modules.peek $(temp-module) : $(v) ] ;
+    }
+    DELETE_MODULE $(temp-module) ;
+}
+
+
+# Transform features by bracketing any elements which aren't already
+# bracketed by "<>"
+local rule grist ( features * )
+{
+    local empty = "" ;
+    local r = $(empty:G=$(features)) ;
+    return $(r) ;
+}
+
+empty = "" ;
+
+# declare a new feature with the given name, values, and attributes.
+rule feature ( 
+    name         # feature name
+  : values *     # the allowable values - may be extended later with feature.extend
+  : attributes * # The feature's attributes (e.g. implicit, free, propagated...)
+)
+{
+    name = [ grist $(name) ] ;
+
+    local error ;
+
+    # if there are any unknown attributes...
+    if ! ( $(attributes) in $(.all-attributes) )
+    {
+        error = unknown attributes:
+          [ set.difference $(attributes) : $(.all-attributes) ] ;
+    }
+    else if $(name) in $(.all-features)
+    {
+        error = feature already defined: ;
+    }
+    else if implicit in $(attributes) && free in $(attributes)
+    {
+        error = free features cannot also be implicit ;
+    }
+    else if free in $(attributes) && propagated in $(attributes)
+    {            
+        error = free features cannot be propagated ;
+    }           
+    
+
+    if $(error)
+    {
+        error $(error)
+          : "in" feature declaration:
+          : feature [ lol->list $(1) : $(2) : $(3) ] ;
+    }
+
+    $(name).values ?= ;
+    $(name).attributes = $(attributes) ;
+    $(name).subfeatures ?= ;
+    $(attributes).features += $(name) ;
+
+    .all-features += $(name) ;
+    if subfeature in $(attributes)
+    {
+        .all-subfeatures += $(name) ;
+    }
+    else
+    {
+        .all-top-features += $(name) ;
+    }
+    extend $(name) : $(values) ;    
+}
+
+# set default value of the given feature, overriding any previous
+# default.
+rule set-default ( feature : value )
+{
+    local f = [ grist $(feature) ] ;
+    if ! $(value) in $($(f).values) 
+    {
+        errors.error "The specified default value, '$(value)' is invalid" 
+          : "allowed values are: " $($(f).values) ;
+    }    
+    $(f).default = $(value) ;
+}
+
+
+# return the default property values for the given features.
+rule defaults ( features * )
+{
+    local result ;
+    for local f in $(features)
+    {
+        local a = $($(f).attributes) ;
+        if ( free in $(a) ) || ( optional in $(a) )
+        {
+        }
+        else
+        {
+            result += $(f)$($(f).default) ;
+        }
+    }
+    return $(result) ;
+}
+
+# returns true iff all elements of names are valid features.
+rule valid ( names + )
+{
+    if $(names) in $(.all-features)
+    {
+        return true ;
+    }
+}
+
+# return the attibutes of the given feature
+rule attributes ( feature )
+{
+    if ! [ valid $(feature) ]
+    {
+        error \"$(feature)\" is not a valid feature name ;
+    }
+    return $($(feature).attributes) ;
+}
+
+# return the values of the given feature
+rule values ( feature )
+{
+    return $($(feature).values) ;
+}
+
+# returns true iff 'value-string' is a value-string of an implicit feature
+rule is-implicit-value ( value-string )
+{
+    local v = [ regex.split $(value-string) - ] ;
+    local failed ;
+    if ! $(v[1]) in $(.all-implicit-values) 
+    {
+        failed = true ;
+    }
+    else 
+    {
+        local feature = $($(v[1]).implicit-feature) ;
+        
+        for local subvalue in $(v[2-])
+        {
+            if ! [ find-implied-subfeature $(feature) $(subvalue) : $(v[1]) ]
+            {
+                failed = true ;
+            }
+        }
+    }
+    
+    if ! $(failed)       
+    {
+        return true ;
+    }
+}
+
+# return the implicit feature associated with the given implicit value.
+rule implied-feature ( implicit-value )
+{
+    local components = [ regex.split $(implicit-value) "-" ] ;
+    
+    local feature = $($(components[1]).implicit-feature) ;
+    if ! $(feature)
+    {
+        error \"$(implicit-value)\" is not a value of an implicit feature ;
+        feature = "" ; # keep testing happy; it expects a result.
+    }
+    return $(feature) ;
+}
+
+local rule find-implied-subfeature ( feature subvalue : value-string ? )
+{
+    # feature should be of the form <feature-name>
+    if $(feature) != $(feature:G)
+    {
+        error invalid feature $(feature) ;
+    }
+
+    return $($(feature)$(value-string:E="")<>$(subvalue).subfeature) ;
+}
+
+# Given a feature and a value of one of its subfeatures, find the name
+# of the subfeature. If value-string is supplied, looks for implied
+# subfeatures that are specific to that value of feature
+rule implied-subfeature ( 
+  feature               # The main feature name
+    subvalue            # The value of one of its subfeatures
+    : value-string ?    # The value of the main feature
+)
+{
+    local subfeature = [ find-implied-subfeature $(feature) $(subvalue)
+      : $(value-string) ] ;
+
+    if ! $(subfeature)
+    {
+        value-string ?= "" ;
+        error \"$(subvalue)\" is not a known subfeature value of
+          $(feature)$(value-string) ;
+    }
+
+    return $(subfeature) ;
+}
+
+# generate an error if the feature is unknown
+local rule validate-feature ( feature )
+{
+    if ! $(feature) in $(.all-features)
+    {
+        error unknown feature \"$(feature)\" ;
+    }
+}
+
+# Given a feature and value, or just a value corresponding to an
+# implicit feature, returns a property set consisting of all component
+# subfeatures and their values. For example:
+#
+#   expand-subfeatures <toolset>gcc-2.95.2-linux-x86
+#       -> <toolset>gcc <toolset-version>2.95.2 <toolset-os>linux <toolset-cpu>x86
+#
+#   equivalent to:
+#       expand-subfeatures gcc-2.95.2-linux-x86
+local rule expand-subfeatures-aux ( 
+    feature ? # The name of the feature, or empty if value corresponds to an implicit property
+  : value     # The value of the feature.
+  : dont-validate ? # If set, no validation of value string will be done  
+)
+{
+    if $(feature)
+    {
+        feature = $(feature) ;
+    }
+
+    if ! $(feature)
+    {
+        feature = [ implied-feature $(value) ] ;
+    }
+    else
+    {
+        validate-feature $(feature) ;
+    }
+    if ! $(dont-validate)
+    {        
+        validate-value-string $(feature) $(value) ;
+    }
+    
+    local components = [ regex.split $(value) "-" ] ;
+    
+    # get the top-level feature's value
+    local value = $(components[1]:G=) ;
+
+    local result = $(components[1]:G=$(feature)) ;
+    
+    local subvalues = $(components[2-]) ;
+    while $(subvalues)
+    {
+        local subvalue = $(subvalues[1]) ; # pop the head off of subvalues
+        subvalues = $(subvalues[2-]) ;
+        
+        local subfeature = [ find-implied-subfeature $(feature) $(subvalue) : $(value) ] ;
+        
+        # If no subfeature was found, reconstitute the value string and use that
+        if ! $(subfeature)
+        {
+            result = $(components:J=-) ;
+            result = $(result:G=$(feature)) ;
+            subvalues = ; # stop looping
+        }
+        else
+        {
+            local f = [ MATCH ^<(.*)>$ : $(feature) ] ;
+            result += $(subvalue:G=$(f)-$(subfeature)) ;
+        }
+    }
+    
+    return $(result) ;
+}
+
+# Make all elements of properties corresponding to implicit features
+# explicit, and express all subfeature values as separate properties
+# in their own right. For example, the property
+#
+#    gcc-2.95.2-linux-x86
+#
+# might expand to
+#
+#   <toolset>gcc <toolset-version>2.95.2 <toolset-os>linux <toolset-cpu>x86
+#
+rule expand-subfeatures ( 
+  properties * # property set with elements of the form
+           # <feature>value-string or just value-string in the
+           # case of implicit features.
+  : dont-validate ?
+)
+{
+    local result ;
+    for local p in $(properties)
+    {
+        # Don't expand subfeatures in subfeatures
+        if ! [ MATCH "(:)" : $(p:G) ]
+        {            
+            result += [ expand-subfeatures-aux $(p:G) : $(p:G=) : $(dont-validate) ] ;
+        }
+        else
+        {
+            result += $(p) ;
+        }        
+    }
+    return $(result) ;
+}
+
+# Helper for extend, below. Handles the feature case.
+local rule extend-feature ( feature : values * )
+{
+    feature = [ grist $(feature) ] ;
+    validate-feature $(feature) ;
+    if implicit in $($(feature).attributes)
+    {
+        for local v in $(values)
+        {
+            if $($(v).implicit-feature)
+            {
+                error $(v) is already associated with the \"$($(v).implicit-feature)\" feature ;
+            }
+            $(v).implicit-feature = $(feature) ;
+        }
+
+        .all-implicit-values += $(values) ;
+    }
+    if ! $($(feature).values)
+    {
+        # This is the first value specified for this feature,
+        # take it as default value
+        $(feature).default = $(values[1]) ;
+    }    
+    $(feature).values += $(values) ;
+}
+
+# Checks that value-string is a valid value-string for the given feature.
+rule validate-value-string ( feature value-string )
+{    
+    if ! ( 
+      free in $($(feature).attributes) 
+      || ( $(value-string) in $(feature).values )
+    )
+    {
+        local values = $(value-string) ;
+    
+        if $($(feature).subfeatures)
+        {
+            values = [ regex.split $(value-string) - ] ;
+        }
+
+        if ! ( $(values[1]) in $($(feature).values) )
+        {
+            error \"$(values[1])\" is not a known value of feature $(feature)
+              : legal values: \"$($(feature).values)\" ;
+        }
+
+        for local v in $(values[2-])
+        {
+            # this will validate any subfeature values in value-string
+            implied-subfeature $(feature) $(v) : $(values[1]) ;
+        }
+    }
+}
+
+# Extends the given subfeature with the subvalues.  If the optional
+# value-string is provided, the subvalues are only valid for the given
+# value of the feature. Thus, you could say that
+# <target-platform>mingw is specifc to <toolset>gcc-2.95.2 as follows:
+#
+#       extend-subfeature toolset gcc-2.95.2 : target-platform : mingw ;
+#
+rule extend-subfeature ( 
+  feature           # The feature whose subfeature is being extended
+    
+    value-string ?  # If supplied, specifies a specific value of the
+                    # main feature for which the new subfeature values
+                    # are valid
+    
+    : subfeature    # The name of the subfeature
+    : subvalues *   # The additional values of the subfeature being defined.
+)
+{
+    feature = [ grist $(feature) ] ;
+    validate-feature $(feature) ;
+    if $(value-string)
+    {
+        validate-value-string $(feature) $(value-string) ;
+    }
+
+    local subfeature-name = [ get-subfeature-name $(subfeature) $(value-string) ] ;
+    
+    local f = [ utility.ungrist $(feature) ] ;
+    extend $(f)-$(subfeature-name) : $(subvalues) ;
+    
+    # provide a way to get from the given feature or property and
+    # subfeature value to the subfeature name.
+    $(feature)$(value-string:E="")<>$(subvalues).subfeature = $(subfeature-name) ;
+}
+
+# Can be called three ways:
+#
+#    1. extend feature : values *
+#    2. extend <feature> subfeature : values *
+#    3. extend <feature>value-string subfeature : values *
+#
+# * Form 1 adds the given values to the given feature
+# * Forms 2 and 3 add subfeature values to the given feature
+# * Form 3 adds the subfeature values as specific to the given
+#   property value-string.
+#
+rule extend ( feature-or-property subfeature ? : values * )
+{
+    local
+      feature           # If a property was specified this is its feature
+      value-string      # E.G., the gcc-2.95-2 part of <toolset>gcc-2.95.2
+      ;
+
+    # if a property was specified
+    if $(feature-or-property:G) && $(feature-or-property:G=)
+    {
+        # Extract the feature and value-string, if any.
+        feature = $(feature-or-property:G) ;
+        value-string = $(feature-or-property:G=) ;
+    }
+    else
+    {
+        feature = [ grist $(feature-or-property) ] ;
+    }
+
+    # Dispatch to the appropriate handler
+    if $(subfeature)
+    {
+        extend-subfeature $(feature) $(value-string)
+          : $(subfeature) : $(values) ;
+    }
+    else
+    {
+        # If no subfeature was specified, we didn't expect to see a
+        # value-string
+        if $(value-string)
+        {
+            error can only be specify a property as the first argument
+              when extending a subfeature
+              : usage:
+              : "    extend" feature ":" values...
+              : "  | extend" <feature>value-string subfeature ":" values...
+              ;
+        }
+
+        extend-feature $(feature) : $(values) ;
+    }
+}
+
+local rule get-subfeature-name ( subfeature value-string ? )
+{
+    local prefix = $(value-string): ;
+    return $(prefix:E="")$(subfeature) ;
+}
+
+# Declares a subfeature
+rule subfeature ( 
+  feature        # Root feature that is not a subfeature
+  value-string ? # A value-string specifying which feature or
+                 # subfeature values this subfeature is specific to,
+                 # if any
+    
+  : subfeature   # The name of the subfeature being declared
+  : subvalues *  # The allowed values of this subfeature
+  : attributes * # The attributes of the subfeature
+)
+{
+    feature = [ grist $(feature) ] ;
+    validate-feature $(feature) ;
+    
+    # Add grist to the subfeature name if a value-string was supplied
+    local subfeature-name = [ get-subfeature-name $(subfeature) $(value-string) ] ;
+    
+    if $(subfeature-name) in $($(feature).subfeatures)
+    {
+        error \"$(subfeature)\" already declared as a subfeature of \"$(feature)\" 
+          "specific to "$(value-string) ;
+    }
+    $(feature).subfeatures += $(subfeature-name) ;
+    
+    # First declare the subfeature as a feature in its own right
+    local f = [ utility.ungrist $(feature) ] ;
+    feature $(f)-$(subfeature-name) : $(subvalues) : $(attributes) subfeature ;
+    
+    # Now make sure the subfeature values are known.
+    extend-subfeature $(feature) $(value-string) : $(subfeature) : $(subvalues) ;
+}
+
+# Set the components of the given composite property
+rule compose ( composite-property : component-properties * )
+{
+    local feature = $(composite-property:G) ;
+    if ! ( composite in [ attributes $(feature) ] )
+    {
+        error "$(feature)" is not a composite feature ;
+    }
+
+    $(composite-property).components ?= ;
+    if $($(composite-property).components)
+    {
+        error components of "$(composite-property)" already set:
+                $($(composite-property).components) ;
+    }
+
+    if $(composite-property) in $(components)
+    {
+        errror composite property "$(composite-property)" cannot have itself as a component ;
+    }
+    $(composite-property).components = $(component-properties) ;
+}
+
+local rule has-attribute ( attribute property )
+{
+    if $(attribute) in [ attributes [ get-feature $(property) ] ]
+    {
+        return true ;
+    }
+}
+
+local rule expand-composite ( property )
+{
+    return $(property)
+      [ sequence.transform expand-composite : $($(property).components) ] ;
+}
+
+# return all values of the given feature specified by the given property set.
+rule get-values ( feature : properties * )
+{
+    local result ;
+    for local p in $(properties)
+    {
+        if $(p:G) = $(feature)
+        {
+            result += $(p:G=) ;
+        }
+    }
+    return $(result) ;
+}
+
+rule free-features ( )
+{
+    return $(free.features) ;
+}
+
+# Expand all composite properties in the set so that all components
+# are explicitly expressed.
+rule expand-composites ( properties * )
+{
+    local explicit-features = $(properties:G) ;
+
+    local result ;
+    # now expand composite features
+    for local p in $(properties)
+    {
+        local expanded = [ expand-composite $(p) ] ;
+        
+        for local x in $(expanded)
+        {
+            if ! $(x) in $(result)
+            {
+                local f = $(x:G) ;
+                
+                if $(f) in $(free.features)
+                {
+                    result += $(x) ;
+                }
+                else if ! $(x) in $(properties)  # x is the result of expansion
+                {
+                    if ! $(f) in $(explicit-features)  # not explicitly-specified
+                    {
+                        if $(f) in $(result:G)
+                        {
+                            error expansions of composite features result in conflicting 
+                              values for $(f)
+                                : values: [ get-values $(f) : $(result) ] $(x:G=) 
+                                  : one contributing composite property was $(p) ;
+                        }
+                        else
+                        {
+                            result += $(x) ;
+                        }
+                    }
+                }                
+                else if $(f) in $(result:G)
+                {
+                    error explicitly-specified values of non-free feature
+                      $(f) conflict :
+                        "existing values:" [ get-values $(f) : $(properties) ] :
+                        "value from expanding " $(p) ":" (x:G=) ;
+                }
+                else
+                {
+                    result += $(x) ;
+                }
+            }            
+        }
+    }
+    return $(result) ;
+}
+
+# Return true iff f is an ordinary subfeature of the parent-property's
+# feature, or if f is a subfeature fo the parent-property's feature
+# specific to the parent-property's value
+local rule is-subfeature-of ( parent-property f )
+{
+    if subfeature in $($(f).attributes)
+    {
+        local specific-subfeature = [ MATCH <(.*):(.*)> : $(f) ] ;
+        if $(specific-subfeature)
+        {
+            # The feature has the form
+            # <topfeature-topvalue:subfeature>,
+            # e.g. <toolset-msvc:version>
+            local feature-value = [ split-top-feature $(specific-subfeature[1]) ] ;
+            if <$(feature-value[1])>$(feature-value[2]) = $(parent-property)
+            {
+                return true ;
+            }
+        }
+        else
+        {
+            # The feature has the form <topfeature-subfeature>,
+            # e.g. <toolset-version>
+            local top-sub = [ split-top-feature [ utility.ungrist $(f) ] ] ;
+            
+            if $(top-sub[2]) && <$(top-sub[1])> = $(parent-property:G)
+            {
+                return true ;
+            }
+        }
+    }
+}
+
+# as above, for subproperties
+local rule is-subproperty-of ( parent-property p )
+{
+    return [ is-subfeature-of $(parent-property) $(p:G) ] ;
+}
+
+# Given a property, return the subset of features consisting of all
+# ordinary subfeatures of the property's feature, and all specific
+# subfeatures of the property's feature which are conditional on the
+# property's value.
+local rule select-subfeatures ( parent-property : features * )
+{
+    return [ sequence.filter is-subfeature-of $(parent-property) : $(features) ] ;
+}
+  
+# as above, for subproperties
+local rule select-subproperties ( parent-property : properties * )
+{
+    return [ sequence.filter is-subproperty-of $(parent-property) : $(properties) ] ;
+}
+
+# Given a property set which may consist of composite and implicit
+# properties and combined subfeature values, returns an expanded,
+# normalized property set with all implicit features expressed
+# explicitly, all subfeature values individually expressed, and all
+# components of composite properties expanded. Non-free features
+# directly expressed in the input properties cause any values of
+# those features due to composite feature expansion to be dropped. If
+# two values of a given non-free feature are directly expressed in the
+# input, an error is issued.
+rule expand ( properties * )
+{
+    local expanded = [ expand-subfeatures $(properties) ] ;
+
+    return [ expand-composites $(expanded) ] ;
+}
+
+
+# Helper rule for minimize, below - return true iff property's feature
+# is present in the contents of the variable named by feature-set-var.
+local rule in-features ( feature-set-var property )
+{
+    if $(property:G) in $($(feature-set-var))
+    {
+        return true ;
+    }
+}
+
+# Helper for minimize, below - returns the list with
+# the same properties, but where all subfeatures
+# are in the end of the list
+local rule move-subfeatures-to-the-end ( properties * )
+{
+    local x1 ;
+    local x2 ;
+    for local p in $(properties)
+    {
+        if subfeature in $($(p:G).attributes)
+        {
+            x2 += $(p) ;
+        }
+        else
+        {
+            x1 += $(p) ;
+        }                
+    }
+    return $(x1) $(x2) ;    
+}
+
+
+# Given an expanded property set, eliminate all redundancy: properties
+# which are elements of other (composite) properties in the set will
+# be eliminated. Non-symmetric properties equal to default values will be
+# eliminated, unless the override a value from some composite property.
+# Implicit properties will be expressed without feature
+# grist, and sub-property values will be expressed as elements joined
+# to the corresponding main property.
+rule minimize ( properties * )
+{
+    # Precondition checking
+    local implicits = [ set.intersection $(p:G=) : $(p:G) ] ;
+    if $(implicits)
+    {
+        error minimize requires an expanded property set, but \"$(implicits[1])\"
+          appears to be the value of an un-expanded implicit feature ;
+    }
+        
+    # remove properties implied by composite features
+    local components = $($(properties).components) ;
+    local x = [ set.difference $(properties) : $(components) ] ;
+    
+    # handle subfeatures and implicit features
+    x = [ move-subfeatures-to-the-end $(x) ] ;    
+    local result ;
+    while $(x)
+    {
+        local p fullp = $(x[1]) ;
+        local f = $(p:G) ;
+        local v = $(p:G=) ;
+        
+        # eliminate features in implicit properties.
+        if implicit in [ attributes $(f) ]
+        {
+            p = $(v) ;
+        }
+
+        # locate all subproperties of $(x[1]) in the property set
+        local subproperties = [ select-subproperties $(fullp) : $(x) ] ;
+        if $(subproperties)
+        {
+            # reconstitute the joined property name
+            local sorted = [ sequence.insertion-sort $(subproperties) ] ;
+            result += $(p)-$(sorted:G="":J=-) ;
+
+            x = [ set.difference $(x[2-]) : $(subproperties) ] ;
+        }
+        else
+        {
+            # eliminate properties whose value is equal to feature's
+            # default and which are not symmetric and which do not
+            # contradict values implied by composite properties.
+            
+            # since all component properties of composites in the set
+            # have been eliminated, any remaining property whose
+            # feature is the same as a component of a composite in the
+            # set must have a non-redundant value.
+            if $(fullp) != [ defaults $(f) ]
+              || symmetric in [ attributes $(f) ]
+                || $(fullp:G) in $(components:G)
+            {
+                result += $(p) ;
+            }
+
+            x = $(x[2-]) ;
+        }
+    }
+    return $(result) ;
+}
+
+# Combine all subproperties into their parent properties
+#
+# Requires: for every subproperty, there is a parent property.  All
+# features are explicitly expressed.
+#
+# This rule probably shouldn't be needed, but
+# build-request.expand-no-defaults is being abused for unintended
+# purposes and it needs help
+rule compress-subproperties ( properties * )
+{
+    local all-subs matched-subs result ;
+    
+    for local p in $(properties)
+    {
+        if ! $(p:G)
+        {
+            assert.nonempty-variable p:G ; # expecting fully-gristed properties
+        }
+        
+        
+        if ! subfeature in $($(p:G).attributes)
+        {
+            local subs = [ 
+              sequence.insertion-sort
+                [ sequence.filter is-subproperty-of $(p) : $(properties) ]
+            ] ;
+            
+            matched-subs += $(subs) ;
+
+            local subvalues = -$(subs:G=:J=-) ;
+            subvalues ?= "" ;
+            result += $(p)$(subvalues) ;
+        }
+        else
+        {
+            all-subs += $(p) ;
+        }
+    }
+    assert.result true : set.equal $(all-subs) : $(matched-subs) ;
+    return $(result) ;
+}
+  
+# given an ungristed string, finds the longest prefix which is a
+# top-level feature name followed by a dash, and return a pair
+# consisting of the parts before and after that dash.  More
+# interesting than a simple split because feature names can contain
+# dashes.
+local rule split-top-feature ( feature-plus )
+{
+    local e = [ regex.split $(feature-plus) - ] ;
+    local f = $(e[1]) ;
+    
+    local v ;
+    while $(e)
+    {
+        if <$(f)> in $(.all-top-features)
+        {
+            v = $(f) $(e[2-]:J=-) ;
+        }
+        e = $(e[2-]) ;
+        f = $(f)-$(e[1]) ;
+    }
+    return $(v) ;
+}
+  
+# Given a set of properties, add default values for features not
+# represented in the set. 
+# Note: if there's there's ordinary feature F1 and composite feature
+# F2, which includes some value for F1, and both feature have default values,
+# then the default value of F1 will be added, not the value in F2. This might
+# not be right idea: consider
+#
+#   feature variant : debug ... ;
+#        <variant>debug : .... <runtime-debugging>on
+#   feature <runtime-debugging> : off on ;
+#   
+#   Here, when adding default for an empty property set, we'll get
+#
+#     <variant>debug <runtime_debugging>off
+#  
+#   and that's kind of strange.
+rule add-defaults ( properties * )
+{
+    for local v in $(properties:G=)
+    {
+        if $(v) in $(properties)
+        {
+            error add-defaults requires explicitly specified features,
+                but \"$(v)\" appears to be the value of an un-expanded implicit feature ;
+        }
+    }
+    # We don't add default for elements with ":" inside. This catches:
+    # 1. Conditional properties --- we don't want <variant>debug:<define>DEBUG
+    #    to be takes as specified value for <variant>
+    # 2. Free properties with ":" in values. We don't care, since free properties
+    #    don't have defaults.
+    local xproperties = [ MATCH "^([^:]+)$" : $(properties) ] ;
+    local missing-top = [ set.difference $(.all-top-features) : $(xproperties:G) ] ;
+    local more =  [ defaults $(missing-top) ] ;
+    properties += $(more) ;
+    xproperties += $(more) ;
+    
+    # Add defaults for subfeatures of features which are present
+    for local p in $(xproperties)
+    {
+        local s = $($(p:G).subfeatures) ;
+        local f = [ utility.ungrist $(p:G) ] ;
+        local missing-subs = [ set.difference <$(f)-$(s)> : $(properties:G) ] ;
+        properties += [ defaults [ select-subfeatures $(p) : $(missing-subs) ] ] ;
+    }
+    
+    return $(properties)  ;
+}
+
+# Given a property-set of the form
+#       v1/v2/...vN-1/<fN>vN/<fN+1>vN+1/...<fM>vM
+#
+# Returns
+#       v1 v2 ... vN-1 <fN>vN <fN+1>vN+1 ... <fM>vM
+#
+# Note that vN...vM may contain slashes. This is resilient to the
+# substitution of backslashes for slashes, since Jam, unbidden,
+# sometimes swaps slash direction on NT.
+rule split ( property-set )
+{
+    local pieces = [ regex.split $(property-set) [\\/] ] ;
+    local result ;
+
+    for local x in $(pieces)
+    {
+        if ( ! $(x:G) ) && $(result[-1]:G)
+        {
+            result = $(result[1--2]) $(result[-1])/$(x) ;
+        }
+        else
+        {
+            result += $(x) ;
+        }
+    }
+
+    return $(result) ;
+}
+
+# tests of module feature
+local rule __test__ ( )
+{
+    # use a fresh copy of the feature module
+    prepare-test feature-test-temp ;
+
+    # These are local rules and so must be explicitly reimported into
+    # the testing module
+    import feature : extend-feature validate-feature select-subfeatures ; 
+    
+    import errors : try catch ;
+    import assert ;
+
+    feature toolset : gcc : implicit ;
+    feature define : : free ;
+    feature runtime-link : dynamic static : symmetric ;
+    feature optimization : on off ;
+    feature variant : debug release : implicit composite symmetric ;
+    feature stdlib : native stlport ;
+    feature magic : : free ;
+
+    compose <variant>debug : <define>_DEBUG <optimization>off ;
+    compose <variant>release : <define>NDEBUG <optimization>on ;
+
+    extend-feature toolset : msvc metrowerks ;
+    subfeature toolset gcc : version : 2.95.2 2.95.3 2.95.4
+      3.0 3.0.1 3.0.2 ;
+    
+    subfeature toolset gcc : platform : linux cygwin : optional ;
+    
+    assert.result <toolset-gcc:version>
+      : select-subfeatures <toolset>gcc
+         : <toolset-gcc:version>
+           <toolset-msvc:version>
+           <toolset-version>
+           <stdlib>
+      ;
+           
+    subfeature stdlib : version : 3 4 : optional ;
+
+    assert.result <stdlib-version>
+      : select-subfeatures <stdlib>native
+         : <toolset-gcc:version>
+           <toolset-msvc:version>
+           <toolset-version>
+           <stdlib-version>
+      ;
+           
+    assert.result <toolset>gcc <toolset-gcc:version>3.0.1
+      : expand-subfeatures <toolset>gcc-3.0.1 ;
+    
+    assert.result <toolset>gcc <toolset-gcc:version>3.0.1 <toolset-gcc:platform>linux
+      : expand-subfeatures <toolset>gcc-3.0.1-linux ;
+
+    
+    assert.result <toolset>gcc <toolset-gcc:version>3.0.1
+      : expand <toolset>gcc <toolset-gcc:version>3.0.1  ;
+      
+    assert.result <define>foo=x-y
+      : expand-subfeatures <define>foo=x-y ;
+
+    assert.result <toolset>gcc <toolset-gcc:version>3.0.1
+      : expand-subfeatures gcc-3.0.1 ;
+    
+    assert.result a c e
+      : get-values <x> : <x>a <y>b <x>c <y>d <x>e ;
+
+    assert.result <toolset>gcc <toolset-gcc:version>3.0.1
+      <variant>debug <define>_DEBUG <optimization>on
+      : expand gcc-3.0.1 debug <optimization>on
+      ;
+    
+    assert.result <variant>debug <define>_DEBUG <optimization>on
+      : expand debug <optimization>on
+      ;
+
+    assert.result <optimization>on <variant>debug <define>_DEBUG 
+      : expand <optimization>on debug 
+      ;
+
+    assert.result <runtime-link>dynamic <optimization>on
+      : defaults <runtime-link> <define> <optimization>
+      ;
+    
+    feature dummy : dummy1 dummy2 ;
+    subfeature dummy : subdummy : x y z : optional ;
+
+    feature fu : fu1 fu2 : optional ;
+    subfeature fu : subfu : x y z : optional ;
+    subfeature fu : subfu2 : q r s ;
+    
+    assert.result <runtime-link>static <define>foobar <optimization>on <toolset>gcc:<define>FOO
+      <toolset>gcc <variant>debug <stdlib>native <dummy>dummy1 <toolset-gcc:version>2.95.2
+
+      : add-defaults <runtime-link>static <define>foobar
+        <optimization>on <toolset>gcc:<define>FOO 
+      ;
+    
+    assert.result <runtime-link>static <define>foobar <optimization>on <toolset>gcc:<define>FOO
+      <fu>fu1 <toolset>gcc <variant>debug <stdlib>native <dummy>dummy1 <fu-subfu2>q      
+      <toolset-gcc:version>2.95.2
+      
+      : add-defaults <runtime-link>static <define>foobar
+        <optimization>on <toolset>gcc:<define>FOO <fu>fu1
+      ;
+    
+    set-default <runtime-link> : static ;
+    assert.result <runtime-link>static 
+      : defaults <runtime-link>
+      ;
+      
+    assert.result gcc-3.0.1 debug <optimization>on
+      : minimize [ expand gcc-3.0.1 debug <optimization>on <stdlib>native ]
+      ;
+
+    assert.result gcc-3.0.1 debug <runtime-link>dynamic
+      : minimize [ expand gcc-3.0.1 debug <optimization>off <runtime-link>dynamic ]
+      ;
+
+    assert.result gcc-3.0.1 debug
+      : minimize [ expand gcc-3.0.1 debug <optimization>off ]
+      ;
+
+    assert.result debug <optimization>on
+      : minimize [ expand debug <optimization>on ]
+      ;
+
+    assert.result gcc-3.0
+      : minimize <toolset>gcc <toolset-gcc:version>3.0 
+      ;
+
+    assert.result gcc-3.0
+      : minimize <toolset-gcc:version>3.0 <toolset>gcc
+      ;
+
+    assert.result <x>y/z <a>b/c <d>e/f
+      : split <x>y/z/<a>b/c/<d>e/f
+      ;
+
+    assert.result <x>y/z <a>b/c <d>e/f
+      : split <x>y\\z\\<a>b\\c\\<d>e\\f
+      ;
+
+    assert.result a b c <d>e/f/g <h>i/j/k
+      : split a/b/c/<d>e/f/g/<h>i/j/k
+      ;
+
+    assert.result a b c <d>e/f/g <h>i/j/k
+      : split a\\b\\c\\<d>e\\f\\g\\<h>i\\j\\k
+      ;
+
+    # test error checking
+
+    try ;
+    {
+        expand release <optimization>off <optimization>on ;
+    }
+    catch explicitly-specified values of non-free feature <optimization> conflict ;
+
+    try ;
+    {
+        validate-feature <foobar> ;
+    }
+    catch unknown feature ;
+
+    validate-value-string <toolset> gcc ;
+    validate-value-string <toolset> gcc-3.0.1 ;
+
+    try ;
+    {
+        validate-value-string <toolset> digital_mars ;
+    }
+    catch \"digital_mars\" is not a known value of <toolset> ;
+
+    try ;
+    {
+        feature foobar : : baz ;
+    }
+    catch unknown attributes: baz ;
+
+    feature feature1 ;
+    try ;
+    {
+        feature feature1 ;
+    }
+    catch feature already defined: ;
+
+    try ;
+    {
+        feature feature2 : : free implicit ;
+    }
+    catch free features cannot also be implicit ;
+
+    try ;
+    {
+        feature feature3 : : free propagated ;
+    }
+    catch free features cannot be propagated ;
+
+    try ;
+    {
+        implied-feature lackluster ;
+    }
+    catch \"lackluster\" is not a value of an implicit feature ;
+
+    try ;
+    {
+        implied-subfeature <toolset> 3.0.1 ;
+    }
+    catch \"3.0.1\" is not a known subfeature value of
+      <toolset> ;
+
+    try ;
+    {
+        implied-subfeature <toolset> not-a-version : gcc ;
+    }
+    catch \"not-a-version\" is not a known subfeature value of
+      <toolset>gcc ;
+
+    # leave a clean copy of the features module behind
+    finish-test feature-test-temp ;
+}

Added: boost-jam/boost-build/branches/upstream/current/build/generators.jam
===================================================================
--- boost-jam/boost-build/branches/upstream/current/build/generators.jam	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/build/generators.jam	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,1102 @@
+#  Copyright (C) Vladimir Prus 2002. Permission to copy, use, modify, sell and
+#  distribute this software is granted provided this copyright notice appears in
+#  all copies. This software is provided "as is" without express or implied
+#  warranty, and with no claim as to its suitability for any purpose.
+
+#  Manages 'generators' --- objects which can do transformation between different
+#  target types and contain algorithm for finding transformation from sources
+#  to targets.
+#
+#  The main entry point to this module is generators.construct rule. It is given
+#  a list of source targets, desired target type and a set of properties.
+#  It starts by selecting 'viable generators', which have any chances of producing
+#  the desired target type with the required properties. Generators are ranked and
+#  a set of most specific ones is selected.
+# 
+#  The most specific generators have their 'run' methods called, with the properties
+#  and list of sources. Each one selects target which can be directly consumed, and
+#  tries to convert the remaining ones to the types it can consume. This is done
+#  by recursively calling 'construct' with all consumable types.
+#
+#  If the generator has collected all the targets it needs, it creates targets 
+#  corresponding to result, and returns it. When all generators have been run,
+#  results of one of them are selected and returned as result.
+#
+#  It's quite possible that 'construct' returns more targets that it was asked for.
+#  For example, it was asked to target type EXE, but the only found generators produces
+#  both EXE and TDS (file with debug) information. The extra target will be returned.
+#
+#  Likewise, when generator tries to convert sources to consumable types, it can get
+#  more targets that it was asked for. The question is what to do with extra targets.
+#  Boost.Build attempts to convert them to requested types, and attempts as early as
+#  possible. Specifically, this is done after invoking each generator. (Later I'll 
+#  document the rationale for trying extra target conversion at that point).
+#
+#  That early conversion is not always desirable. Suppose a generator got a source of
+#  type Y and must consume one target of type X_1 and one target of type X_2.
+#  When converting Y to X_1 extra target of type Y_2 is created. We should not try to
+#  convert it to type X_1, because if we do so, the generator will get two targets
+#  of type X_1, and will be at loss as to which one to use. Because of that, the
+#  'construct' rule has a parameter, telling if multiple targets can be returned. If
+#  the parameter is false, conversion of extra targets is not performed.
+
+import "class" : is-a new ;
+import container ;
+import utility : str equal ;
+import set sequence ;
+import assert ;
+import virtual-target ;
+
+if "--debug-generators" in [ modules.peek : ARGV ] 
+{    
+    .debug = true ;
+}
+
+# Outputs a debug message if generators debugging is on.
+# Each element of 'message' is checked to see if it's class instance.
+# If so, instead of the value, the result of 'str' call is output.
+local rule generators.dout ( message * )
+{
+    if $(.debug)
+    {                
+        ECHO [ sequence.transform utility.str : $(message) ] ;
+    }    
+}
+
+
+local rule indent ( )
+{
+    return $(.indent:J="") ;
+}
+
+local rule increase-indent ( )
+{
+    .indent += "    " ;
+}
+
+local rule decrease-indent ( )
+{
+    .indent = $(.indent[2-]) ;
+}
+
+# Takes a vector of 'virtual-target' instances and makes a normalized
+# representation, which is the same for given set of targets,
+# regardless of their order.
+rule normalize-target-list ( targets )
+{
+    $(targets).sort ;                   
+}
+
+# Creates a generator
+class generator 
+{
+    import generators ;
+    import assert ;
+    import generators : indent increase-indent decrease-indent generators.dout ;
+    import set ;
+    import utility : equal ;
+    import feature ;
+    import errors : error ;
+    import sequence ;
+    import type ;
+    import virtual-target ;
+    import "class" : new ;
+    import property ;
+   
+    EXPORT class at generator : indent increase-indent decrease-indent generators.dout ;
+    
+    rule __init__ (  
+      id # identifies the generator - should be name of the rule which
+         # sets up build actions
+      composing ? # whether generator processes each source target in
+                  # turn, converting it to required types.
+                  # Ordinary generators pass all sources together to
+                  # recusrive generators.construct-types call.
+    
+    : source-types *  # types that this generator can handle
+    
+    : target-types-and-names +   
+      # types the generator will create and, optionally, names for
+      # created targets. Each element should have the form
+      #    type["(" name-pattern ")"]
+      # for example, obj(%_x). Name of generated target will be found
+      # by replacing % with the name of source, provided explicit name
+      # was not specified.
+    
+    : requirements *
+                )
+    {                    
+        self.id = $(id) ;
+        self.composing = $(composing) ;
+        self.source-types = $(source-types) ;
+        self.target-types-and-names = $(target-types-and-names) ;
+        self.requirements = $(requirements) ;
+        
+        for local e in $(target-types-and-names)
+        {        
+            # Create three parallel lists: one with the list of target types,
+            # and two other with prefixes and postfixes to be added to target 
+            # name. We use parallel lists for prefix and postfix (as opposed
+            # to mapping), because given target type might occur several times,
+            # for example "H H(%_symbols)".
+            local m = [ MATCH ([^\\(]*)(\\((.*)%(.*)\\))? : $(e) ] ;
+            self.target-types += $(m[1]) ;
+            self.name-prefix += $(m[3]:E="") ;
+            self.name-postfix += $(m[4]:E="") ;
+        }
+                                    
+        # Note that 'transform' here, is the same as 'for_each'.
+        sequence.transform type.validate : $(self.source-types) ;
+        if $(self.target-types) != *
+        {        
+            sequence.transform type.validate : $(self.target-types) ;
+        }
+    }
+                            
+    ############## End of constructor #################
+    
+    rule id ( )
+    {
+        return $(self.id) ;
+    }
+
+    # Returns the list of target type the generator accepts.
+    rule source-types ( )
+    {
+        return $(self.source-types) ;
+    }
+
+    # Returns the list of target types that this generator produces.
+    # It is assumed to be always the same -- i.e. it cannot change depending
+    # list of sources.    
+    rule target-types ( )
+    {
+        return $(self.target-types) ;
+    }
+
+    # Returns the required properties for this generator. Properties
+    # in returned set must be present in build properties if this 
+    # generator is to be used. If result has grist-only element,
+    # that build properties must include some value of that feature.
+    # XXX: remove this method?
+    rule requirements ( )
+    {
+        return $(self.requirements) ;
+    }
+    
+    # Returns a true value if the generator can be run with the specified 
+    # properties.
+    rule match-rank ( property-set-to-match )
+    {
+        # See if generator's requirements are satisfied by
+        # 'properties'.  Treat a feature name in requirements
+        # (i.e. grist-only element), as matching any value of the
+        # feature.
+        local all-requirements = [ requirements ] ;
+        
+        local property-requirements feature-requirements ;
+        for local r in $(all-requirements)
+        {
+            if $(r:G=)
+            {
+                property-requirements += $(r) ;
+            }
+            else
+            {
+                feature-requirements += $(r) ;
+            }                      
+        }
+
+        local properties-to-match = [ $(property-set-to-match).raw ] ;
+        if $(property-requirements) in $(properties-to-match) 
+           && $(feature-requirements) in $(properties-to-match:G)
+        {
+            return true ;
+        }
+        else
+        {
+            return ;
+        }
+    }
+        
+    # Returns another generator which differers from $(self) in
+    # - id
+    # - value to <toolset> feature in properties
+    rule clone ( new-id : new-toolset-properties + )
+    {
+        return [ new $(__class__) $(new-id) $(self.composing)
+                 : $(self.source-types)
+                 : $(self.target-types-and-names) 
+                 # Note: this does not remove any subfeatures of <toolset>
+                 # which might cause problems
+                 : [ property.change $(self.requirements) : <toolset> ]
+                   $(new-toolset-properties)
+               ] ;
+    }
+    
+    # Tries to invoke this generator on the given sources. Returns a
+    # list of generated targets (instances of 'virtual-target').
+    rule run ( project  # Project for which the targets are generated
+               name ?   # Determines the name of 'name' attribute for 
+                        # all generated targets. See 'generated-targets' method.
+               : property-set # Desired properties for generated targets.
+               : sources +  # Source targets.
+               : multiple ? # Allows the rule to run generator several times and return
+                          # multiple targets of the same type. When this argument is not
+                          # given, 'run' will return the list of targets, which is equal
+                          # in size to the list of target types, and where type of
+                          # each target is the same as the corresponding element of
+                          # target type list. Non-empty value allows to return several
+                          # such target lists, joined together.
+             )
+    {
+        # multiple = true ; # The tests seem to tolerate this; will
+                          # remove the parameter altogether in the
+                          # next revision to see what I learn -- DWA 2003/5/6
+        
+        generators.dout [ indent ] "  generator" $(self.id) ;
+        generators.dout [ indent ] "  multiple:" $(mutliple) ;
+        generators.dout [ indent ] "  composing:" $(self.composing) ;        
+        
+        if ! $(self.composing) && $(sources[2]) && $(self.source-types[2])
+        {
+            errors.error "Unsupported source/source-type combination" ;
+        }
+
+        if $(self.source-types[2])
+        {
+            multiple = ;
+        }
+        
+        # We don't run composing generators if no name is specified. The reason
+        # is that composing generator combines several targets, which can have
+        # different names, and it cannot decide which name to give for produced
+        # target. Therefore, the name must be passed.
+        #
+        # This in effect, means that composing generators are runnable only
+        # at top-level of transofrmation graph, or if name is passed explicitly.
+        # Thus, we dissallow composing generators in the middle. For example, the
+        # transofrmation CPP -> OBJ -> STATIC_LIB -> RSP -> EXE won't be allowed 
+        # (the OBJ -> STATIC_LIB generator is composing)
+        if ! $(self.composing) || $(name)
+        {            
+            run-really $(project) $(name) : $(property-set) : $(sources) : $(multiple) ;
+        }        
+    }
+    
+    
+    rule run-really ( project name ? : property-set : sources + : multiple ? )
+    {
+                
+        # Targets that this generator will consume directly.
+        local consumed = ;
+        # Targets that can't be consumed and will be returned as-is.
+        local bypassed = ;
+        
+        if $(self.composing)
+        {
+            convert-multiple-sources-to-consumable-types $(project)
+              : $(property-set) : $(sources) : consumed bypassed ;            
+        }
+        else
+        {            
+            convert-to-consumable-types $(project) $(name) : 
+              $(property-set) : $(sources) : $(multiple)
+                :
+                : consumed bypassed ;
+        }
+                
+        local result ;
+        if $(consumed)  
+        {            
+            result = [ construct-result $(consumed) : $(project) $(name) 
+                     : $(property-set) ] ;
+            result += $(bypassed) ;
+        }
+                            
+                
+        if $(result)
+        {
+           generators.dout [ indent ] "  SUCCESS: " $(result) ;
+        }
+        else
+        {
+            generators.dout [ indent ] "  FAILURE" ;
+        }
+        generators.dout ;
+        return $(result) ;        
+    }
+
+    # Constructs the dependency graph that will be returned by this 
+    # generator
+    rule construct-result ( 
+        consumed + # Already prepared list of consumable targets
+                   # If generator requires several source files will contain 
+                   # exactly len $(self.source-types) targets with matching types
+                   # Otherwise, might contain several targets with the type of 
+                   # $(self.source-types[1])                               
+        : project name ? 
+        : property-set  # Properties to be used for all actions create here
+    )
+    {
+        local result ;
+        # If this is 1->1 transformation, apply it to all consumed targets in order.
+        if ! $(self.source-types[2]) && ! $(self.composing)
+        {
+            generators.dout [ indent ] "alt1" ;
+            for local r in $(consumed)
+            {                
+                result += [ generated-targets $(r) : $(property-set) : $(project) $(name) ] ; #(targets) ;
+            }
+        }
+        else
+        {
+            generators.dout [ indent ] "alt2 : consumed is" $(consumed) ;
+            if $(consumed) 
+            {
+                result += [ generated-targets $(consumed) : $(property-set) 
+                            : $(project) $(name) ] ;
+            }                        
+        }
+        return $(result) ;
+    }   
+    
+    # Constructs targets that are created after consuming 'sources'.
+    # The result will be the list of virtual-target, which the same length
+    # as 'target-types' attribute and with corresponding types.
+    # 
+    # When 'name' is empty, all source targets must have the same value of 
+    # the 'name' attribute, which will be used instead of the 'name' argument.
+    #
+    # The value of 'name' attribute for each generated target will be equal to
+    # the 'name' parameter if there's no name pattern for this type. Otherwise,
+    # the '%' symbol in the name pattern will be replaced with the 'name' parameter 
+    # to obtain the 'name' attribute.
+    #
+    # For example, if targets types are T1 and T2(with name pattern "%_x"), suffixes
+    # for T1 and T2 are .t1 and t2, and source if foo.z, then created files would
+    # be "foo.t1" and "foo_x.t2". The 'name' attribute actually determined the
+    # basename of a file.
+    #
+    # Note that this pattern mechanism has nothing to do with implicit patterns
+    # in make. It's a way to produce target which name is different for name of 
+    # source.
+    rule generated-targets ( sources + : property-set : project name ? )
+    {
+        if ! $(name)
+        {
+            name = [ $(sources[1]).name ] ;            
+
+            for local s in $(sources[2])
+            {
+                if [ $(s).name ] != $(name)
+                {
+                    error "$(self.id): source targets have different names: cannot determine target name" ;
+                }
+            }
+
+            # Names of sources might include directory. We should strip it.
+            name = $(name:D=) ;
+        }
+        
+        # Create generated target for each target type.
+        local targets ;
+        local pre = $(self.name-prefix) ;
+        local post = $(self.name-postfix) ;
+        for local t in $(self.target-types)                 
+        {      
+            local generated-name = $(pre[1])$(name)$(post[1]) ;
+            pre = $(pre[2-]) ;
+            post = $(post[2-]) ;
+            
+            targets += [ class.new file-target $(generated-name) : $(t) : $(project) ] ;
+        }                 
+        # Assign an action for each target
+        local action = [ action-class ] ;
+        local a = [ class.new $(action) $(targets) : $(sources) : $(self.id) : 
+                    $(property-set) ] ;
+        for local t in $(targets)
+        {
+            $(t).action $(a) ;
+            $(t).set-intermediate true ;
+        }       
+        
+        return [ sequence.transform virtual-target.register : $(targets) ] ;
+    }    
+    
+    # Attempts to convert 'source' to the types that this generator can
+    # handle. The intention is to produce the set of targets can should be
+    # used when generator is run.
+    rule convert-to-consumable-types ( project name ? : 
+        property-set : sources + : multiple ? 
+        : only-one ? # convert 'source' to only one of source types
+                     # if there's more that one possibility, report an
+                     # error 
+        : consumed-var # name of variable which recieves all targets which 
+                       # can be consumed. 
+          bypassed-var # name variable which recieves all targets which 
+                       # cannot be consumed  
+    )
+    {        
+        # We're likely to be passed 'consumed' and 'bypassed'
+        # var names. Use "_" to avoid name conflicts.
+        local _consumed ;
+        local _bypassed ;
+        local missing-types ; 
+
+        if $(sources[2])
+        {
+            # Don't know how to handle several sources yet. Just try 
+            # to pass the request to other generator
+            missing-types = $(self.source-types) ;
+        }
+        else
+        {            
+            consume-directly $(sources) : _consumed : missing-types ;
+        }
+        
+        # No need to search for transformation if
+        # some source type has consumed source and
+        # no more source types are needed.
+        if $(only-one) && $(_consumed) 
+        {
+            missing-types = ;
+        }
+            
+        #TODO: we should check that only one source type
+        #if create of 'only-one' is true.
+        # TODO: consider if consuned/bypassed separation should
+        # be done by 'construct-types'.
+                    
+        if $(missing-types)
+        {            
+            local transformed = [ generators.construct-types $(project) $(name)
+              : $(missing-types) : $(multiple) : $(property-set) : $(sources) ] ;
+                                
+            # Add targets of right type to 'consumed'. Add others to
+            # 'bypassed'. The 'generators.construct' rule has done
+            # its best to convert everything to the required type.
+            # There's no need to rerun it on targets of different types.
+                
+            for local t in $(transformed)
+            {
+                if [ $(t).type ] in $(missing-types)
+                {
+                    _consumed += $(t) ;
+                }
+                else
+                {
+                    _bypassed += $(t) ;
+                }
+            }               
+        }   
+        
+        _consumed = [ sequence.unique $(_consumed) ] ;        
+        _bypassed = [ sequence.unique $(_bypassed) ] ;
+        
+        # remove elements of '_bypassed' that are in '_consumed'
+        
+        # Suppose the target type of current generator, X is produced from 
+        # X_1 and X_2, which are produced from Y by one generator.
+        # When creating X_1 from Y, X_2 will be added to 'bypassed'
+        # Likewise, when creating X_2 from Y, X_1 will be added to 'bypassed'
+        # But they are also in 'consumed'. We have to remove them from
+        # bypassed, so that generators up the call stack don't try to convert
+        # them. 
+            
+        # In this particular case, X_1 instance in 'consumed' and X_1 instance
+        # in 'bypassed' will be the same: because they have the same source and
+        # action name, and 'virtual-target.register' won't allow two different
+        # instances. Therefore, it's OK to use 'set.difference'.
+        
+        _bypassed = [ set.difference $(_bypassed) : $(_consumed) ] ;
+        
+                
+        $(consumed-var) += $(_consumed) ;
+        $(bypassed-var) += $(_bypassed) ;
+    }
+    
+    # Converts several files to consumable types.
+    rule convert-multiple-sources-to-consumable-types
+      ( project : property-set : sources * : consumed-var bypassed-var : multiple ? )
+    {
+        multiple ?= * ;
+        # We process each source one-by-one, trying to convert it to
+        # a usable type.
+        local failed ;
+        while $(sources) && ! $(failed)
+        {
+            local _c ;
+            local _b ;
+            # TODO: need to check for failure on each source.
+            convert-to-consumable-types $(project) : $(property-set)
+              : $(sources[1]) : $(multiple) : true : _c _b ;
+            if ! $(_c)
+            {
+                generators.dout [ indent ] " failed to convert " [ $(sources[1]).str ] ;
+                # failed = true ;
+            }
+            $(consumed-var) += $(_c) ;            
+            $(bypassed-var) += $(_b) ;
+            sources = $(sources[2-]) ;
+        }           
+        if $(failed)
+        {
+            $(consumed-var) = ;
+            $(bypassed-var) = ;
+        }        
+    }
+        
+    rule consume-directly ( source : consumed-var : missing-types-var )
+    {
+        local real-source-type = [ $(source).type ] ;
+
+        for local st in $(self.source-types)
+        {
+            # The 'source' if of right type already)
+            if $(real-source-type) = $(st) || 
+              [ type.is-derived $(real-source-type) $(st) ]
+            {
+                $(consumed-var) += $(source) ;
+            }
+            else
+            {
+               $(missing-types-var) += $(st) ;
+            }
+        }        
+    }
+    
+    
+    # Returns the class to be used to actions. Default implementation 
+    # returns "action".
+    rule action-class ( )
+    {
+        return "action" ;
+    }    
+}
+
+import errors : error ;
+
+.generators = ;
+
+# Registers new generator instance 'g'.
+rule register ( g )
+{
+    .generators += $(g) ;
+                   
+    for local t in [ $(g).target-types ] 
+    {            
+        .generators.$(t) += $(g) ;
+    }    
+    
+    # Update the set of generators for toolset
+    
+    # TODO: should we check that generator with this id
+    # is not already registered. For example, the fop.jam
+    # module intentionally declared two generators with the
+    # same id, so such check will break it.
+    local id = [ $(g).id ] ;
+        
+    # Some generators have multiple periods in their name, so the
+    # normal $(id:S=) won't generate the right toolset name.
+    # e.g. if id = gcc.compile.c++, then
+    # .generators-for-toolset.$(id:S=) will append to
+    # .generators-for-toolset.gcc.compile, which is a separate
+    # value from .generators-for-toolset.gcc. Correcting this
+    # makes generator inheritance work properly.
+    # See also inherit-generators in module toolset
+    local base = $(id) ;
+    while $(base:S)
+    {
+        base = $(base:B) ;
+    }
+    .generators-for-toolset.$(base) += $(g) ;
+}
+    
+# Creates new instance of the 'generator' class and registers it.
+# Retursn the creates instance.
+# Rationale: the instance is returned so that it's possible to first register
+# a generator and then call 'run' method on that generator, bypassing all
+# generator selection.
+rule register-standard ( id : source-types + : target-types + : requirements * )
+
+{
+    local g = [ new generator $(id) : $(source-types) : $(target-types)
+      : $(requirements) ] ;
+    register $(g) ;   
+    return $(g) ;
+}
+
+# Creates new instance of the 'composing-generator' class and
+# registers it.
+rule register-composing ( id : source-types + : target-types + : requirements * )
+{
+    local g = [ new generator $(id) true : $(source-types) 
+                : $(target-types) : $(requirements) ] ;
+    register $(g) ;
+    return $(g) ;
+}
+
+# Returns all generators which belong to 'toolset', i.e. which
+# ids are $(toolset).<something>
+rule generators-for-toolset ( toolset )
+{
+    return $(.generators-for-toolset.$(toolset)) ;
+}
+
+rule override ( overrider-id : overridee-id )
+{
+    .override.$(overrider-id) += $(overridee-id) ;    
+}
+
+
+
+    
+# Set if results of the current generators search are going to be cached
+# This means no futher attempts to cache generators search should be
+# made.
+.caching = ;
+
+# For all t in 'targets':
+# if [ $(t).type ] in $(target-types), add 't' to result
+# if [ $(t).type ] in base type for any of 'target-types', add 't' to result
+# otherwise, add 't' to extra.
+rule base-to-derived-type-conversion ( targets * : target-types +
+    : result-var extra-var )
+{
+    for local t in $(targets) 
+    {
+        if [ $(t).type ] in $(target-types)
+        {
+            $(result-var) += $(t) ;
+        }
+        else 
+        {
+            # We might have asked for a type 'D', but found only generator for
+            # a type 'B', where 'D' is derived from 'B'. In this case, the 
+            # generation succeeds, but we should change type of the generated target.
+            
+            local at = [ $(t).type ] ;
+            local found ;
+            for local tt in $(target-types)
+            {
+                if ! $(found) && [ type.is-derived $(tt) $(at) ] 
+                {
+                    $(t).set-type $(tt) ;
+                    $(result-var) += $(t) ;
+                    found = 1 ;
+                }                
+            }            
+            if ! $(found)
+            {
+                $(extra-var) += $(t) ;                
+            }            
+        }        
+    }    
+}
+
+
+
+local rule try-one-generator ( project name ? : generator multiple ? : 
+    target-type : property-set : sources * )
+{
+    local targets =
+      [ $(generator).run $(project) $(name)
+                       : $(property-set)
+                       : $(sources)
+                       : $(multiple)
+      ] ;
+
+    # Generated targets that are of required types
+    local result ;
+    # Generated target of other types.
+    local extra ;
+
+    base-to-derived-type-conversion $(targets) : $(target-type) 
+        : result extra ;
+            
+    # Now try to convert extra targets 
+    # 'construct' will to its best to return only requested
+    # target types, so if we receive any extra from that call,
+    # we don't try to do anything about them.
+    local extra2 ;
+    if $(multiple) 
+    {
+        for local e in $(extra) 
+        {
+            local try2 = [ construct-types $(project) $(name) 
+                                         : $(target-type)
+                                         :
+                                         : $(property-set)
+                                         : $(e) ] ;
+    
+            result += $(try2) ;
+        }    
+    }
+    else
+    {
+        extra2 = $(extra) ;
+    }
+    generators.dout [ indent ] "  generator" [ $(generator).id ] " spawned " ;
+    generators.dout [ indent ] " " $(result) -- $(extra2) ; 
+    return $(result) $(extra2) ;                     
+}
+
+rule construct-types ( project name ? : target-types + : multiple ? : 
+    property-set : sources + )
+{
+    local result ;
+    local matched-types ; 
+    for local t in $(target-types)
+    {
+        local r = [ construct $(project) $(name) : $(t) $(multiple) : $(property-set) :
+          $(sources) ] ;
+        if $(r)
+        {
+            result += $(r) ;
+            matched-types += $(t) ;
+        }
+    }
+    # TODO: have to introduce parameter controlling if
+    # several types can be matches and add appropriate
+    # checks 
+
+    # TODO: need to review the documentation for
+    # 'construct' to see if it should return $(source) even
+    # if nothing can be done with it. Currents docs seem to
+    # imply that, contrary to the behaviour.
+    if $(result)
+    {
+        return $(result) ;
+    }
+    else
+    {
+        return $(sources) ;
+    }
+}
+
+# Ensures all 'targets' have types. If this is not so, exists with 
+# error.
+local rule ensure-type ( targets * )
+{
+    for local t in $(targets)
+    {
+        if ! [ $(t).type ]
+        {
+            errors.error "target" [ $(t).str ] "has no type" ;
+        }        
+    }    
+}
+
+    
+# Returns generators which can be used to construct target of specified type
+# with specified properties. Uses the following algorithm:
+# - iterates over requested target-type and all it's bases (in the order returned bt
+#   type.all-bases.
+# - for each type find all generators that generate that type and which requirements
+#   are satisfied by properties.
+# - if the set of generators is not empty, returns that set.
+#
+# Note: this algorithm explicitly ignores generators for base classes if there's
+# at least one generator for requested target-type.
+local rule find-viable-generators ( target-type : property-set )
+{
+    # Select generators that can create the required target type.
+    local viable-generators = ;
+    local generator-rank = ;
+
+    import type ;
+    # Try all-type generators first. Assume they have
+    # quite specific requirements.
+    local t = * [ type.all-bases $(target-type) ] ;
+    
+    generators.dout  [ indent ] find-viable-generators target-type= $(target-type) 
+      property-set= [ $(property-set).as-path ]
+          ;
+    
+    while $(t[1])
+    {
+        generators.dout  [ indent ] "trying type" $(t[1]) ;
+        for local g in $(.generators.$(t[1]))
+        {
+            generators.dout [ indent ] "trying generator" [ $(g).id ] "(" [ $(g).source-types ] -> [ $(g).target-types ] ")" ;
+            
+            # Avoid trying the same generator twice on different levels.
+            if ! $(g) in $(.active-generators) 
+            {       
+                local m = [ $(g).match-rank $(property-set) ] ;
+                if $(m) 
+                {
+                    generators.dout [ indent ] "  is viable" ;
+                    viable-generators += $(g) ;
+                    t = ;
+                }                                    
+            }            
+        }
+        t = $(t[2-]) ;
+    }
+    
+    # Generators which override 'all'.
+    local all-overrides ;
+    # Generators which are overriden
+    local overriden-ids ;    
+    for local g in $(viable-generators)
+    {
+        local id = [ $(g).id ] ;
+        local this-overrides = $(.override.$(id)) ;
+        overriden-ids += $(this-overrides) ;
+        if all in $(this-overrides)
+        {
+            all-overrides += $(g) ;
+        }        
+    }         
+    if $(all-overrides)
+    {
+        viable-generators = $(all-overrides) ;
+    }
+    local result ;
+    for local g in $(viable-generators)
+    {
+        if ! [ $(g).id ] in $(overriden-ids)
+        {
+            result += $(g) ;
+        }        
+    }
+                        
+    return $(result) ;
+}
+    
+# Given a vector of vectors, of of them represents results of running some 
+# generator, returns the 'best' result, it it exists. Otherwise, exit with
+# and error. Result is returned as plain jam list.
+local rule select-dependency-graph ( options )
+{
+    if [ $(options).size ] = 0
+    {
+        return ;
+    }
+    else if [ $(options).size ] = 1
+    {
+        return [ $(options).get-at 1 ] ;
+    }
+    else
+    {
+        # We have several alternatives and need to check if they
+        # are the same. 
+        
+        for local r in [ $(options).get ] 
+        {
+            normalize-target-list $(r) ;
+            generators.dout $(r) ;
+        }
+        
+        # One note why we can compare object names directly,
+        # without using deep copy. All the targets here are
+        # produced by some generators, and generators should
+        # pass the targets they've returned via 'virtual-target.register'.
+        # So, two elements can only be equivalent, if they are just
+        # the same object.       
+        local f = [ $(options).at 1 ] ;
+        local mismatch ;
+        for local r in [ $(results).get ] 
+        {
+            if [ $(r).get ] != [ $(f).get ] 
+            {
+                mismatch = true ;
+            }
+        }
+
+        if ! $(mismatch)
+        {
+            return [ $(f).get ] ;
+        }
+        else 
+        {                        
+            error [ $(options).size ] "possible generations for "
+                   $(target-types) "Can't handle this now." ;
+        }            
+    }                        
+}
+    
+.construct-stack = ;
+
+# Attempt to construct the target by looking at transformation cache.
+local rule construct-with-caching (
+   project name ? : target-type multiple ? : property-set : sources * )
+{     
+    local result ;
+    # Caching is only possible when we're not computing cacheable transformation
+    # already, when there's only one source which has no action -- i.e. source file,
+    # and name of target is not specified.
+    if ! $(.caching) && ! $(sources[2]) && $(sources[1]) && ! $(name)      
+       && ! [ $(sources[1]).action ] 
+    {
+        local .caching = true ;
+        
+        local t = $(sources[1]) ;            
+                    
+        local signature = [ sequence.join [ $(t).type ] $(target-type) $(property-set) : - ] ;
+            
+        # Get a transformation template from cache or create it.
+        local cresult ;
+        if $(.transformation.cache.$(signature))
+        {
+            cresult = $(.transformation.cache.$(signature)) ;
+        }
+        else 
+        {                            
+            local ut = [ new file-target % : [ $(t).type ] : "no project" ] ;            
+            cresult = [ construct $(project) : $(target-type) $(multiple) 
+              : $(property-set) : $(ut) ] ;
+            .transformation.cache.$(signature) = $(cresult) ;                
+        }
+                                    
+        # Substitute the real source name in the transformation template.
+        if $(cresult)
+        {                
+            generators.dout [ indent ] "*** putting to cache?" ;
+            for local c in $(cresult)
+            {
+                generators.dout [ indent ] "*** cloning " $(c) ;                
+                local cc = [ virtual-target.clone-template $(c) : $(t) : $(project) ] ;
+                generators.dout [ indent ] "*** cloned" $(cc) --- $(cc) ;
+                result += $(cc) ;
+            }
+        }    
+    }
+    return $(result) ;
+}
+
+# Attempts to construct target by finding viable generators, running them
+# and selecting the dependency graph
+local rule construct-without-caching (
+   project name ? : target-type multiple ? : property-set : sources * )
+{
+    viable-generators = [ find-viable-generators $(target-type) : $(property-set) ] ;
+                    
+    local results = [ new vector ] ;
+    
+    generators.dout [ indent ] "*** " [ sequence.length $(viable-generators) ] 
+      " viable generators" ;
+    
+    for local g in $(viable-generators)
+    {
+        # This variable will be restored on exit from this scope.
+        local .active-generators = $(g) $(.active-generators) ;
+        
+        local r = [ try-one-generator $(project) $(name) : $(g) $(multiple) : $(target-type) :
+          $(property-set) : $(sources) ] ;
+        
+        if $(r)
+        {
+            $(results).push-back [ new vector $(r) ] ;
+        }
+    }
+    
+    return [ select-dependency-graph $(results) ] ;
+}       
+    
+        
+# Attempts to create target of 'target-type' with 'properties'
+# from 'sources'. The 'sources' are treated as a collection of
+# *possible* ingridients -- i.e. it is not required to consume
+# them all. If 'multiple' is true, the rule is allowed to return
+# several targets of 'target-type'.          
+#
+#
+# Returns a list of target. When this invocation is first instance of
+# 'construct' in stack, returns only targets of requested 'target-type',
+# otherwise, returns also unused sources and additionally generated
+# targets.    
+#
+# Does not return target which are not of 'allowed-type' or of type derived from
+# it. If 'allowed-type' is not specified, it's defaulted to 'target-type'.
+# See lib-target-class for use case of this.
+rule construct ( project name ? : target-type multiple ? : property-set * : sources * 
+   : allowed-type * )
+{
+    allowed-type ?= $(target-type) ;
+    if (.construct-stack)
+    {
+        ensure-type $(sources) ;
+    }
+
+    # Intermediate targets are not passed to generators
+    # and just returned unmodified.
+    local intermediate ;
+    if ! $(.construct-stack)
+    {
+        local sources2 ;
+        for local s in $(sources)
+        {
+            if ! [ $(s).intermediate ] 
+            {
+                sources2 += $(s) ;
+            }
+            else
+            {
+                intermediate += $(s) ;
+            }            
+        }
+        sources = $(sources2) ;
+    }
+        
+    .construct-stack += 1 ;
+
+    increase-indent ;
+    
+    local m ;
+    if $(multiple)
+    {
+        m = "(may return multiple targets)" ;
+    }
+    generators.dout [ indent ] "*** construct" $(target-type) $(m) ;
+    
+    for local s in $(sources)
+    {
+        generators.dout [ indent ] "    from" $(s) ;
+    }
+    generators.dout [ indent ] "    properties:" [ $(property-set).raw ] ;        
+               
+    local result = [ construct-with-caching $(project) $(name)  
+      : $(target-type) $(multiple) : $(property-set) : $(sources) ] ;
+    
+    if ! $(result)  {
+        result = [ construct-without-caching $(project) $(name)  
+      : $(target-type) $(multiple) : $(property-set) : $(sources) ] ;
+    }
+                    
+    decrease-indent ;
+        
+    .construct-stack = $(.construct-stack[2-]) ;
+    
+    if ! $(.construct-stack)
+    {
+        result += $(intermediate) ;
+    }
+    
+    # For all targets of 'allowed-type', reset the 'intermediate' attribute.
+    if ! $(.construct-stack) && $(allowed-type) != * # This is first invocation in stack
+    {
+        local result2 ;
+        for local t in $(result)
+        {
+            local type = [ $(t).type ] ; 
+            assert.nonempty-variable type ;
+            assert.nonempty-variable target-type ;
+            
+            # Return only targets of the requested type, unless 'return-all'
+            # is specified. If we don't do this, then all targets calling
+            # 'construct' will get unused target returned, which will break
+            # checking for unused sources a bit harder.
+            if $(type) = $(target-type) || [ type.is-derived $(type) $(allowed-type) ]
+            {
+                $(t).set-intermediate ;
+            }
+        }                
+    } 
+            
+    
+    return $(result) ;        
+}
+

Added: boost-jam/boost-build/branches/upstream/current/build/modifiers.jam
===================================================================
--- boost-jam/boost-build/branches/upstream/current/build/modifiers.jam	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/build/modifiers.jam	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,223 @@
+# (C) Copyright Rene Rivera, 2003.
+#
+# See accompanying license for terms and conditions of use.
+#
+
+# Modifiers are generalized generators that mutate targets in specific ways.
+# This structure allows for grouping a variety of functionality in an
+# orthogonal way to the functionality in toolsets, and without specifying
+# more target variations. In turn the modifiers can be used as building
+# blocks to implement simple requests, like the <version> feature.
+
+import modules ;
+import feature ;
+import errors ;
+import type ;
+import "class" : new ;
+import generators : generator ;
+import property ;
+import virtual-target ;
+import numbers ;
+import sequence ;
+import symlink ;
+import property-set ;
+
+# Base generator for creating targets that are modifications of existing
+# targets.
+#
+rule modifier (
+    id
+    composing ?
+    : source-types *
+    : target-types-and-names +   
+    : requirements *
+    )
+{
+    generator.__init__ $(id) $(composing) : $(source-types) : $(target-types-and-names) : $(requirements) ;
+    
+    self.targets-in-progress = ;
+    
+    # Wraps the generation of the target to call before and after rules to
+    # affect the real target.
+    #
+    rule run ( project name ? : property-set : sources + :  multiple ? )
+    {
+        local result ;
+        local current-target = $(project)^$(name) ;
+        if ! $(current-target) in $(self.targets-in-progress)
+        {
+            # Before modifications...
+            local project_ = [ modify-project-before
+                $(project) $(name) : $(property-set) : $(sources) : $(multiple) ] ;
+            local name_ = [ modify-name-before
+                $(project) $(name) : $(property-set) : $(sources) : $(multiple) ] ;
+            local property-set_ = [ modify-properties-before
+                $(project) $(name) : $(property-set) : $(sources) : $(multiple) ] ;
+            local sources_ = [ modify-sources-before
+                $(project) $(name) : $(property-set) : $(sources) : $(multiple) ] ;
+            local multiple_ = [ modify-multiple-before
+                $(project) $(name) : $(property-set) : $(sources) : $(multiple) ] ;
+            project = $(project_) ;
+            name = $(name_) ;
+            property-set = $(property-set_) ;
+            sources = $(sources_) ;
+            multiple = $(multiple_) ;
+            
+            # Generate the real target...
+            local target-type-p = [ property.select <main-target-type> : [ $(property-set).raw ] ] ;
+            self.targets-in-progress += $(current-target) ;
+            result =
+                [ generators.construct $(project) $(name) : $(target-type-p:G=) $(multiple) :
+                    $(property-set) : $(sources) ] ;
+            self.targets-in-progress = $(self.targets-in-progress[1--2]) ;
+            
+            # After modifications...
+            result = [ modify-target-after $(result) :
+                $(project) $(name) : $(property-set) : $(sources) : $(multiple) ] ;
+        }
+        return $(result) ;
+    }
+    
+    rule modify-project-before ( project name ? : property-set : sources + :  multiple ? )
+    {
+        return $(project) ;
+    }
+    
+    rule modify-name-before ( project name ? : property-set : sources + :  multiple ? )
+    {
+        return $(name) ;
+    }
+    
+    rule modify-properties-before ( project name ? : property-set : sources + :  multiple ? )
+    {
+        return $(property-set) ;
+    }
+    
+    rule modify-sources-before ( project name ? : property-set : sources + :  multiple ? )
+    {
+        return $(sources) ;
+    }
+    
+    rule modify-multiple-before ( project name ? : property-set : sources + :  multiple ? )
+    {
+        return $(multiple) ;
+    }
+    
+    rule modify-target-after ( target : project name ? : property-set : sources + :  multiple ? )
+    {
+        return $(target) ;
+    }
+    
+    # Utility, clones a file-target with optional changes to the name, type, and project
+    # of the target.
+    # NOTE: This functionality should be moved, and generalized, to virtual-targets.
+    #
+    rule clone-file-target ( target : new-name ? : new-type ? : new-project ? )
+    {
+        # Need a MUTCH better way to clone a target...
+        new-name ?= [ $(target).name ] ;
+        new-type ?= [ $(target).type ] ;
+        new-project ?= [ $(target).project ] ;
+        local result = [ new file-target $(new-name) : $(new-type) : $(new-project) ] ;
+        
+        if [ $(target).dependencies ] { $(result).depends [ $(target).dependencies ] ; }
+        $(result).suffix [ $(target).suffix ] ;
+        $(result).root [ $(target).root ] ;
+        $(result).set-usage-requirements [ $(target).usage-requirements ] ;
+        
+        local action = [ $(target).action ] ;
+        local action-class = [ modules.peek $(action) : __class__ ] ;
+        
+        local ps = [ $(action).properties ] ;
+        local cloned-action = [ new $(action-class) $(result) : 
+          [ $(action).sources ] : [ $(action).action-name ] : $(ps) ] ;
+        $(result).action $(cloned-action) ;
+        
+        return $(result) ;
+    }
+}
+class modifier : generator ;
+
+# A modifier that changes the name of a target, after it's generated, given
+# a regular expression to slpit the name, and a set of token to insert
+# between the split tokens of the name. This also exposes the target for other
+# uses with a symlink to the original name (optionally).
+#
+rule name-modifier ( )
+{
+    # Apply ourselves to EXE targets, for now.
+    modifier.__init__ name.modifier : : EXE LIB : <name-modify>yes ;
+    
+    # Modifies the name, by cloning the target with the new name.
+    #
+    rule modify-target-after ( target : project name ? : property-set : sources + :  multiple ? )
+    {
+        local result = $(target) ;
+        
+        local name-mod-p = [ property.select <name-modifier> : [ $(property-set).raw ] ] ;
+        if $(name-mod-p)
+        {
+            local new-name = [ modify-name [ $(target).name ] : $(name-mod-p:G=) ] ;
+            if $(new-name) != [ $(target).name ]
+            {
+                result = [ clone-file-target $(target) : $(new-name) ] ;
+            }
+            local expose-original-as-symlink = [ MATCH "<symlink>(.*)" : $(name-mod-p) ] ;
+            if $(expose-original-as-symlink)
+            {
+                local symlink-t = [ new symlink-targets $(project) : $(name) : [ $(result).name ] ] ;
+                result = [ $(symlink-t).construct $(result)
+                    : [ property-set.create [ $(property-set).raw ] <symlink-location>build-relative ] ] ;
+            }
+        }
+        
+        return $(result) ;
+    }
+    
+    # Do the transformation of the name.
+    #
+    rule modify-name ( name : modifier-spec + )
+    {
+        local match = [ MATCH "<match>(.*)" : $(modifier-spec) ] ;
+        local name-parts = [ MATCH $(match) : $(name) ] ;
+        local insertions = [ sequence.insertion-sort [ MATCH "(<[0123456789]+>.*)" : $(modifier-spec) ] ] ;
+        local new-name-parts ;
+        local insert-position = 1 ;
+        while $(insertions)
+        {
+            local insertion = [ MATCH "<$(insert-position)>(.*)" : $(insertions[1]) ] ;
+            if $(insertion)
+            {
+                new-name-parts += $(insertion) ;
+                insertions = $(insertions[2-]) ;
+            }
+            new-name-parts += $(name-parts[1]) ;
+            name-parts = $(name-parts[2-]) ;
+            insert-position = [ numbers.increment $(insert-position) ] ;
+        }
+        new-name-parts += $(name-parts) ;
+        return [ sequence.join $(new-name-parts) ] ;
+    }
+    
+    rule optional-properties ( )
+    {
+        return <name-modify>yes ;
+    }
+}
+class name-modifier : modifier ;
+feature.feature name-modifier : : free ;
+feature.feature name-modify : no yes : incidental optional ;
+generators.register [ new name-modifier ] ;
+
+# Translates <version> property to a set of modification properties
+# that are applied by the name-modifier, and symlink-modifier.
+#
+rule version-to-modifier ( property : properties * )
+{
+    return
+        <name-modify>yes
+            <name-modifier><match>"^([^.]*)(.*)" <name-modifier><2>.$(property:G=)
+            <name-modifier><symlink>yes
+        ;
+}
+feature.action <version> : version-to-modifier ;

Added: boost-jam/boost-build/branches/upstream/current/build/project-roots.jam
===================================================================
--- boost-jam/boost-build/branches/upstream/current/build/project-roots.jam	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/build/project-roots.jam	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,370 @@
+# (C) Copyright Rene Rivera, 2002.
+#
+# See accompanying license for terms and conditions of use.
+#
+
+# Represents the projet-root of a collection of projects. This maintains
+# information about the root, and pointers to the project defined within
+# the root. Each project-root gets it's own module to put things into. For
+# instance declared constants which also get interned into each loaded project.
+
+import modules ;
+import path ;
+import "class" ;
+import set ;
+import regex ;
+
+# Load the project-root file for the given directory. The directory can
+# be either the project-root itself, or any subdirectory. Fails if it can't
+# find the project-root. We return the project-root module.
+#
+rule load (
+    dir # The directory to obtain the project-root for.
+    )
+{
+    local location = [ find-project-root $(dir) ] ;
+
+    # No project-root file found.
+    #
+    if ! $(location)
+    {
+        ECHO "Failed to find the project root for directory '$(dir)'." ;
+        ECHO "Did not find a project-root.jam file there or in any of its parent"
+            "directories." ;
+        EXIT "Please consult the documentation at 'http://www.boost.org'." ;
+    }
+    location = [ path.parent [ path.make $(location) ] ] ;
+
+    local module-name = project-root<$(location)> ;
+
+    local root ;
+    # Only bother with the rest if the project-root isn't loaded yet.
+    #
+    if ! [ modules.peek $(module-name) : .project-root ]
+    {
+        # Create the project-root, and remember it.
+        #
+        root = [ class.new project-root-object $(location) ] ;
+        modules.poke $(module-name) : .project-root : $(root) ;
+        .roots += $(root) ;
+        
+        # Let the project root initialize and load the contents.
+        #
+        $(root).initialize ;
+    }
+    else
+    {
+        root = [ modules.peek $(module-name) : .project-root ] ;
+    }
+    
+
+    # Return the module for the project.
+    #
+    return $(root) ;
+}
+
+# Finds the location of project root for a directory.
+# Returns the path to 'project-root.jam'.
+rule find-project-root ( dir )
+{
+    # Find the project-root.jam corresponding to this directory.
+    #
+    local location = [ path.glob $(dir) : project-root.jam ] ;
+    if ! $(location)
+    {
+        location = [ path.glob-in-parents $(dir) : project-root.jam ] ;
+    }
+    return $(location) ;
+}
+
+
+# Print out all the project-roots.
+#
+rule print ( )
+{
+    import sequence ;
+    import print ;
+    
+    local rule compare-project-roots ( r1 r2 )
+    {
+        if [ $(r1).get-module ] < [ $(r2).get-module ]
+        {
+            return true ;
+        }
+    }
+
+    print.section "Project Roots" ;
+    local roots = [ sequence.insertion-sort $(.roots) : compare-project-roots ] ;
+    for local root in $(roots)
+    {
+        $(root).print ;
+    }
+}
+
+# Class encapsulating settings for a single project root.
+#
+class project-root-object 
+{
+    import path ;
+    import set ;    
+    import sequence ;
+    import print ;
+    import project ;
+        
+    rule __init__ (
+      location # The root location.
+    )
+    {        
+        # The module name of the project-root.
+        self.module = project-root<$(location)> ;
+    
+        # The location of the project-root, as a path.
+        self.location = $(location) ;
+    
+        # The set of projects registered in this project-root.
+        self.projects = ;
+    
+        # The set of interned constants for this project-root.
+        self.constants = ;
+    }    
+    
+    # Accessor, the module of the project root.
+    rule get-module ( )
+    {
+        return $(self.module) ;
+    }
+    
+    # Accessor, the location of the porject root.
+    rule get-location ( )
+    {
+        return $(self.location) ;
+    }
+    
+    # Accessor, the project modules under this project root.
+    rule get-projects ( )
+    {
+        return $(self.projects) ;
+    }
+    
+    # Accessor, the constants to intern into the project root.
+    rule get-constants ( )
+    {
+        return $(self.constants) ;
+    }
+    
+    # Initialize the project root, also loads the project root file.
+    rule initialize ( )
+    {
+        # Give the new module all the rules from project-root-context
+        #
+        modules.clone-rules project-root-context $(self.module) ;
+
+        # Load it within a module specifically for the project root.
+        # The module system handles checking for multiple includes.
+        #
+        modules.load $(self.module)
+            : project-root.jam : [ path.native $(self.location) ] ;
+    }
+    
+    # Accessor, add a constant.
+    rule add-constant (
+        name # Variable name of the constant.
+        : value # Value of the constant.
+        : type ? # Optional type of value.
+        )
+    {
+        switch $(type)
+        {
+            case path :
+                value = [ path.root [ path.make $(value) ] $(self.location) ] ;
+                # Now make the value absolute path
+                value = [ path.root $(value) [ path.pwd ] ] ;
+                # Constants should be in platform-native form
+                value = [ path.native $(value) ] ;
+        }
+        if ! $(name) in $(self.constants)
+        {
+            self.constants += $(name) ;
+        }
+        self.constant.$(name) = $(value) ;
+        # Inject the constant in the scope of project-root module
+        modules.poke $(self.module) : $(name) : $(value) ;
+    }
+    
+    # Register a project under this project-root. This does any setup
+    # in the module of the project, including interning the project-root
+    # constants. Multiple calls on the same project are allowed and will
+    # not disturb the previous calls.
+    #
+    rule register-project (
+        project-module # The module of the project to register.
+        )
+    {
+        if ! $(project-module) in $(self.projects)
+        {
+            self.projects += $(project-module) ;
+            intern-constants $(project-module) ;
+            modules.clone-rules project-context $(project-module) ;
+            
+            # Import project-root rules declared by teh user into each project.
+            #
+            local user-rules = [ set.difference
+                [ RULENAMES $(self.module) ] :
+                [ RULENAMES project-root-context ] ] ;
+            IMPORT $(self.module) : $(user-rules) : $(project-module) : $(user-rules) ;
+        }
+    }
+    
+    # Intern the constants from this project-root into the calling context.
+    #
+    rule intern-constants (
+        context ? # The module to intern into the current module.
+        )
+    {
+        local intern-module = $(context) ;
+        intern-module ?= [ CALLER_MODULE ] ;
+        for local c in $(self.constants)
+        {
+            modules.poke $(intern-module) : $(c) : $(self.constant.$(c)) ;
+        }
+    }
+    
+    # Needed to get deterministic order of output, which makes testing simpler
+    local rule compare-projects ( p1 p2 )
+    {
+        local id1 = [ project.attribute $(p1) id ] ;
+        local id2 = [ project.attribute $(p2) id ] ;
+        if $(id1) < $(id2)
+        {
+            return true ;
+        }
+        else
+        {
+            if $(id1) = $(id2) && $(p1) < $(p2)
+            {
+                return true ;
+            }
+        }
+    }
+    
+    
+    # Print out info about this project root. Calls print on the
+    # individual projects in this project-root.
+    #
+    rule print ( )
+    {        
+        print.section "'"$(self.location)"'" Module for project-root is "'"$(self.module)"'" ;
+        if $(self.constants)
+        {
+            print.section Constants ;
+            print.list-start ;
+            local constants = [ sequence.insertion-sort $(self.constants) ] ;
+            for local c in $(constants)
+            {
+                print.list-item $(c) "=" $(self.constant.$(c)) ;
+            }
+            print.list-end ;
+        }
+        if $(self.projects)
+        {
+            print.section Projects ;
+            local projects = [ sequence.insertion-sort $(self.projects) : compare-projects ] ;
+            for local p in $(projects)
+            {
+                local attributes = [ project.attributes $(p) ] ;
+                $(attributes).print ;
+            }
+        }
+    }
+}
+
+# Rules callable by the user in the context of the project-root.jam of a project.
+#
+module project-root-context
+{
+    # Make toolset.using accessible in project-root.
+    import toolset : using ;
+    EXPORT project-root-context : using ;
+    
+    # Access to project root object and shortcut for it's methods. The
+    # optional argument is a shortcut to execute the given method on the
+    # object. This saves the hasle of creating local vars to call on the
+    # singleton.
+    #
+    rule project-root (
+        method ? # The optional method.
+        args * # The arguments.
+        : * # The rest.
+        )
+    {
+        if $(method)
+        {
+            return [ $(.project-root).$(method) $(args) : $(2) : $(3) : $(4) : $(5) : $(6) : $(7) : $(8) : $(9) ] ;
+        }
+        else
+        {
+            return $(.project-root) ;
+        }
+    }
+            
+    # Declare and set a project global constant. Project global constants are
+    # normal variables but should not be changed. They are applied to each
+    # Jamfile that is loaded under it's corresponding project-root.
+    #
+    rule constant (
+        name # Variable name of the constant.
+        : value # Value of the constant.
+        )
+    {
+        project-root add-constant $(name) : $(value) ;
+    }
+    
+    # Declare and set a project global constant, whose value is a path. The
+    # path is adjusted to be relative to the invocation directory. The given
+    # value path is taken to be either absolute, or relative to this project root.
+    #
+    rule path-constant (
+        name # Variable name of the constant.
+        : value # Value of the constant.
+        )
+    {
+        project-root add-constant $(name) : $(value) : path ;
+    }
+    
+    # Load and use a project in this project root.
+    #
+    rule use-project (
+        id # The ID of the project.
+        : location # The location of the project.
+        )
+    {
+        import project ;
+        import path ;
+        project.use $(id) : [ path.root 
+            [ path.make $(location) ] [ project-root get-location ] ] ;
+    }
+}
+
+# Project root specific rules callable in the context of a project file. These
+# get imported into each project.
+#
+module project-context
+{
+    # Access to project root object and shortcut for it's methods. The
+    # optional argument is a shortcut to execute the given method on the
+    # object. This saves the hasle of creating local vars to call on the
+    # singleton.
+    #
+    rule project-root (
+        method ? # The optional method.
+        args * # The arguments.
+        : * # The rest.
+        )
+    {
+        import project ;
+        local attributes = [ project.attributes $(__name__) ] ;
+        local project-root = [ $(attributes).get project-root ] ;
+        return [ $(project-root).$(method) 
+          $(args) : $(2) : $(3) : $(4) : $(5) : $(6) : $(7) : $(8) : $(9) ] ;
+    }
+}


Property changes on: boost-jam/boost-build/branches/upstream/current/build/project-roots.jam
___________________________________________________________________
Name: svn:executable
   + 

Added: boost-jam/boost-build/branches/upstream/current/build/project.jam
===================================================================
--- boost-jam/boost-build/branches/upstream/current/build/project.jam	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/build/project.jam	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,644 @@
+#  Copyright (C) Vladimir Prus and Rene Rivera 2002.
+#  Permission to copy, use, modify, sell and
+#  distribute this software is granted provided this copyright notice appears in
+#  all copies. This software is provided "as is" without express or implied
+#  warranty, and with no claim as to its suitability for any purpose.
+
+#  Implements project representation and loading.
+#   Each project is represented by 
+#   - a module where all the Jamfile content live. 
+#   - an instance of 'project-attributes' class.
+#     (given module name, can be obtained by 'attributes' rule)
+#   - an instance of 'project-target' class (from targets.jam)
+#     (given a module name, can be obtained by 'target' rule)
+#
+#  Typically, projects are created as result of loading Jamfile, which is
+#  do by rules 'load' and 'initialize', below. First, module for Jamfile
+#  is loaded and new project-attributes instance is created. Some rules
+#  necessary for project are added to the module (see 'project-rules' module)
+#  at the bottom of this file.
+#  Default project attributes are set (inheriting attributes of parent project, if
+#  it exists). After that, Jamfile is read. It can declare its own attributes,
+#  via 'project' rule, which will be combined with already set attributes.
+#
+#
+#  The 'project' rule can also declare project id, which will be associated with 
+#  the project module.
+#
+#  There can also be 'standalone' projects. They are created by calling 'initialize'
+#  on arbitrary module, and not specifying location. After the call, the module can
+#  call 'project' rule, declare main target and behave as regular projects. However,
+#  since it's not associated with any location, it's better declare only prebuilt 
+#  targets.
+#
+#  The list of all loaded Jamfile is stored in variable .project-locations. It's possible
+#  to obtain module name for a location using 'module-name' rule. The standalone projects
+#  are not recorded, the only way to use them is by project id.
+
+
+import modules : peek poke ;
+import numbers ;
+import path ;
+import sequence ;
+import errors : error ;
+import project-roots ;
+
+import print ;
+import "class" : new ;
+import errors ;
+import assert ;
+import property-set ;
+
+#
+#   Loads jamfile at the given location. After loading, project global
+#   file and jamfile needed by the loaded one will be loaded recursively.
+#   If the jamfile at that location is loaded already, does nothing.
+#   Returns the project module for the Jamfile.
+#
+rule load ( jamfile-location )
+{   
+    # Load project root, first. It might decide to act as Jamfile.
+    project-roots.load $(jamfile-location) ;
+        
+    local module-name = [ module-name $(jamfile-location) ] ;            
+    # If Jamfile is already loaded, don't try again.
+    if ! $(module-name) in $(.jamfile-modules)
+    {      
+        load-jamfile $(jamfile-location) ;
+                
+        for local p in [ attribute $(module-name) projects-to-build ]
+        {
+            load [ path.join $(jamfile-location) $(p) ] ;
+        }
+    }                
+    return $(module-name) ;        
+}
+
+# Makes the specified 'module' act as if it were a regularly loaded Jamfile 
+# at 'location'. If Jamfile is already located for that location, it's an 
+# error. 
+rule act-as-jamfile ( module : location )
+{
+    if [ module-name $(location) ] in $(.jamfile-modules)
+    {
+        errors.error "Jamfile was already loaded for '$(location)'" ;
+    }
+    # Set up non-default mapping from location to module.
+    .module.$(location) = $(module) ;    
+    
+    # Add the location to the list of project locations
+    # so that we don't try to load Jamfile in future
+    .jamfile-modules += [ module-name $(location) ] ;
+    
+    initialize $(module) : $(location) ;
+}
+
+
+# Given 'name' which can be project-id or plain directory name,
+# return project module corresponding to that id or directory.
+# Returns nothing of project is not found.
+rule find ( name : current-location )
+{
+    local project-module ;
+    
+    # Try interpreting name as project id.
+    if [ path.is-rooted $(name) ]
+    {            
+        project-module =  $($(name).jamfile-module) ;
+    }            
+                
+    if ! $(project-module)
+    {            
+        local location = [ path.root $(name) $(current-location) ] ;
+        # If no project is registered for the given location, try to
+        # load it. First see if we have Jamfile. If not we might have project
+        # root, willing to act as Jamfile. In that case, project-root
+        # must be placed in the directory referred by id.
+        
+        project-module = [ module-name $(location) ] ;
+        if ! $(project-module) in $(.jamfile-modules) 
+        {
+            if [ find-jamfile $(location) ]
+            {
+                project-module = [ load $(location) ] ;            
+            }        
+            else
+            {
+                project-module = ;
+            }
+        }                    
+    }
+    
+    return $(project-module) ;
+}
+
+#
+# Returns the name of module corresponding to 'jamfile-location'.
+# If no module corresponds to location yet, associates default
+# module name with that location.
+#
+rule module-name ( jamfile-location )
+{
+    if ! $(.module.$(jamfile-location))
+    {
+        # Root the path, so that locations are always umbiguious.
+        # Without this, we can't decide if '../../exe/program1' and '.'
+        # are the same paths, or not.
+        jamfile-location = [ path.root $(jamfile-location) [ path.pwd ] ] ;
+        .module.$(jamfile-location) =  Jamfile<$(jamfile-location)> ;
+    }
+    return $(.module.$(jamfile-location)) ;
+}
+
+# Default patterns to search for the Jamfiles to use for build
+# declarations.
+#
+JAMFILE = [ modules.peek : JAMFILE ] ;
+JAMFILE ?= [Jj]amfile.v2 [Jj]amfile [Jj]amfile.jam ;
+
+# Find the Jamfile at the given location. This returns the exact names of
+# all the Jamfiles in the given directory. The optional parent-root argument
+# causes this to search not the given directory but the ones above it up
+# to the directory given in it.
+#
+local rule find-jamfile (
+    dir # The directory(s) to look for a Jamfile.
+    parent-root ? # Optional flag indicating to search for the parent Jamfile.
+    )
+{
+    # Glob for all the possible Jamfiles according to the match pattern.
+    #
+    local jamfile-glob = ;
+    if $(parent-root)
+    {
+        if ! $(.parent-jamfile.$(dir))
+        {     
+            .parent-jamfile.$(dir) = 
+              [ path.glob-in-parents $(dir) : $(JAMFILE) : $(parent-root) ] ;            
+        }        
+        jamfile-glob = $(.parent-jamfile.$(dir)) ;                            
+    }
+    else
+    {
+        if ! $(.jamfile.$(dir))
+        {            
+            .jamfile.$(dir) = [ path.glob $(dir) : $(JAMFILE) ] ;         
+        }   
+        jamfile-glob = $(.jamfile.$(dir)) ;
+        
+    }
+
+    return $(jamfile-glob) ;
+}
+
+# Load a Jamfile at the given directory. Returns nothing.
+# Will attempt to load the file as indicated by the JAMFILE patterns. 
+# Effect of calling this rule twice with the same 'dir' is underfined.
+
+local rule load-jamfile (
+    dir # The directory of the project Jamfile.
+    )
+{
+    # See if the Jamfile is where it should be.
+    #
+    local jamfile-to-load = [ find-jamfile $(dir) ] ;
+
+    # Could not find it, error.
+    #
+    if ! $(jamfile-to-load)
+    {
+        errors.error
+            "Unable to load Jamfile." :
+            "Could not find a Jamfile in directory '$(dir)'". : 
+            "Attempted to find it with pattern '"$(JAMFILE:J=" ")"'." :
+            "Please consult the documentation at 'http://www.boost.org'." ;
+    }
+
+    # Multiple Jamfiles found in the same place. Warn about this.
+    # And ensure we use only one of them.
+    # As a temporary convenience measure, if there's Jamfile.v2 amount
+    # found files, suppress the warning and use it.
+    #
+    if $(jamfile-to-load[2-])
+    {
+        local v2-jamfiles = [ MATCH (.*[Jj]amfile\\.v2) : $(jamfile-to-load) ] ;
+
+        if $(v2-jamfiles) && ! $(v2-jamfiles[2])
+        {
+            jamfile-to-load = $(v2-jamfiles) ;
+        }        
+        else
+        {                    
+            ECHO
+              "WARNING: Found multiple Jamfiles at this '"$(dir)"' location!"
+                "Loading the first one: '" [ path.basename $(jamfile-to-load[1]) ]  "'." ;
+        }
+                    
+        jamfile-to-load = $(jamfile-to-load[1]) ;
+    }
+    
+    # The module of the jamfile.
+    #
+    local jamfile-module = [ module-name  [ path.parent $(jamfile-to-load) ] ] ;
+
+    # Initialize the jamfile module before loading.
+    #
+    initialize $(jamfile-module) : [ path.parent $(jamfile-to-load) ] ;
+
+    # Now load the Jamfile in it's own context.
+    # Initialization might have load parent Jamfiles, which might have
+    # loaded the current Jamfile with use-project. Do a final check to make
+    # sure it's not loaded already.
+    if ! $(jamfile-module) in $(.jamfile-modules)
+    {           
+        .jamfile-modules += $(jamfile-module) ;
+        modules.load $(jamfile-module) :  [ path.native $(jamfile-to-load) ] : . ;
+    }
+    .current-project = $(.current-project[2-]) ;
+}
+
+# Initialize the module for a project. 
+#
+rule initialize (
+    module-name # The name of the project module.
+    : location ? # The location (directory) of the project to initialize.
+                 # If not specified, stanalone project will be initialized.               
+    )
+{
+    # TODO: need to consider if standalone projects can do anything but defining
+    # prebuilt targets. If so, we need to give more sensible "location", so that
+    # source paths are correct.
+    location ?= "" ;
+    # Create the module for the Jamfile first.    
+    module $(module-name)
+    {          
+    }    
+    $(module-name).attributes = [ new project-attributes $(location) ] ;
+    local attributes = $($(module-name).attributes) ;
+    
+    if $(location)
+    {        
+        $(attributes).set source-location : [ path.make $(location) ] : exact ;    
+    }
+    else
+    {
+        $(attributes).set source-location : "" : exact ;    
+    }
+    
+    $(attributes).set requirements : [ property-set.empty ] : exact ;
+    $(attributes).set usage-requirements : [ property-set.empty ] : exact ;    
+
+    # Import rules common to all project modules from project-rules module,
+    # defined at the end of this file.
+    modules.clone-rules project-rules $(module-name) ;
+
+    # We search for parent/project-root only if jamfile was specified --- i.e
+    # if the project is not standalone.
+    if $(location)
+    {       
+        # Make sure we've loaded the project-root corresponding to this
+        # Jamfile.
+        #
+        local project-root-object = [ project-roots.load $(location) ] ;
+        local project-root = [ $(project-root-object).get-location ] ;
+        
+        $(attributes).set project-root : $(project-root-object) : exact ;
+
+        local parent = [ find-jamfile $(location) $(project-root) ] ;
+        local parent-module = ;
+        if $(parent)
+        {
+            parent-module = [ load [ path.parent $(parent[1]) ] ] ;
+        }
+        
+        inherit-attributes $(module-name) : $(project-root-object) : $(parent-module) ;
+    }    
+    
+    .current-project = [ target $(module-name) ] $(.current-project) ;
+}
+
+# Make 'project-module' inherit attributes of project root and parent module.
+rule inherit-attributes ( project-module : project-root : parent-module ? )
+{
+    # Register with the project root. This will inject project-root
+    # constants and do some other initialization.
+    $(project-root).register-project $(project-module) ;
+
+    if $(parent-module)
+    {
+        local attributes = $($(project-module).attributes) ;        
+        local pattributes = [ attributes $(parent-module) ] ;
+        $(attributes).set parent : [ path.parent 
+            [ path.make [ modules.binding $(parent-module) ] ] ] ;
+        $(attributes).set default-build 
+            : [ $(pattributes).get default-build ] ;
+        $(attributes).set requirements
+            : [ $(pattributes).get requirements ] : exact ;
+        $(attributes).set usage-requirements
+            : [ $(pattributes).get usage-requirements ] : exact ;
+        local parent-build-dir = [ $(pattributes).get build-dir ] ;
+        if $(parent-build-dir)
+        {            
+            # Have to compute relative path from parent dir to our dir
+            # Convert both paths to absolute, since we cannot
+            # find relative path from ".." to "."
+            
+            local location = [ attribute $(project-module) location ] ;
+            local parent-location = [ attribute $(parent-module) location ] ;
+            
+            local pwd = [ path.pwd ] ;
+            local parent-dir = [ path.root $(parent-location) $(pwd) ] ;
+            local our-dir = [ path.root $(location) $(pwd) ] ;
+            $(attributes).set build-dir : [ path.join $(parent-build-dir) 
+                  [ path.relative $(our-dir) $(parent-dir) ] ] : exact ;
+        }        
+    }            
+}
+
+
+# Associate the given id with the given project module
+rule register-id ( id : module )
+{
+    $(id).jamfile-module = $(module) ;
+}
+
+# Class keeping all the attributes of a project.
+#
+# The standard attributes are "id", "location", "project-root", "parent"
+# "requirements", "default-build", "source-location" and "projects-to-build".
+class project-attributes 
+{
+    import property ;
+    import property-set ;
+    import errors ;
+    import path ;
+    import print ;
+    import sequence ;
+        
+    rule __init__ ( location )
+    {       
+        self.location = $(location) ;
+    }
+            
+    # Set the named attribute from the specification given by the user.
+    # The value actually set may be different.
+    rule set ( attribute : specification * 
+        : exact ? # Sets value from 'specification' without any processing
+        ) 
+    {
+        if $(exact)
+        {
+            self.$(attribute) = $(specification) ;
+        }
+        else if $(attribute) = "requirements" 
+        {
+            specification = [ property.translate-paths $(specification)
+                              : $(self.location) ] ;            
+            specification = 
+              [ property.expand-subfeatures-in-conditions $(specification) ] ;                
+            specification = [ property.make $(specification) ] ;            
+            result = [ property-set.create $(specification) ] ;            
+            
+            # If we have inherited properties, need to refine them with the
+            # specified.
+            local current = $(self.requirements) ;                                    
+            if $(current)
+            {
+                result = [ $(current).refine $(result) ] ;
+            }
+
+            if $(result[1]) = "@error"
+            {
+                errors.error
+                    "Requirements for project at '$(self.location)'"
+                    "conflict with parent's." :
+                    "Explanation: " $(result[2-]) ;
+            }
+            else
+            {
+                self.requirements = $(result) ;
+            }
+        }
+        else if $(attribute) = "usage-requirements"
+        {
+            local unconditional ;
+            for local p in $(specification)
+            {
+                local split = [ property.split-conditional $(p) ] ;
+                split ?= nothing $(p) ;
+                unconditional += $(split[2]) ;
+            }
+            
+            local non-free = [ property.remove free : $(unconditional) ] ;
+            if $(non-free)
+            {
+                errors.error "usage-requirements" $(specification) "have non-free properties" $(non-free) ;
+            }            
+            local t = [ property.translate-paths $(specification)
+                                      : $(self.location) ] ;
+            if $(self.usage-requirements)
+            {
+                self.usage-requirements = [ property-set.create 
+                    [ $(self.usage-requirements).raw ] $(t) ] ;
+            }
+            else 
+            {
+                self.usage-requirements = [ property-set.create $(t) ] ;
+            }                        
+        }        
+        else if $(attribute) = "default-build"
+        {
+            self.default-build = [ property.make $(specification) ] ;
+        }        
+        else if $(attribute) = "source-location"
+        { 
+            self.source-location = [ path.root 
+                [ path.make $(specification) ] $(self.location) ] ;
+        }            
+        else if $(attribute) = "build-dir"
+        {
+            self.build-dir = [ path.root $(specification) $(self.location) ] ;
+        }        
+        else if ! $(attribute) in "id" "default-build" "location" "source-location"
+          "parent" "projects-to-build"
+        {
+            errors.error "Invalid project attribute '$(attribute)' specified "
+                               "for project at '$(self.location)'" ;
+        }
+        else
+        {
+            self.$(attribute) = $(specification) ;
+        }
+    }
+
+    # Returns the value of the given attribute.
+    rule get ( attribute )
+    {
+        return $(self.$(attribute)) ;
+    }
+
+    # Prints the project attributes.
+    rule print ( )
+    {
+        local id = $(self.id) ; id ?= (none) ;
+        local parent = $(self.parent) ; parent ?= (none) ;
+        print.section "'"$(id)"'" ;
+        print.list-start ;
+        print.list-item "Parent project:" $(parent) ;
+        print.list-item "Requirements:" [ $(self.requirements).raw ] ;
+        print.list-item "Default build:" $(self.default-build) ;
+        print.list-item "Source location:" $(self.source-location) ;
+        print.list-item "Projects to build:" 
+                            [ sequence.insertion-sort $(self.projects-to-build) ] ;
+        print.list-end ;
+    }
+    
+}
+
+# Returns the project which is currently being loaded
+rule current ( )
+{
+    return $(.current-project[1]) ;
+}
+
+# Returns the project-attribute instance for the specified jamfile module.
+rule attributes ( project )
+{
+    return $($(project).attributes) ;
+}
+
+# Returns the value of the specified attribute in the specified jamfile module.
+rule attribute ( project attribute )
+{
+    return [ $($(project).attributes).get $(attribute) ] ;        
+}
+
+# Returns the project target corresponding to the 'project-module'.
+rule target ( project-module )
+{
+    if ! $(.target.$(project-module))
+    {
+        .target.$(project-module) = [ new project-target $(project-module) 
+          : $(project-module) 
+           : [ attribute $(project-module) requirements ] ] ;
+    }
+    return $(.target.$(project-module)) ;    
+}
+
+# Use/load a project.
+rule use ( id : location )
+{
+    local saved-project = $(.current-project) ;
+    local project-module = [ project.load $(location) ] ;
+    local declared-id = [ project.attribute $(project-module) id ] ;
+
+    if ! $(declared-id)
+    {
+        error "project loaded by 'use-project' has no project-id." ;
+    }
+    if $(declared-id) != $(id)
+    {
+        error project \"$(declared-id)\" at \"$(location)\" redeclared with id \"$(id)\". ;
+    }
+    .current-project = $(saved-project) ;
+}
+
+# This module defines rules common to all projects
+module project-rules
+{
+    rule project ( id ? : options * : * )
+    {
+        import project ;
+        import path ;
+                
+        local attributes = [ project.attributes $(__name__) ] ;
+        if $(id) 
+        {
+           id = [ path.root $(id) / ] ;
+           project.register-id $(id) : $(__name__) ;
+           $(attributes).set id : $(id) ;
+        }
+
+        for n in 2 3 4 5 6 7 8 9
+        {
+            local option = $($(n)) ;
+            if $(option) 
+            {
+                $(attributes).set $(option[1]) : $(option[2-]) ;
+            }
+        }
+    }
+
+    rule use-project ( id : where )
+    {
+        import project ;
+        import path ;
+        local attributes = [ project.attributes $(__name__) ] ;
+        project.use $(id) : [ path.root 
+            [ path.make $(where) ] [ $(attributes).get location ] ] ;
+    }
+
+    rule build-project ( dir )
+    {
+        import project ;
+        local attributes = [ project.attributes $(__name__) ] ;
+
+        local now = [ $(attributes).get projects-to-build ] ;
+        $(attributes).set projects-to-build : $(now) $(dir) ;
+    }
+    
+    rule explicit ( target-names * )
+    {
+        import project ;
+        local t = [ project.target $(__name__) ] ;
+        for local n in $(target-names)
+        {            
+            $(t).mark-target-as-explicit $(n) ;
+        }        
+    }    
+    
+    rule glob ( wildcards + )
+    {
+        import path ;
+        import project ;
+        
+        local location = [ project.attribute $(__name__) source-location ] ;
+
+        local all-paths ;
+        if ! $(wildcards:D)
+        {
+            # No directory in any wildcard -- the simplest case.
+            all-paths = [ path.glob $(location) : $(wildcards) ] ;
+            all-paths = $(all-paths:D="") ;
+        } 
+        else
+        {
+            for local w in $(wildcards)
+            {
+                local l = [ path.join $(location) $(w:D) ] ;
+                local paths = [ path.glob $(l) : $(w:D="") ] ;                
+                # The paths we've found are relative to current directory,
+                # but the names specified in sources list are assumed to
+                # be relative to source directory of the corresponding
+                # prject. So, just make the name absolute.
+                for local p in $(paths)
+                {
+                    all-paths += [ path.root $(p) [ path.pwd ] ] ;
+                }                
+            }
+            
+        }
+
+        return $(all-paths) ;                
+    }        
+}
+
+
+local rule __test__ ( )
+{
+    import assert ;
+    assert.result foo/bar : remove-trailing-slash foo/bar/ ;
+    assert.result foo/bar : remove-trailing-slash foo/bar ;
+    assert.result foo : remove-trailing-slash foo/ ;
+    assert.result foo : remove-trailing-slash foo ;
+}

Added: boost-jam/boost-build/branches/upstream/current/build/property-set.jam
===================================================================
--- boost-jam/boost-build/branches/upstream/current/build/property-set.jam	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/build/property-set.jam	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,319 @@
+#  Copyright (C) Vladimir Prus 2002. Permission to copy, use, modify, sell and
+#  distribute this software is granted provided this copyright notice appears in
+#  all copies. This software is provided "as is" without express or implied
+#  warranty, and with no claim as to its suitability for any purpose.
+
+import "class" : new ;
+import feature ;
+import property ;
+import sequence ;
+
+# Class for storing a set of properties.
+# - there's 1<->1 correspondence between identity and value. No
+#   two instances of the class are equal. To maintain this property,
+#   the 'property-set.create' rule should be used to create new instances.
+#   Instances are immutable.
+# 
+# - each property is classified with regard to it's effect on build
+#   results. Incidental properties have no effect on build results, from
+#   Boost.Build point of view. Others are either free, or non-free, which we
+#   call 'base'. Each property belong to exactly one of those categories and
+#   it's possible to get list of properties in each category.
+#
+#   In addition, it's possible to get list of properties with specific
+#   attribute.
+#
+# - several operations, like and refine and as-path are provided. They all use
+#   caching whenever possible.
+#
+class property-set 
+{
+    import feature ;
+    import property-set ;
+    import property ;
+    import set ;
+            
+    rule __init__ ( raw-properties * )
+    {        
+        self.raw = $(raw-properties) ;
+        
+        for local p in $(raw-properties)
+        {
+            local att = [ feature.attributes $(p:G) ] ;        
+            # A feature can be both incidental and free,
+            # in which case we add it to incidental.
+            if incidental in $(att)
+            {
+                self.incidental += $(p) ;
+            }
+            else if free in $(att)
+            {
+                self.free += $(p) ;
+            }
+            else 
+            {
+                self.base += $(p) ;
+            }
+        
+            if dependency in $(att)
+            {
+                self.dependency += $(p) ;
+            }
+            else
+            {
+                self.non-dependency += $(p) ;
+            }
+            
+            if [ MATCH (:) : $(p:G=) ]            
+            {
+                self.conditional += $(p) ;
+            }
+            else
+            {
+                self.non-conditional += $(p) ;
+            }
+            
+                                    
+            if propagated in $(att)
+            {
+                self.propagated += $(p) ;
+            }                        
+            if link-incompatible in $(att)
+            {
+                self.link-incompatible += $(p) ;
+            }                                
+        }
+        
+    }
+    
+    
+    # Returns Jam list of stored properties
+    rule raw ( )
+    {
+        return $(self.raw) ;
+    }
+    
+    # Returns properties that are neither incidental nor free
+    rule base ( )
+    {
+        return $(self.base) ;
+    }
+    
+    
+    # Returns free properties which are not dependency properties
+    rule free ( )
+    {
+        return $(self.free) ;
+    }
+    
+    # Returns dependency properties
+    rule dependency ( )
+    {
+        return $(self.dependency) ;
+    }
+    
+    rule non-dependency ( )
+    {
+        return $(self.non-dependency) ;
+    }
+    
+    rule conditional ( )
+    {
+        return $(self.conditional) ;
+    }
+        
+    rule non-conditional ( )
+    {
+        return $(self.non-conditional) ;
+    }
+              
+    # Returns incidental properties
+    rule incidental ( )
+    {
+        return $(self.incidental) ;
+    }
+    
+    rule refine ( ps )
+    {
+        if ! $(self.refined.$(ps))
+        {
+            local r = [ property.refine $(self.raw) : [ $(ps).raw ] ] ; 
+            if $(r[1]) != "@error"
+            {
+                self.refined.$(ps) = [ property-set.create $(r) ] ; 
+            }
+            else
+            {
+                self.refined.$(ps) = $(r) ;
+            }
+        }
+        return $(self.refined.$(ps)) ;
+    }
+    
+    rule expand ( )
+    {
+        if ! $(self.expanded)
+        {
+            self.expanded = [ property-set.create [ feature.expand $(self.raw) ] ] ;
+        }
+        return $(self.expanded) ;
+    }
+    
+    
+    rule expand-composites ( )
+    {
+        if ! $(self.composites)
+        {
+            self.composites = [ property-set.create
+                [ feature.expand-composites $(self.raw) ] ] ;
+        }
+        return $(self.composites) ;
+    }
+                
+    rule evaluate-conditionals ( context ? )
+    {
+        context ?= $(__name__) ;
+        if ! $(self.evaluated.$(context))
+        {
+            self.evaluated.$(context) = [ property-set.create 
+                [ property.evaluate-conditionals-in-context $(self.raw) : [ $(context).raw ] ] ] ;
+        }
+        return $(self.evaluated.$(context)) ;        
+    }
+    
+    rule propagated ( )
+    {
+        if ! $(self.propagated-ps)
+        {
+            self.propagated-ps = [ property-set.create $(self.propagated) ] ;
+        }
+        return $(self.propagated-ps) ;
+    }                   
+    
+    rule link-incompatible ( )
+    {
+        if ! $(self.link-incompatible-ps)
+        {
+            self.link-incompatible-ps = 
+              [ property-set.create $(self.link-incompatible) ] ;
+        }
+        return $(self.link-incompatible-ps) ;
+    }
+    
+    
+    rule run-actions ( )
+    {
+        if ! $(self.run)
+        {
+            self.run = [ property-set.create [ feature.run-actions $(self.raw) ] ] ;
+        }
+        return $(self.run) ;
+    }
+    
+    rule add-defaults ( )
+    {
+        if ! $(self.defaults)
+        {
+            self.defaults = [ property-set.create 
+                [ feature.add-defaults $(self.raw) ] ] ;
+        }
+        return $(self.defaults) ;
+    }
+    
+    
+    rule as-path ( )
+    {
+        if ! $(self.as-path)
+        {
+            self.as-path = [ property.as-path $(self.base) ] ;
+        }        
+        return $(self.as-path) ;
+    }        
+    
+    rule add ( ps )
+    {
+        if ! $(self.added.$(ps))        
+        {
+            self.added.$(ps) = [ property-set.create $(self.raw) [ $(ps).raw ] ] ;
+        }
+        return $(self.added.$(ps)) ;
+    }            
+    
+    rule add-raw ( properties * )
+    {
+        return [ add [ property-set.create $(properties) ] ] ;
+    }            
+    
+    rule link-incompatible-with ( ps )
+    {
+        if ! $(.li.$(ps))
+        {
+            local li1 = [ $(__name__).link-incompatible ] ;
+            local li2 = [ $(ps).link-incompatible ] ;            
+            if [ set.equal $(li1) : $(li2) ] 
+            {
+                .li.$(ps) = false ;
+            }
+            else
+            {
+                .li.$(ps) = true ;
+            }            
+        }    
+        if $(.li.$(ps)) = true
+        {
+            return true ;
+        }
+        else
+        {
+            return ;
+        }                
+    }
+    
+
+    
+    # Returns all values of 'feature'.
+    rule get ( feature )
+    {
+        return [ feature.get-values $(feature) : $(self.raw) ] ;
+    }
+    
+}
+
+# Creates new 'property-set' instance for the given raw properties,
+# or returns an already existing ones.
+rule create ( raw-properties * )
+{
+    raw-properties = [ sequence.unique 
+        [ sequence.insertion-sort $(raw-properties) ] ] ;
+         
+    local key = $(raw-properties:J=-:E=) ;
+    
+    if ! $(.ps.$(key)) 
+    {
+        .ps.$(key) = [ new property-set $(raw-properties) ] ;
+    }
+    return $(.ps.$(key)) ;    
+}
+NATIVE_RULE property-set : create ;
+
+# Creates new 'property-set' instances after checking
+# that all properties are valid and converting incidental
+# properties into gristed form.
+rule create-with-validation ( raw-properties * )
+{
+    property.validate $(raw-properties) ;
+    
+    return [ create [ property.make $(raw-properties) ] ] ;
+}
+
+
+# Returns property-set with empty set of properties.
+rule empty ( )
+{
+    if ! $(.empty)
+    {
+      .empty = [ create ] ;
+    }
+    
+    return $(.empty) ;
+}

Added: boost-jam/boost-build/branches/upstream/current/build/property.jam
===================================================================
--- boost-jam/boost-build/branches/upstream/current/build/property.jam	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/build/property.jam	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,639 @@
+#  Copyright (C) Vladimir Prus 2002. Permission to copy, use, modify, sell and
+#  distribute this software is granted provided this copyright notice appears in
+#  all copies. This software is provided "as is" without express or implied
+#  warranty, and with no claim as to its suitability for any purpose.
+
+import utility : ungrist ;
+import sequence : unique ;
+import errors : error ;
+import feature ;
+import regex ;
+import sequence ;
+import set ;
+import path ;
+import assert ;
+
+# Refines 'properties' by overriding any non-free properties 
+# for which a different value is specified in 'requirements'. 
+# Conditional requirements are just added without modification.
+# Returns the resulting list of properties.
+rule refine ( properties * : requirements * )
+{
+    local result ;
+    local error ;
+    
+    # All the elements of requirements should be present in the result
+    # Record them so that we can handle 'properties'.
+    for local r in $(requirements)
+    {
+        # Don't consider conditional requirements.
+        if ! [ MATCH (:) : $(r:G=) ]
+        {            
+            # Note: cannot use local here, so take an ugly name
+            __require__$(r:G) = $(r:G=) ;
+        }        
+    }
+
+    for local p in $(properties)
+    {       
+        # No processing for free properties
+        if [ MATCH (:) : $(p:G=) ]
+        {
+            # Skip conditional properties
+            result += $(p) ;
+        }        
+        else if free in [ feature.attributes $(p:G) ]
+        {
+            result += $(p) ;
+        }
+        else
+        {
+            local required-value = $(__require__$(p:G)) ;
+            if $(required-value)
+            {
+                local value = $(p:G=) ;
+                if $(value) != $(required-value)
+                {
+                    result += $(p:G)$(required-value) ;
+                }
+                else
+                {
+                    result += $(p) ;
+                }
+            }
+            else
+            {
+                result += $(p) ;
+            }
+        }
+    }
+
+    # Unset our ugly map.        
+    for local r in $(requirements)
+    {
+         __require__$(r:G) = ;
+    }
+    
+    if $(error)
+    {
+        return $(error) ;
+    }
+    else
+    {
+        return [ unique $(result) $(requirements) ] ;
+    }
+}
+
+# Removes all conditional properties which conditions are not met
+# For those with met conditions, removes the condition. Properies
+# in conditions are looked up in 'context'
+rule evaluate-conditionals-in-context ( properties * : context * )
+{
+    local base ;
+    local conditionals ;
+    for local p in $(properties)
+    {
+        if [ MATCH (:<) : $(p) ]
+        {
+            conditionals += $(p) ;
+        }
+        else
+        {
+            base += $(p) ;
+        }        
+    }
+
+    local result = $(base) ;
+    for local p in $(conditionals)
+    {
+        # Separate condition and property
+        local s = [ MATCH (.*):(<.*) : $(p) ] ;
+        # Split condition into individual properties
+        local c = [ regex.split $(s[1]) "," ] ;
+        # Evaluate condition
+        if $(c) in $(context)
+        {
+            result += $(s[2]) ;
+        }                
+    }
+    return $(result) ;    
+}
+
+rule expand-subfeatures-in-conditions ( properties * )
+{
+    local result ;
+    for local p in $(properties)
+    {
+        local s = [ MATCH (.*):(<.*) : $(p) ] ;        
+        if ! $(s)
+        {
+            result += $(p) ;
+        }
+        else
+        {
+            local condition = $(s[1]) ;
+            # Condition might include several elements
+            condition = [ regex.split $(condition) "," ] ;
+            local value = $(s[2]) ;
+            local e ;
+            for local c in $(condition)
+            {           
+                if [ MATCH "^(<toolset>|<toolset->)" : $(c:G) ] ||
+                   [ MATCH "^(<os>)" : $(c:G) ]
+                {
+                    # It common that condition includes a toolset which
+                    # was never defined, or mentiones subfeatures which
+                    # were never defined. In that case, validation will
+                    # only produce an spirious error, so don't validate.
+                    e += [ feature.expand-subfeatures $(c) : true ] ;
+                }               
+                else
+                {
+                    e += [ feature.expand-subfeatures $(c) ] ;
+                }                
+            }
+            
+            if $(e) = $(condition)
+            {
+                result += $(p) ;
+            }
+            else
+            {
+                local individual-subfeatures = [ set.difference $(e) : $(condition) ] ;
+                result += $(individual-subfeatures:J=,):$(value) ;
+            }            
+        }        
+    }    
+    return $(result) ;
+}
+
+
+
+# Helper for as-path, below. Orders properties with the implicit ones
+# first, and within the two sections in alphabetical order of feature
+# name.
+local rule path-order ( x y )
+{
+    if $(y:G) && ! $(x:G)
+    {
+        return true ;
+    }
+    else if $(x:G) && ! $(y:G)
+    {
+        return ;
+    }
+    else
+    {
+        if ! $(x:G)
+        {
+            x = [ feature.expand-subfeatures $(x) ] ;
+            y = [ feature.expand-subfeatures $(y) ] ;
+        }
+        
+        if $(x[1]) < $(y[1])
+        {
+            return true ;
+        }
+    }
+}
+
+# Returns a path which represents the given expanded property set.
+rule as-path ( properties * )
+{
+    local entry = .result.$(properties:J=-) ;
+    
+    if ! $($(entry))
+    {
+        # trim redundancy
+        properties = [ feature.minimize $(properties) ] ;
+    
+        # sort according to path-order
+        properties = [ sequence.insertion-sort $(properties) : path-order ] ;
+    
+        local components ;
+        for local p in $(properties)
+        {
+            if $(p:G)
+            {
+                local f = [ ungrist $(p:G) ] ;
+                components += $(f)-$(p:G=) ;
+            }
+            else
+            {
+                components += $(p) ;
+            }
+        }
+        
+        $(entry) = $(components:J=/) ;
+    }    
+    
+    return $($(entry)) ;
+}
+
+# Exit with error if property is not valid.
+local rule validate1 ( property )
+{
+    local msg ;
+    if $(property:G)
+    {
+        local feature = $(property:G) ;
+        local value = $(property:G=) ;
+
+        if ! [ feature.valid $(feature) ]
+        {
+            feature = [ ungrist $(property:G) ] ; # Ungrist for better error messages
+            msg = "unknown feature '$(feature)'" ;
+        }
+        else if $(value) && ! free in [ feature.attributes $(feature) ] 
+        {
+            feature.validate-value-string $(feature) $(value) ;
+        } 
+        else if ! $(value)
+        {
+            feature = [ ungrist $(property:G) ] ; # Ungrist for better error messages
+            msg = "No value specified for feature '$(feature)'" ; 
+        }
+    }
+    else
+    {
+        local feature = [ feature.implied-feature $(property) ] ;
+        feature.validate-value-string $(feature) $(property) ;
+    }
+    if $(msg) 
+    {
+        error "Invalid property "'$(property:J=" ")'": "$(msg:J=" "). ;
+    }
+}
+
+rule validate ( properties * )
+{
+    for local p in $(properties)
+    {
+        validate1 $(p) ;
+    }
+}
+
+rule validate-property-sets ( property-sets * )
+{
+    for local s in $(property-sets)
+    {
+        validate [ feature.split $(s) ] ;
+    }
+}
+
+# Makes a property set from 'specification', converting implicit values into 
+# full properties.
+rule make ( specification * )
+{
+    local result ;
+    for local e in $(specification) 
+    {
+        if $(e:G)
+        {
+            result += $(e) ;
+        }
+        else if [ feature.is-implicit-value $(e) ]
+        {
+            local feature = [ feature.implied-feature $(e) ] ;
+            result += $(feature)$(e) ;      
+        }
+        else
+        {
+            error "'$(e)' is not a valid for property specification" ;
+        }
+    }
+    return $(result) ;
+}
+
+# Returns a property sets which include all the elements in 'properties' that
+# do not have attributes listed in 'attributes'. 
+rule remove ( attributes + : properties * )
+{
+    local result ;
+    for local e in $(properties)
+    {
+        if ! [ set.intersection $(attributes) : [ feature.attributes $(e:G) ] ]
+        {
+            result += $(e) ;
+        }
+    }
+    return $(result) ;
+}
+
+# Returns a property set which include all properties in 'properties' that have
+# any of 'attributes'.
+rule take ( attributes + : properties * )
+{
+    local result ;
+    for local e in $(properties)
+    {
+        if [ set.intersection $(attributes) : [ feature.attributes $(e:G) ] ]
+        {
+            result += $(e) ;
+        }
+    }
+    return $(result) ;
+}
+
+# Selects properties which correspond to any of the given features.
+rule select ( features * : properties * )
+{
+    local result ;
+    
+    # add any missing angle brackets
+    local empty = "" ;
+    features = $(empty:G=$(features)) ;
+    
+    for local p in $(properties)
+    {
+        if $(p:G) in $(features)
+        {
+            result += $(p) ;
+        }
+    }
+    return $(result) ;
+}
+
+# Returns a modified version of properties with all values of the
+# given feature replaced by the given value.
+# If 'value' is empty the feature will be removed
+rule change ( properties * : feature value ? )
+{
+    local result ; 
+    for local p in $(properties)
+    {
+        if $(p:G) = $(feature)
+        {
+            result += $(value:G=$(feature)) ;            
+        }
+        else
+        {
+            result += $(p) ;
+        }
+    }
+    return $(result) ;
+}
+
+# If 'property' is conditional property, returns
+# condition and the property, e.g
+# <variant>debug,<toolset>gcc:<inlining>full will become
+# <variant>debug,<toolset>gcc <inlining>full.
+# Otherwise, returns empty string.
+rule split-conditional ( property )
+{
+    local m = [ MATCH "(.+):<(.+)" : $(property) ] ;
+    if $(m)
+    {
+        return $(m[1]) <$(m[2]) ;
+    }    
+}
+
+
+# Interpret all path properties in 'properties' as relative to 'path'
+# The property values are assumed to be in system-specific form, and
+# will be translated into normalized form.
+rule translate-paths ( properties * : path )
+{
+    local result ;
+    for local p in $(properties)
+    {
+        local split = [ split-conditional $(p) ] ;
+        local condition = "" ; 
+        if $(split)
+        {
+            condition = $(split[1]): ;
+            p = $(split[2]) ;
+        }
+
+        # need to do this here to get reasonable error messages for
+        # unrecognized implicit features.
+        validate $(p) ;   
+        
+        if path in [ feature.attributes $(p:G) ] 
+        {
+            local values = [ regex.split $(p:TG=) "&&" ] ;
+            local t ;
+            for local v in $(values)
+            {
+                t += [ path.root [ path.make $(v) ] $(path) ] ;                
+            }
+            t = $(t:J="&&") ;            
+            result += $(condition)$(t:TG=$(p:G)) ;
+        }
+        else
+        {
+            result += $(condition)$(p) ;
+        }        
+    }
+    return $(result) ;
+}
+
+# Class which maintains a property set -> string
+# mapping
+class property-map
+{
+    import numbers ;
+    import sequence ;
+    import errors : error ;
+    
+    rule __init__ ( )
+    {        
+        self.next-flag = 1 ;
+    }
+    
+    # Associate 'value' with 'properties'
+    rule insert ( properties + : value )
+    {
+        self.all-flags += $(self.next-flag) ;
+        self.properties.$(self.next-flag) = $(properties) ;
+        self.value.$(self.next-flag) = $(value) ;
+
+        self.next-flag = [ numbers.increment $(self.next-flag) ] ;
+    }
+
+    # Return the value associated with 'properties'
+    # or any subset of it. If more than one
+    # subset has value assigned to it, return the
+    # value for the longest subset, if it's unique.
+    rule find ( properties + )
+    {
+        return [ find-replace $(properties) ] ;
+    }
+    
+    # Find the value associated with 'properties'.
+    # If 'value' parameter is given, replaces the found value
+    # Returns the value that were stored originally.
+    rule find-replace ( properties + : value ? )
+    {
+        # First find all matches
+        local matches ;
+        local match-ranks ;
+        for local i in $(self.all-flags)
+        {
+            if $(self.properties.$(i)) in $(properties)
+            {
+                matches += $(i) ;
+                match-ranks += [ sequence.length 
+                    $(self.properties.$(i)) ] ;
+            }
+        }
+        local best = [ sequence.select-highest-ranked 
+            $(matches) : $(match-ranks) ] ;
+        if $(best[2])
+        {
+            error "Ambiguous key" ;
+        }        
+        local original = $(self.value.$(best)) ;
+        if $(value)
+        {
+            self.value.$(best) = $(value) ;
+        }        
+        return $(original) ;
+    }      
+}
+
+local rule __test__ ( )
+{
+    import errors : try catch ;
+    import feature ;
+    import feature : feature subfeature compose ;
+    
+    # local rules must be explicitly re-imported
+    import property : path-order ;
+    
+    feature.prepare-test property-test-temp ;
+
+    feature toolset : gcc : implicit symmetric ;
+    subfeature toolset gcc : version : 2.95.2 2.95.3 2.95.4
+      3.0 3.0.1 3.0.2 : optional ;
+    feature define : : free ;
+    feature runtime-link : dynamic static : symmetric link-incompatible ;
+    feature optimization : on off ;
+    feature variant : debug release : implicit composite symmetric ;
+    feature rtti : on off : link-incompatible ;
+
+    compose <variant>debug : <define>_DEBUG <optimization>off ;
+    compose <variant>release : <define>NDEBUG <optimization>on ;
+
+    import assert ;
+    import "class" : new ;
+    
+    validate <toolset>gcc  <toolset>gcc-3.0.1 : $(test-space) ;
+    
+    assert.true path-order $(test-space) debug <define>foo ;
+    assert.false path-order $(test-space) <define>foo debug ;
+    assert.true path-order $(test-space) gcc debug ;
+    assert.false path-order $(test-space) debug gcc ;
+    assert.true path-order $(test-space) <optimization>on <rtti>on ;
+    assert.false path-order $(test-space) <rtti>on <optimization>on ;
+      
+    assert.result <toolset>gcc <rtti>off <define>FOO
+        : refine <toolset>gcc <rtti>off
+        : <define>FOO
+        : $(test-space)
+        ;
+
+    assert.result <toolset>gcc <optimization>on
+        : refine <toolset>gcc <optimization>off
+        : <optimization>on
+        : $(test-space)
+        ;
+
+    assert.result <toolset>gcc <rtti>off
+        : refine <toolset>gcc : <rtti>off : $(test-space)
+        ;
+
+    assert.result <toolset>gcc <rtti>off <rtti>off:<define>FOO
+        : refine <toolset>gcc : <rtti>off <rtti>off:<define>FOO 
+        : $(test-space)
+        ;
+    
+    assert.result <toolset>gcc:<define>foo <toolset>gcc:<define>bar 
+        : refine <toolset>gcc:<define>foo : <toolset>gcc:<define>bar 
+        : $(test-space)
+        ;
+
+    assert.result <define>MY_RELEASE
+        : evaluate-conditionals-in-context 
+          <variant>release,<rtti>off:<define>MY_RELEASE
+          : <toolset>gcc <variant>release <rtti>off
+                 
+        ;
+
+    assert.result debug
+      : as-path <optimization>off <variant>debug
+      : $(test-space)
+      ;
+
+    assert.result gcc/debug/rtti-off
+      : as-path <toolset>gcc <optimization>off <rtti>off <variant>debug
+      : $(test-space)
+      ;
+        
+    try ;
+        validate <feature>value : $(test-space) ;
+    catch "Invalid property '<feature>value': unknown feature 'feature'." ;
+
+    try ;
+        validate <rtti>default : $(test-space) ;
+    catch \"default\" is not a known value of feature <rtti> ;
+    
+    validate <define>WHATEVER : $(test-space) ;
+
+    try ;
+        validate <rtti> : $(test-space) ;
+    catch "Invalid property '<rtti>': No value specified for feature 'rtti'." ;
+
+    try ;
+        validate value : $(test-space) ;
+    catch "value" is not a value of an implicit feature ;
+           
+
+    assert.result <rtti>on 
+        : remove free implicit : <toolset>gcc <define>foo <rtti>on : $(test-space) ;
+
+    assert.result <include>a 
+        : select include : <include>a <toolset>gcc ;
+
+    assert.result <include>a 
+        : select include bar : <include>a <toolset>gcc ;
+
+    assert.result <include>a <toolset>gcc
+        : select include <bar> <toolset> : <include>a <toolset>gcc ;
+    
+    assert.result <toolset>kylix <include>a 
+        : change <toolset>gcc <include>a : <toolset> kylix ;
+
+    pm = [ new property-map ] ;
+    $(pm).insert <toolset>gcc : o ;
+    $(pm).insert <toolset>gcc <os>NT : obj ;
+    $(pm).insert <toolset>gcc <os>CYGWIN : obj ;
+
+    assert.equal o
+      : [ $(pm).find <toolset>gcc ] ;
+
+    assert.equal obj
+      : [ $(pm).find <toolset>gcc <os>NT ] ;
+
+    try ;
+        $(pm).find <toolset>gcc <os>NT <os>CYGWIN ;
+    catch "Ambiguous key" ;
+
+    # Test ordinary properties 
+    assert.result 
+      : split-conditional <toolset>gcc 
+      ;
+    
+    # Test properties with ":"
+    assert.result
+      : split-conditional <define>FOO=A::B
+      ;
+    
+    # Test conditional feature
+    assert.result <toolset>gcc,<toolset-gcc:version>3.0 <define>FOO
+      : split-conditional <toolset>gcc,<toolset-gcc:version>3.0:<define>FOO
+      ;
+    
+    feature.finish-test property-test-temp ;
+}
+

Added: boost-jam/boost-build/branches/upstream/current/build/readme.txt
===================================================================
--- boost-jam/boost-build/branches/upstream/current/build/readme.txt	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/build/readme.txt	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,8 @@
+Development code for new build system. To run unit tests for jam code, execute:
+
+  bjam --debug --build-system=test
+
+Comprehensive tests require Python. See ../test/readme.txt
+
+
+

Added: boost-jam/boost-build/branches/upstream/current/build/scanner.jam
===================================================================
--- boost-jam/boost-build/branches/upstream/current/build/scanner.jam	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/build/scanner.jam	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,147 @@
+#  Copyright (C) Vladimir Prus 2002. Permission to copy, use, modify, sell and
+#  distribute this software is granted provided this copyright notice appears in
+#  all copies. This software is provided "as is" without express or implied
+#  warranty, and with no claim as to its suitability for any purpose.
+
+#  Implements scanners: objects that compute implicit dependencies for
+#  files, such as includes in C++.
+#
+#  Scanner has a regular expression used to find dependencies, some
+#  data needed to interpret those dependencies (for example, include
+#  paths), and a code which actually established needed relationship
+#  between actual jam targets.
+#
+#  Scanner objects are created by actions, when they try to actualize
+#  virtual targets, passed to 'virtual-target.actualize' method and are
+#  then associated with actual targets. It is possible to use
+#  several scanners for a virtual-target. For example, a single source
+#  might be used by to compile actions, with different include paths.
+#  In this case, two different actual targets will be created, each 
+#  having scanner of its own.
+#
+#  Typically, scanners are created from target type and action's 
+#  properties, using the rule 'get' in this module. Directly creating
+#  scanners is not recommended, because it might create many equvivalent
+#  but different instances, and lead in unneeded duplication of
+#  actual targets. However, actions can also create scanners in a special
+#  way, instead of relying on just target type.
+
+import "class" : new ;
+import property virtual-target ;
+
+#  Base scanner class. 
+class scanner 
+{
+    rule __init__ ( )
+    {
+    }
+    
+    # Returns a pattern to use for scanning
+    rule pattern ( )
+    {
+        error "method must be overriden" ;
+    }
+
+    # Establish necessary relationship between targets,
+    # given actual target beeing scanned, and a list of
+    # pattern matches in that file.
+    rule process ( target : matches * )
+    {
+        error "method must be overriden" ;
+    }        
+}
+
+# Registers a new generator class, specifying a set of 
+# properties relevant to this scanner.  Ctor for that class
+# should have one parameter: list of properties.
+rule register ( scanner-class : relevant-properties * )
+{
+    .registered += $(scanner-class) ;
+    .relevant-properties.$(scanner-class) = $(relevant-properties) ;
+}
+
+# Common scanner class, which can be used when there's only one
+# kind of includes (unlike C, where "" and <> includes have different
+# search paths).
+class common-scanner : scanner 
+{
+    import scanner ;
+    rule __init__ ( includes * )
+    {
+        scanner.__init__ ;
+        self.includes = $(includes) ;
+    }
+            
+    rule process ( target : matches * : binding )
+    {
+        local target_path = [ NORMALIZE_PATH $(binding:D) ] ;
+
+        NOCARE $(matches) ;
+        INCLUDES $(target) : $(matches) ;
+        SEARCH on $(matches) = $(target_path) $(self.includes:G=) ;
+    
+        scanner.propagate $(__name__) : $(matches) : $(target) ;     
+    }
+}
+
+
+# Returns an instance of previously registered scanner,
+# with the specified properties.
+rule get ( scanner-class : properties * ) 
+{
+    if ! $(scanner-class) in $(.registered)
+    {
+        error "attempt to get unregisted scanner" ;
+    }
+    local r = [ property.select $(.relevant-properties.$(scanner-class)) :
+                $(properties) ] ;
+    if ! $(r)
+    {
+        r = "" ;
+    }    
+    if ! $(scanner.$(scanner-class).$(r:J=-))
+    {
+        scanner.$(scanner-class).$(r:J=-) = [ new $(scanner-class) $(r) ] ;
+    }
+    return $(scanner.$(scanner-class).$(r:J=-)) ;    
+}
+
+
+# Installs the specified scanner on actual target 'target'. 
+rule install ( scanner : target 
+    vtarget # virtual target from which 'target' was actualized
+)
+{
+    HDRSCAN on $(target) = [ $(scanner).pattern ] ;
+    SCANNER on $(target) = $(scanner) ;
+    HDRRULE on $(target) = scanner.hdrrule ;
+    
+    # scanner reflects difference in properties affecting    
+    # binding of 'target', which will be known when processing
+    # includes for it, will give information on how to
+    # interpret quoted includes.
+    HDRGRIST on $(target) = $(scanner) ;
+}
+
+# Propagate scanner setting from 'including-target' to 'targets'.
+rule propagate ( scanner : targets * : including-target )
+{
+    HDRSCAN on $(targets) = [ on $(including-target) return $(HDRSCAN) ] ;
+    SCANNER on $(targets) = $(scanner) ;
+    HDRRULE on $(targets) = scanner.hdrrule ;
+    HDRGRIST on $(targets) = [ on $(including-target) return $(HDRGRIST) ] ;
+}
+
+
+rule hdrrule ( target : matches * : binding )
+{
+    local scanner = [ on $(target) return $(SCANNER) ] ;
+    $(scanner).process $(target) : $(matches) : $(binding) ;
+}
+# hdrrule must be available at global scope so that it can be invoked
+# by header scanning
+IMPORT scanner : hdrrule : : scanner.hdrrule ;
+
+
+
+

Added: boost-jam/boost-build/branches/upstream/current/build/targets.jam
===================================================================
--- boost-jam/boost-build/branches/upstream/current/build/targets.jam	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/build/targets.jam	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,1280 @@
+#  Copyright (C) Vladimir Prus 2002. Permission to copy, use, modify, sell and
+#  distribute this software is granted provided this copyright notice appears in
+#  all copies. This software is provided "as is" without express or implied
+#  warranty, and with no claim as to its suitability for any purpose.
+
+
+#   Supports 'abstract' targets, which are targets explicitly defined in Jamfile.
+#
+#   Abstract targets are represented by classes derived from 'abstract-target' class. 
+#   The first abstract target is 'project-target', which is created for each
+#   Jamfile, and can be obtained by the 'target' rule in the Jamfile's module.
+#   (see project.jam). 
+#
+#   Project targets keep a list of 'main-target' instances.
+#   A main target is what the user explicitly defines in a Jamfile. It is
+#   possible to have several definitions for a main target, for example to have
+#   different lists of sources for different platforms. So, main targets
+#   keep a list of alternatives.
+#
+#   Each alternative is an instance of 'abstract-target'. When a main target
+#   subvariant is defined by some rule, that rule will decide what class to
+#   use, create an instance of that class and add it to the list of alternatives
+#   for the main target.
+#
+#   Rules supplied by the build system will use only targets derived
+#   from 'basic-target' class, which will provide some default behaviour.
+#   There will be two classes derived from it, 'make-target', created by the
+#   'make' rule, and 'typed-target', created by rules such as 'exe' and 'dll'.
+
+#
+#                         +------------------------+
+#                         |abstract-target         |
+#                         +========================+
+#                         |name                    |
+#                         |project                 |                                   
+#                         |                        |                                   
+#                         |generate(properties) = 0|                                   
+#                         +-----------+------------+                                   
+#                                     |                                                
+#                                     ^                                                
+#                                    / \                                               
+#                                   +-+-+                                              
+#                                     |                                                
+#                                     |                                                
+#            +------------------------+------+------------------------------+          
+#            |                               |                              |          
+#            |                               |                              |          
+# +----------+-----------+            +------+------+                +------+-------+  
+# | project-target       |            | main-target |                | basic-target |  
+# +======================+ 1        * +=============+  alternatives  +==============+  
+# | generate(properties) |o-----------+ generate    |<>------------->| generate     |  
+# | main-target          |            +-------------+                | construct = 0|
+# +----------------------+                                           +--------------+  
+#                                                                           |          
+#                                                                           ^          
+#                                                                          / \         
+#                                                                         +-+-+        
+#                                                                           |          
+#                                                                           |          
+#                 ...--+----------------+------------------+----------------+---+      
+#                      |                |                  |                    |      
+#                      |                |                  |                    |      
+#               ... ---+-----+   +------+-------+   +------+------+    +--------+-----+
+#                            |   | typed-target |   | make-target |    | stage-target |
+#                            .   +==============+   +=============+    +==============+
+#                            .   | construct    |   | construct   |    | construct    |
+#                                +--------------+   +-------------+    +--------------+
+
+import "class" : new ;
+import sequence ;
+import regex ;
+import property ;
+import errors ;
+import common ;
+import property-set ;
+import project ;
+import feature ;
+import virtual-target ;
+import path ;
+import set ;
+import assert ;
+
+# Base class for all abstract targets.
+class abstract-target 
+{
+    import project assert "class" errors ;    
+        
+    rule __init__ ( name      # name of the target in Jamfile
+        : project-target      # the project target to which this one belongs
+    )
+    {        
+        assert.true class.is-a $(project-target) : project-target ;
+        # Note: it might seem that we don't need either name or project at all.
+        # However, there are places where we really need it. One example is error
+        # messages which should name problematic targets. Another is setting correct
+        # paths for sources and generated files.
+        
+        self.name = $(name) ;
+        self.project = $(project-target) ;
+        self.location = [ errors.nearest-user-location ] ;
+    }    
+    
+    # Returns the name of this target.
+    rule name ( )
+    {
+        return $(self.name) ;
+    }
+    
+    # Returns the project for this target.
+    rule project ( )
+    {
+        return $(self.project) ;
+    }
+    
+    # Return the location where the target was declared
+    rule location ( )
+    {
+        return $(self.location) ;
+    }
+            
+    # Returns a user-readable name for this target.
+    rule full-name ( )
+    {
+        local location = [ $(self.project).get location ] ;
+        return $(location)/$(self.name) ;
+    }
+        
+    # Takes properties in split form ("<feature1>foo <feature2>bar").
+    # Generates virtual targets for this abstract target, using the specified properties,
+    # unless a different value of some feature is required by the target. The properties
+    # on returned virtual targets should be link-compatible with the requested ones.
+    #
+    # On success, returns: 
+    # - a property-set with the usage requirements to be applied to dependents
+    # - a list of produced virtual targets, which may be empty.
+    #
+    # If 'properties' are empty, performs default build of this target, in a way specific
+    # to derived class.
+    rule generate ( property-set )
+    {
+        errors.error "method should be defined in derived classes" ;
+    }
+    
+    rule rename ( new-name )
+    {
+        self.name = $(new-name) ;
+    }        
+}
+
+#  Project target class (derived from 'abstract-target')
+#
+#  This class these responsibilities:
+#  - maintaining a list of main target in this project and
+#    building it
+#
+#  Main targets are constructed in two stages:
+#  - When Jamfile is read, a number of calls to 'add-alternative' is made.
+#    At that time, alternatives can also be renamed to account for inline
+#    targets.
+#  - The first time 'main-target' or 'has-main-target' rule is called,
+#    all alternatives are enumerated an main targets are created.
+class project-target : abstract-target 
+{
+    import project targets ;
+    import path ;
+    import print ;
+    import property-set ;
+    import set : difference : set.difference ;
+    import sequence ;
+    import "class" : new ;
+    import errors ;
+        
+    rule __init__ ( name : project-module : requirements * : default-build * )
+    {    
+        abstract-target.__init__ $(name) : $(__name__) ;
+        
+        self.project-module = $(project-module) ;
+        self.requirements = $(requirements) ;
+        self.default-build = $(default-build) ;
+    }
+
+    # This is needed only by the 'make' rule. Need to find the
+    # way to make 'make' work without this method.
+    rule project-module ( )
+    {
+        return $(self.project-module) ;
+    }
+        
+    rule get ( attribute )    
+    {
+        return [ project.attribute $(self.project-module) $(attribute) ] ;
+    }
+    
+    
+    # Generates all possible targets contained in this project.
+    rule generate ( property-set * )
+    {
+        local usage-requirements = [ property-set.empty ] ;
+        local targets ;
+        
+        for local t in [ targets-to-build ] 
+        {
+            local g = [ $(t).generate $(property-set) ] ;
+            usage-requirements = [ $(usage-requirements).add $(g[1]) ] ;
+            targets += $(g[2-]) ;
+        }
+        return $(usage-requirements) [ sequence.unique $(targets) ] ;        
+    }
+        
+    # Computes and returns a list of abstract-target instances which
+    # must be built when this project is built.
+    rule targets-to-build ( )
+    {
+        local result ;
+        
+        if ! $(self.built-main-targets)
+        {
+            build-main-targets ;
+        }
+        
+        # Collect all main targets here, except for "explicit" ones.
+        for local t in $(self.main-targets)
+        {
+            if ! [ $(t).name ] in $(self.explicit-targets)
+            {                    
+                result += $(t) ;
+            }
+        }
+
+        # Collect all projects referenced via "projects-to-build" attribute.
+        local self-location = [ get location ] ;
+        for local pn in [ get projects-to-build ]
+        {
+            local p = [ project.module-name [ path.join $(self-location) $(pn) ] ] ;
+            result += [ project.target $(p) ] ;
+        }
+                        
+        return $(result) ;
+    }
+    
+    # Add 'target' to the list of targets in this project that should be build
+    # only by explicit request
+    rule mark-target-as-explicit ( target-name )
+    {
+        # Record the name of the target, not instance, since this
+        # rule is called before main target instaces are created.
+        self.explicit-targets += $(target-name) ;
+    }
+    
+    # Add new target alternative
+    rule add-alternative ( target-instance )
+    {
+        if $(self.built-main-targets)
+        {
+            errors.error "add-alternative called when main targets are already created." 
+              : "in project" [ full-name ] ;
+        }        
+        self.alternatives += $(target-instance) ;
+    }
+    
+            
+    # Returns a 'main-target' class instance corresponding to the 'name'.
+    rule main-target ( name )
+    {
+        if ! $(self.built-main-targets)
+        {
+            build-main-targets ;
+        }
+                        
+        return $(self.main-target.$(name)) ;
+    }
+
+    # Tells if a main target with the specified name exists.
+    rule has-main-target ( name )
+    {
+        if ! $(self.built-main-targets)
+        {
+            build-main-targets ;
+        }
+        
+        if $(self.main-target.$(name)) 
+        {
+            return true ;
+        } 
+    }
+    
+    rule build-main-targets ( )
+    {
+        self.built-main-targets = true ;
+        for local a in $(self.alternatives)
+        {
+            local name = [ $(a).name ] ;
+            local target = $(self.main-target.$(name)) ;
+            if ! $(target)
+            {
+                local t = [ new main-target $(name) : $(self.project) ] ;
+                self.main-target.$(name) = $(t) ;
+                self.main-targets += $(t) ;
+                target = $(self.main-target.$(name)) ;
+            }
+            
+            $(target).add-alternative $(a) ;            
+        }    
+    }                            
+}
+
+
+# Helper rules to detect cycles in main target references
+local rule start-building ( main-target-instance )
+{
+    if $(main-target-instance) in $(.targets-being-built)
+    {
+        local names ;
+        for local t in $(.targets-being-built) $(main-target-instance)
+        {
+            names += [ $(t).full-name ] ;
+        }
+        
+        errors.error "Recursion in main target references" 
+          : "the following target are being built currently:"
+          : $(names) ;
+    }
+    .targets-being-built += $(main-target-instance) ;    
+}
+
+local rule end-building ( main-target-instance )
+{
+    .targets-being-built = $(.targets-being-built[1--2]) ;
+}
+
+
+# A named top-level target in Jamfile
+class main-target : abstract-target
+{
+    import errors : error ;
+    import assert ;
+    import sequence ;    
+    import print ;
+    import build-request feature property-set ;
+    import targets : start-building end-building ;
+    import "class" : is-a ;
+        
+    rule __init__ ( name : project )
+    {
+        abstract-target.__init__ $(name) : $(project) ;
+    }
+    
+        
+    # Add a new alternative for this target
+    rule add-alternative ( target )
+    {
+        local d = [ $(target).default-build ] ;
+        if $(self.alternatives) && ( $(self.default-build) != $(d) )
+        {
+            errors.error "default build must be identical in all alternatives"
+              : "main target is" [ full-name ]
+              : "with" [ $(d).raw ]
+              : "differing from previous default build" [ $(self.default-build).raw ] ;
+        }
+        else
+        {
+            self.default-build = $(d) ;
+        }        
+        self.alternatives += $(target) ;
+    }
+
+    # Returns the best viable alternative for this property-set
+    # See the documentation for selection rules.
+    local rule select-alternatives ( property-set )
+    {
+        # When selecting alternatives we have to consider defaults,
+        # for example:
+        #    lib l : l.cpp : <variant>debug ;
+        #    lib l : l_opt.cpp : <variant>release ;
+        # won't work unless we add default value <variant>debug.        
+        property-set = [ $(p).add-defaults ] ;        
+        
+        # The algorithm: we keep the current best viable alternative.
+        # When we've got new best viable alternative, we compare it
+        # with the current one. 
+        
+        local best ;
+        local best-properties ;
+                        
+        if $(self.alternatives[2-])
+        {
+            local bad ;
+            local worklist = $(self.alternatives) ;    
+            while $(worklist) && ! $(bad)
+            {
+                local v = $(worklist[1]) ; 
+                local properties = [ $(v).match $(property-set) ] ;
+                           
+                if $(properties) != no-match
+                {                                    
+                    if ! $(best)
+                    {
+                        best = $(v) ;
+                        best-properties = $(properties) ;
+                    }
+                    else
+                    {                                                   
+                        if $(properties) = $(best-properties)
+                        {
+                            bad = true ;
+                        }
+                        else if $(properties) in $(best-properties) 
+                        {
+                            # Do nothing, this alternative is worse
+                        }
+                        else if $(best-properties) in $(properties)
+                        {
+                            best = $(v) ;
+                            best-properties = $(properties) ;
+                        }
+                        else 
+                        {
+                            bad = true ;
+                        }                                                
+                    }
+                }
+                worklist = $(worklist[2-]) ;                
+            }
+            if ! $(bad)
+            {
+                return $(best) ;
+            }                                    
+        }
+        else
+        {
+            return $(self.alternatives) ;
+        }        
+    }
+    
+    
+    rule apply-default-build ( property-set )
+    {           
+        # 1. First, see what properties from default-build
+        # are already present in property-set. 
+        
+        local raw = [ $(property-set).raw ] ;
+        local specified-features = $(raw:G) ;
+        
+        local defaults-to-apply ;
+        for local d in [ $(self.default-build).raw ] 
+        {
+            if ! $(d:G) in $(specified-features)
+            {
+                defaults-to-apply += $(d) ; 
+            }            
+        }
+        
+        # 2. If there's any defaults to be applied, form the new
+        # build request. Pass it throw 'expand-no-defaults', since
+        # default-build might contain "release debug", which will
+        # result in two property-sets.
+        local result ;
+        if $(defaults-to-apply)
+        {
+            properties = [ 
+              build-request.expand-no-defaults 
+                
+                # We have to compress subproperties here to prevent
+                # property lists like:
+                #
+                #    <toolset>msvc <toolset-msvc:version>7.1 <threading>multi
+                #
+                # from being expanded into:
+                #
+                #    <toolset-msvc:version>7.1/<threading>multi
+                #    <toolset>msvc/<toolset-msvc:version>7.1/<threading>multi
+                #
+                # due to cross-product property combination.  That may
+                # be an indication that
+                # build-request.expand-no-defaults is the wrong rule
+                # to use here.
+                [ feature.compress-subproperties $(raw) ] 
+                  $(defaults-to-apply)
+            ] ;
+              
+            if $(properties)
+            {                
+                for local p in $(properties)
+                {
+                    result += [ property-set.create 
+                        [ feature.expand [ feature.split $(p) ] ] ] ;
+                }
+            }
+            else
+            {
+                result = [ property-set.empty ] ;
+            }            
+            
+        }
+        else
+        {
+            result = $(property-set) ;
+        }
+        return $(result) ;
+    }
+        
+    # Select an alternative for this main target, by finding all alternatives
+    # which requirements are satisfied by 'properties' and picking the one with
+    # longest requirements set.
+    # Returns the result of calling 'generate' on that alternative.
+    rule generate ( property-set )
+    {
+        start-building $(__name__) ;
+
+        # We want composite properties in build request act as if
+        # all the properties it expands too are explicitly specified.
+        property-set = [ $(property-set).expand ] ;
+        
+        local all-property-sets = [ apply-default-build $(property-set) ] ;
+        local usage-requirements = [ property-set.empty ] ;
+        local result ;
+        for local p in $(all-property-sets)
+        {
+            local r = [ generate-really $(p) ] ;
+            usage-requirements = [ $(usage-requirements).add $(r[1]) ] ;
+            result += $(r[2-]) ;
+        }
+        end-building $(__name__) ;
+        return $(usage-requirements) [ sequence.unique $(result) ] ;                
+    }
+        
+    # Generates the main target with the given property set
+    # and returns a list which first element is property-set object
+    # containing usage-requirements of generated target and with
+    # generated virtual target in other elements. It's possible
+    # that no targets are generated.
+    local rule generate-really ( property-set )
+    {            
+        local best-alternatives = [ select-alternatives $(property-set) ] ;
+        if ! $(best-alternatives)
+        {
+            errors.error
+                "failed to build" [ full-name ]
+                "with properties" [ $(property-set).raw ]
+                  "because no best-matching alternative could be found"
+                  ; 
+            return [ property-set.empty ] ;
+        }
+        else
+        {
+            local result = [ $(best-alternatives).generate $(property-set) ] ;
+                        
+            # Now return virtual targets for the only alternative
+            return $(result) ;
+        }        
+    }
+    
+    rule rename ( new-name )
+    {
+        abstract-target.rename $(new-name) ;
+        for local a in $(self.alternatives)
+        {
+            $(a).rename $(new-name) ;
+        }
+        
+    }
+    
+}
+
+# Abstract target which refers to a source file.
+# This is artificial creature; it's usefull so that sources to 
+# a target can be represented as list of abstract target instances.
+class file-reference : abstract-target 
+{
+    import virtual-target ;
+    import property-set ;
+    import path ;
+    
+    rule __init__ ( file : project )
+    {
+        abstract-target.__init__ $(file) : $(project) ;
+    }
+    
+    rule generate ( properties )
+    {
+         return [ property-set.empty ] 
+                [ virtual-target.from-file $(self.name) : $(self.project) ] ;        
+    }    
+
+    # Returns true if the referred file really exists;
+    rule exists ( )
+    {
+        local location = [ path.root $(self.name)
+          [ $(self.project).get source-location ] ] ;        
+        return [ path.exists [ path.native $(location) ] ] ;
+    }    
+    
+    # Returns the location of target. Needed by 'testing.jam'
+    rule location ( )
+    {
+        return [ path.root $(self.name)
+          [ $(self.project).get source-location ] ] ;    
+    }    
+}
+
+
+if "--quiet" in [ modules.peek : ARGV ]
+{
+    .quiet = true ;
+}
+
+
+rule find ( id : project )
+{
+    local current-location = [ $(project).get location ] ;
+    local target ;    
+    
+    local split = [ MATCH (.*)//(.*) : $(id) ] ;
+    
+    local project-part = $(split[1]) ;
+    local target-part = $(split[2]) ;
+    if ! $(split)
+    {
+        target-part = $(id) ;
+    }
+        
+    # Make a more convenient name
+    local have-project-reference = $(split) ;
+    
+    # The project used for finding main targets and for providing base directory
+    # for file paths.
+    local base-project ;
+    if $(project-part) 
+    {
+        local pm = [ project.find $(project-part) : $(current-location) ] ;
+        # If we can't find a project, it means project part is invalid.
+        # Don't assign any value to base-project, the below code will eventually
+        # return empty result.
+        if $(pm)
+        {                  
+            base-project = [ project.target $(pm) ] ;
+        }        
+    }
+    else
+    {
+        # No project part in id. Resolve references relatively to the referring
+        # project.
+        base-project = $(project) ;
+    }
+    
+    
+    # Interpret target-part as project-id
+    if ! $(have-project-reference)
+    {   
+        local project-module = [ project.find $(target-part) : $(current-location) ] ;
+        if $(project-module)
+        {
+            target = [ project.target $(project-module) ] ;
+        }        
+    }
+    
+    # Interpret target-name as name of main target
+    if ! $(target) && $(base-project)
+    {
+        if [ $(base-project).has-main-target $(target-part) ] 
+        {
+            target = [ $(base-project).main-target $(target-part) ] ;
+        }
+    }
+    
+    if ! $(target) && ! $(have-project-reference)
+    {
+        target = [ new file-reference [ path.make $(target-part) ] : $(project) ] ;        
+        if ! [ $(target).exists ]
+        {
+            # File actually does not exist.
+            # Reset 'target' so that an error is issued.
+            target = ;
+        }                
+    }
+        
+    if ! $(target)
+    {
+        ECHO "error: Unable to find file or target named" ;
+        ECHO "error:     '$(id)'" ;
+        ECHO "error: referred from project at" ;
+        ECHO "error:     '$(current-location)'" ;
+        EXIT ;
+        
+        
+        errors.error "Unable to resolve target-id $(id)" : 
+          "Reference was made from project at '$(current-location)'" ;
+    }        
+    return $(target) ;
+}
+
+# Given a target-reference, made in context of 'project',
+# returns the abstract-target instance that is referred to, as well
+# as properties explicitly specified for this reference.
+rule resolve-reference ( target-reference : project )
+{
+    # Separate target name from properties override
+    local split = [ MATCH "^([^<]*)(/(<.*))?$" : $(target-reference) ] ;
+    local id = $(split[1]) ;
+    local sproperties = ;
+    if $(split[3])
+    {
+        sproperties = [ property.make [ feature.split $(split[3]) ] ] ;
+        sproperties = [ feature.expand-composites $(sproperties) ] ;
+    }
+
+    # Find the target
+    local target = 
+      [ find $(id) :  $(project) ] ;
+    
+    # Do a sanity check
+    if $(sproperties) && [ class.is-a $(target) : file-reference ] 
+    {
+        errors.error 
+          "error: target reference '$(target-reference)' contains properties," :
+          "error: but refers to a file" ;
+    }
+    return $(target) [ property-set.create $(sproperties) ] ;
+}
+
+
+
+# Attempts to generate the target given by target reference, which
+# can refer both to a main target or to a file.
+# Returns a list consisting of
+# - usage requirements
+# - generated virtual targets, if any
+rule generate-from-reference 
+   ( target-reference            # Target reference
+    : project                    # Project where the reference is made
+    : property-set               # Properties of the main target that 
+                                 # makes the reference
+   )
+{
+    local r = [ resolve-reference $(target-reference) : $(project) ] ;
+    local target = $(r[1]) ;
+    local sproperties = $(r[2]) ;
+    
+    # Take properties which should be propagated and refine them
+    # with source-specific requirements.
+    local propagated = [ $(property-set).propagated ] ;
+    local rproperties = [ $(propagated).refine $(sproperties) ] ;
+    if $(rproperties[1]) = "@error"
+    {
+        errors.error
+          "When building" [ full-name ] " with properties " $(properties) :
+            "Invalid properties specified for " $(source) ":"
+              $(rproperties[2-]) ;
+    }
+    return [ $(target).generate $(rproperties) ] ;
+}
+
+# Given build request and requirements, return properties
+# common to dependency build request and target build
+# properties
+rule common-properties ( build-request requirements )
+{
+    # For optimization, we add free requirements directly,
+    # without using complex algorithsm.
+    # This gives the complex algorithm better chance of caching results.
+    local free = [ $(requirements).free ] ;        
+    local non-free = [ property-set.create 
+        [ $(requirements).base ]  [ $(requirements).incidental ] ] ;
+    
+    local key = .rp.$(build-request)-$(non-free) ;
+    if ! $($(key))
+    {           
+        $(key) = [ common-properties2 $(build-request) $(non-free) ] ;        
+    }        
+    result = [ $($(key)).add-raw $(free) ] ;
+}
+    
+rule common-properties2 ( build-request requirements )
+{           
+    # This guarantees that default properties are present
+    # in result, unless they are overrided by some requirement.
+    # FIXME: There is possibility that we've added <foo>bar, which is composite
+    # and expands to <foo2>bar2, but default value of <foo2> is not bar2,
+    # in which case it's not clear what to do.
+    # 
+    build-request = [ $(build-request).add-defaults ] ;
+    # Featured added by 'add-default' can be composite and expand
+    # to features without default values -- so they are not added yet.
+    # It could be clearer/faster to expand only newly added properties
+    # but that's not critical.
+    build-request = [ $(build-request).expand ] ;
+    
+    # Apply non-conditional requirements. 
+    # There's a slight bug here: it's possible that conditional
+    # requirement change a value set by non-conditional requirements. This
+    # should be error, but we don't detect it yet.
+    local raw = [ $(build-request).raw ] ;
+    raw = [ property.refine $(raw) : 
+      [ feature.expand [ $(requirements).non-conditional ] ] ] ;
+    
+    # We've collected properties that surely must be present in common
+    # properties. We now try to figure out what other properties
+    # should be added in order to satisfy rules (4)-(6) from the docs.        
+    
+    local conditionals = [ $(requirements).conditional ] ;
+    local count = $(conditionals) and-once-more ;
+    local prev ;
+    
+    local current = $(raw) ;
+    
+    local ok ;
+    while $(count) 
+    {
+        # Evaluate conditionals in context of current properties
+        local e = [ property.evaluate-conditionals-in-context $(conditionals) 
+          : $(current) ] ;
+        if $(e) = $(prev)
+        {                
+            # If we got the same result, we've found final properties.
+            count = ;      
+            ok = true ;
+        }         
+        else
+        {
+            # Oops, results of evaluation of conditionals has changes
+            # Also 'current' contains leftover from previous evaluation.
+            # Recompute 'current' using initial properties and conditional
+            # requirements.
+            prev = $(e) ;
+            current = [ property.refine $(raw) : [ feature.expand $(e) ] ] ;
+        }            
+        count = $(count[2-]) ;
+    }
+    if ! $(ok)
+    {
+        errors.error "Can't evaluate conditional properties " $(conditionals) ;
+    }
+    
+    
+    return [ property-set.create $(current) ] ;
+}
+
+# Implements the most standard way of constructing main target
+# alternative from sources. Allows sources to be either file or
+# other main target and handles generation of those dependency
+# targets.
+class basic-target : abstract-target
+{
+    import build-request ;
+    import virtual-target targets ;
+    import property-set ;
+    import set sequence errors ;
+    import "class" : new ;
+    import property feature ;
+        
+    rule __init__ ( name : project
+        : sources * : requirements * : 
+        default-build * : usage-requirements * )
+    {        
+        abstract-target.__init__ $(name) : $(project) ;
+    
+        self.sources = $(sources) ;
+        if ! $(requirements) {
+            requirements = [ property-set.empty ] ;
+        }    
+        self.requirements = $(requirements) ;
+        if ! $(default-build) 
+        {
+            default-build = [ property-set.empty ] ;
+        }    
+        self.default-build = $(default-build) ;
+        if ! $(usage-requirements)
+        {
+            usage-requirements = [ property-set.empty ] ;
+        }    
+        self.usage-requirements = $(usage-requirements) ;
+        
+        if $(sources:G)
+        {
+            errors.error "gristed element in sources for" [ full-name ] ;
+        }
+    }
+    
+    # Returns the list of abstract-targets which are used as sources.
+    # The extra properties specified for sources are not represented.
+    rule sources ( )
+    {
+        if ! $(self.source-targets) {
+            for local s in $(self.sources)
+            {
+                self.source-targets += 
+                  [ targets.resolve-reference $(s) : $(self.project) ] ;
+            }            
+        }    
+        return $(self.source-targets) ;
+    }
+    
+    rule requirements ( )
+    {
+        return $(self.requirements) ;
+    }
+                        
+    rule default-build ( )
+    {
+        return $(self.default-build) ;
+    }
+    
+    # Returns the alternative condition for this alternative, if
+    # the condition is satisfied by 'property-set'.
+    rule match ( property-set )
+    {    
+        # The condition is composed of all base non-conditional properties.
+        # It's not clear if we should expand 'self.requirements' or not.
+        # For one thing, it would be nice to be able to put
+        #    <toolset>msvc-6.0 
+        # in requirements.
+        # On the other hand, if we have <variant>release in condition it 
+        # does not make sense to require <optimization>full to be in
+        # build request just to select this variant.
+        local bcondition = [ $(self.requirements).base ] ;
+        local ccondition = [ $(self.requirements).conditional ] ;
+        local condition = [ set.difference $(bcondition) : $(ccondition) ] ;
+        if $(condition) in [ $(property-set).raw ] 
+        {
+            return $(condition) ;            
+        }
+        else
+        {
+            return no-match ;
+        }        
+    }
+
+    #
+    # Allows the user to tag the name of the target, according to properties.
+    #
+    rule tag-name ( name : property-set )
+    {
+        local properties = [ $(property-set).raw ] ;
+
+        local tagged-name = $(name) ;
+
+        if <tag> in $(properties:G)
+        {
+            local tags = [ $(property-set).get <tag> ] ;
+            for local tag in $(tags)
+            {
+                tagged-name = $(tagged-name)$(tag) ;
+            }
+        }
+
+        return $(tagged-name) ;
+    }
+    
+    # Takes a target reference, which might be either target id
+    # or a dependency property, and generates that target using
+    # 'property-set' as build request.
+    #
+    # The results are added to to variable called 'result-var'.
+    # Usage requirements are added variable called 'usage-requirements-var'.
+    rule generate-dependencies ( dependencies * : property-set 
+        : result-var usage-requirements-var )
+    {
+        for local dependency in $(dependencies)
+        {            
+            local grist = $(dependency:G) ;
+            local id = $(dependency:G=) ;
+        
+            local result = 
+              [ targets.generate-from-reference $(id) : $(self.project) 
+                : $(property-set) ] ;
+            check-for-link-compatibility $(result[2-]) : $(property-set) ;
+        
+            $(result-var) += $(result[2-]:G=$(grist)) ;
+            $(usage-requirements-var) += [ $(result[1]).raw ] ;
+        }        
+    }
+    
+    
+    # Determines final build properties, generates sources,
+    # and calls 'construct'. This method should not be
+    # overridden.
+    rule generate ( property-set )
+    {
+        if --debug-targets in [ modules.peek : ARGV ]
+        {
+            ECHO "Building $(self.name) with" [ $(property-set).raw ] ;
+        }
+                
+        if ! $(self.generated.$(property-set)) 
+        {           
+            local rproperties = [ targets.common-properties $(property-set) 
+              $(self.requirements) ] ;            
+                        
+            if $(rproperties[1]) != "@error"                    
+            {
+                local source-targets ;
+                local properties = [ $(rproperties).non-dependency ] ;
+                local usage-requirements ;
+                
+                generate-dependencies [ $(rproperties).dependency ]
+                  : $(rproperties) 
+                  : properties usage-requirements ;
+                
+                generate-dependencies $(self.sources) : $(rproperties)
+                  : source-targets usage-requirements ;
+                
+                if --debug-targets in [ modules.peek : ARGV ]
+                {
+                    ECHO "Usage requirements for $(self.name) are $(usage-requirements)" ;
+                }
+
+                rproperties = [ property-set.create $(properties) 
+                  $(usage-requirements) ] ;
+                usage-requirements = [ property-set.create $(usage-requirements) ] ;
+                
+                local extra = [ $(rproperties).get <source> ] ;                
+                source-targets += $(extra:G=) ;
+                # We might get duplicate sources, for example if
+                # we link to two library which have the same <library> in
+                # usage requirements.
+                source-targets = [ sequence.unique $(source-targets) ] ;
+                                                
+                local tagged-name = [ tag-name $(self.name) : $(rproperties) ] ;
+
+                local original-name = $(self.name) ;
+                self.name = $(tagged-name) ;
+                
+                local result = 
+                  [ construct $(source-targets) : $(rproperties) ] ;
+
+                local s = [ create-subvariant $(result) : $(property-set) : $(source-targets)
+                  : $(rproperties) : $(usage-requirements) ] ;
+
+                local ur = [ compute-usage-requirements $(s) ] ;
+                $(s).set-usage-requirements $(ur) ;
+                self.generated.$(property-set) = $(ur) $(result) ;
+
+                self.name = $(original-name) ;
+            } 
+            else
+            {
+                self.generated.$(property-set) = $(rproperties) ;
+            }       
+        }                
+        return $(self.generated.$(property-set)) ;
+    }
+
+    # Given the set of generated targets, and refined build 
+    # properties, determines and sets appripriate usage requirements
+    # on those targets.
+    rule compute-usage-requirements ( subvariant )
+    {
+        local rproperties = [ $(subvariant).build-properties ] ;
+        xusage-requirements = [ $(self.usage-requirements).evaluate-conditionals 
+          $(rproperties) ] ;                
+        
+        # We generate all dependency properties and add them,
+        # as well as their usage requirements, to result.
+        local extra ;
+        generate-dependencies [ $(xusage-requirements).dependency ] :
+            $(rproperties) : extra extra ;
+                
+        local result = [ property-set.create
+            [ $(xusage-requirements).non-dependency ] $(extra) ] ;
+        
+        return $(result) ;
+    }
+    
+    # Creates a new subvariant-dg instances for 'targets'
+    local rule create-subvariant ( targets * : build-request : sources * :
+        rproperties 
+        : usage-requirements )
+    {
+        for local e in $(targets)                    
+        {
+            $(e).root true ;
+        }                    
+        
+        # Process all vtargets that will be created if this main target
+        # is created.
+        local all-targets = 
+          [ sequence.transform virtual-target.traverse : $(targets) ] ; 
+        local s = [ new subvariant $(__name__) : $(build-request) : $(sources)
+          : $(rproperties) : $(usage-requirements) : $(all-targets) ] ;
+        for local v in $(all-targets)          
+        {
+            if ! [ $(v).creating-subvariant ]
+            {                
+                $(v).creating-subvariant $(s) ;            
+            }            
+        }                        
+        return $(s) ;
+    }
+               
+    # Checks if 'targets' are link-compatible with 'build-request' and
+    # issues a warning if that's not the case.
+    local rule check-for-link-compatibility ( targets * : build-request )
+    {
+        local checked ;
+        for local t in $(targets)
+        {
+            local a = [ $(t).action ] ;
+            if $(a)
+            {
+                local p = [ $(a).properties ] ;
+                if ! $(p) in $(cheched)
+                {
+                    if [ $(p).link-incompatible-with $(build-request) ]
+                    {
+                        local s = [ $(t).creating-subvariant ] ;
+                        local other-mt = [ $(s).main-target ] ;
+                        ECHO "warning: targets produced from" [ $(other-mt).name ] 
+                            "are link incompatible" ;
+                        ECHO "warning: with main target" [ name ] ;
+                    }                    
+                }                
+                checked += $(p) ;
+            }            
+        }
+        
+    }
+    
+    
+        
+    # Constructs the virtual targets for this abstract targets and
+    # the dependecy graph. Returns the list of virtual targets.
+    # Should be overrided in derived classes.
+    rule construct ( source-targets * : properties * )
+    {
+        errors.error "method should be defined in derived classes" ;
+    }
+}
+
+class typed-target : basic-target
+{
+    import generators ;    
+    
+    rule __init__ ( name : project : type 
+    : sources * : requirements * : default-build * : usage-requirements * )
+    {
+        basic-target.__init__ $(name) : $(project) 
+          : $(sources) : $(requirements) : $(default-build) : $(usage-requirements) ;
+        
+        self.type = $(type) ;
+    }
+    
+    rule type ( )
+    {
+        return $(self.type) ;
+    }
+            
+    rule construct ( source-targets * : property-set )
+    {
+        local r = [ generators.construct $(self.project) $(self.name) : $(self.type) 
+          : [ property-set.create [ $(property-set).raw ] # [ feature.expand
+              <main-target-type>$(self.type) ]
+          # ]
+            : $(source-targets) ] ;
+        if ! $(r)
+        {
+            errors.error "unable to construct" [ full-name ] ;
+        }
+        
+        return $(r) ;
+    }            
+}
+
+# Return the list of sources to use, if main target rule is invoked
+# with 'sources'. If there are any objects in 'sources', they are treated
+# as main target instances, and WRITEME.
+rule main-target-sources ( sources * : main-target-name )
+{
+    local result ;
+    for local t in $(sources)
+    {
+        if [ class.is-instance $(t) ]
+        {
+            local name = [ $(t).name ] ;
+            # NOTE: on windows, this won't work if 'main-target-name'
+            # if single letter. But other alternatives are even worse.
+            local new-name = $(main-target-name)..$(name) ;
+            $(t).rename $(new-name) ;
+            #local p = [ $(t).project ] ;            
+            #local pt = [ project.target $(p) ] ;
+            #$(pt).rename-main-target $(name) : $(new-name) ;
+            result += $(new-name) ;
+        }
+        else
+        {
+            result += $(t) ;
+        }                
+    }    
+    return $(result) ;
+}
+
+
+# Returns the requirement to use when declaring a main target,
+# which are obtained by
+# - translating all specified property paths, and
+# - refining project requirements with the one specified for the target
+rule main-target-requirements ( 
+  specification * # Properties explicitly specified for a main target
+  : project       # Project where the main target is to be declared
+      )
+{
+    local loc = [ $(project).get location ] ;
+    local requirements = [ property.translate-paths $(specification) : $(loc) ] ; 
+    local requirements = 
+      [ property.expand-subfeatures-in-conditions $(requirements) ] ;
+    local requirements = [ property-set.create $(requirements) ] ;
+    local project-requirements = [ $(project).get requirements ] ;
+    requirements = [ $(project-requirements).refine $(requirements) ] ;    
+    if $(requirements[1]) = "@error" 
+    {
+        errors.error "Conflicting requirements for target:" $(requirements) ;
+    }
+    return $(requirements) ;
+}
+
+# Returns the use requirement to use when declaraing a main target,
+# which are obtained by
+# - translating all specified property paths, and
+# - adding project's usage requirements
+rule main-target-usage-requirements (
+  specification * # Use-properties explicitly specified for a main target
+  : project       # Project where the main target is to be declared
+     )
+{
+    local loc = [ $(project).get location ] ;         
+    local project-usage-requirements = [ $(project).get usage-requirements ] ;
+        
+    local usage-requirements = [ property-set.create 
+        [ property.translate-paths $(specification) : $(loc) ] ] ;
+    
+    return [ $(project-usage-requirements).add $(usage-requirements) ] ;
+}
+
+# Return the default build value to use when declaring a main target,
+# which is obtained by using specified value if not empty and parent's
+# default build attribute otherwise.
+rule main-target-default-build (
+  specification * # Default build explicitly specified for a main target
+  : project       # Project where the main target is to be declared
+     )
+{
+    local result ;
+    if $(specification)
+    {
+        result = $(specification) ;
+    }
+    else
+    {
+        result = [ $(project).get default-build ] ;
+    }    
+    return [ property-set.create-with-validation $(result) ] ;
+}         
+
+# Registers the specified target as a main target alternatives.
+# Returns 'target'.
+rule main-target-alternative ( target ) 
+{               
+    local ptarget = [ $(target).project ] ;
+    
+    $(ptarget).add-alternative $(target) ;
+    return $(target) ;
+}
+
+# Creates a typed-target with the specified properties.
+# The 'name', 'sources', 'requirements', 'default-build' and
+# 'usage-requirements' are assumed to be in the form specified
+# by the user in Jamfile corresponding to 'project'.
+rule create-typed-target ( type : project : 
+    name : sources * : requirements * : default-build * 
+    : usage-requirements * )
+{
+    return [
+      targets.main-target-alternative
+      [ new typed-target $(name) : $(project) : $(type)
+        : [ targets.main-target-sources $(sources) : $(name) ] 
+        : [ targets.main-target-requirements $(requirements) : $(project) ] 
+        : [ targets.main-target-default-build $(default-build) : $(project) ]
+        : [ targets.main-target-usage-requirements $(usage-requirements) : $(project) ]
+      ] ] ;
+
+}

Added: boost-jam/boost-build/branches/upstream/current/build/toolset.jam
===================================================================
--- boost-jam/boost-build/branches/upstream/current/build/toolset.jam	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/build/toolset.jam	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,349 @@
+#  Copyright (C) Vladimir Prus 2002. Permission to copy, use, modify, sell and
+#  distribute this software is granted provided this copyright notice appears in
+#  all copies. This software is provided "as is" without express or implied
+#  warranty, and with no claim as to its suitability for any purpose.
+
+#  Support for toolset definition.
+
+import feature ;
+import numbers ;
+import errors : error ;
+import property ;
+import path ;
+import generators ;
+import set : difference ;
+import regex ;
+import sequence ;
+
+.flag-no = 1 ;
+
+# Initializes an additional toolset-like module.
+# First load 'toolset-module' and then calls its 'init'
+# rule with trailing arguments
+rule using ( toolset-module : * )
+{
+    import $(toolset-module) ;
+    if ! $(.$(toolset-module)-init-callled)
+    {        
+        $(toolset-module)-init-callled = true ;
+        $(toolset-module).init $(2) : $(3) : $(4) : $(5) : $(6) : $(7) : $(8) : $(9) ;
+    }    
+}
+
+# Expands subfeatures in each property sets.
+# e.g
+# <toolset>gcc-3.2
+# will be converted to
+# <toolset>gcc/<toolset-version>3.2
+local rule normalize-condition ( property-sets * )
+{
+    local result ;
+    for local p in $(property-sets)
+    {
+        local split = [ feature.split $(p) ] ;
+        local expanded = [ feature.expand-subfeatures [ feature.split $(p) ] ] ;
+        result += $(expanded:J=/) ;
+    }
+    return $(result) ;
+}
+
+
+# Specifies the flags (variables) that must be set on targets under certain
+# conditions, described by arguments.
+rule flags ( rule-or-module   # If contains dot, should be a rule name.
+                              # The flags will be applied when that rule is
+                              # used to set up build actions.
+                              #
+                              # If does not contain dot, should be a module name.
+                              # The flags will be applied for all rules in that
+                              # module.
+                              # If module for rule is different from the calling
+                              # module, an error is issued.
+    
+             variable-name    # Variable that should be set on target
+             condition * :    # A condition when this flag should be applied.
+                              # Should be set of property sets. If one of
+                              # those property sets is contained in build
+                              # properties, the flag will be used.
+                              # Implied values are not allowed:
+                              # "<toolset>gcc" should be used, not just
+                              # "gcc". Subfeatures, like in "<toolset>gcc-3.2"
+                              # are allowed. If left empty, the flag will
+                              # always used.
+
+
+             values * :       # The value to add to variable. If <feature>
+                              # is specified, then the value of 'feature' 
+                              # will be added.
+             unchecked ?      # If value 'unchecked' is passed, will not test
+                              # that flags are set for the calling module.
+          )
+{
+    local module_ = [ MATCH "([^.]*).*" : $(rule-or-module) ] ;
+    local caller = [ CALLER_MODULE ] ;
+    if $(unchecked) != unchecked && $(module_) != $(caller)
+    {
+        errors.error "Module $(caller) attempted to set flags for module $(module_)" ;
+    }
+    
+    if $(condition) && ! $(condition:G=)
+    {
+        # We have condition in the form '<feature>', that is, without
+        # value. That's a previous syntax:
+        #
+        #   flags gcc.link RPATH <dll-path> ;
+        # for compatibility, convert it to
+        #   flags gcc.link RPATH : <dll-path> ;                
+        values = $(condition) ;
+        condition = ;
+    }
+    
+    if $(condition)
+    {
+        property.validate-property-sets $(condition) ;
+        condition = [ normalize-condition $(condition) ] ;
+    }
+    
+    add-flag $(rule-or-module) : $(variable-name)
+      : $(condition) : $(values) ;
+}
+
+# Adds new flag setting with the specified values
+# Does no checking
+local rule add-flag ( rule-or-module :
+    variable-name : condition * : values * )
+{
+    .$(rule-or-module).flags += $(.flag-no) ;
+
+    # Store all flags for a module
+    local module_ = [ MATCH "([^.]*).*" : $(rule-or-module) ] ;    
+    .module-flags.$(module_) += $(.flag-no) ;
+    # Store flag-no -> rule-or-module mapping
+    .rule-or-module.$(.flag-no) = $(rule-or-module) ;
+
+    .$(rule-or-module).variable.$(.flag-no) += $(variable-name) ;
+    .$(rule-or-module).values.$(.flag-no) += $(values) ;
+    .$(rule-or-module).condition.$(.flag-no) += $(condition) ;            
+                   
+    .flag-no = [ numbers.increment $(.flag-no) ] ;
+}
+    
+
+# Returns the first element of 'property-sets' which is a subset of
+# 'properties', or an empty list if no such element exists.
+local rule find-property-subset ( property-sets * : properties * )
+{
+    local result ;
+    for local s in $(property-sets)
+    {
+        if ! $(result)
+        {
+            if [ feature.split $(s) ] in $(properties)
+            {
+                result = $(s) ;
+            }
+        }
+    }
+    return $(result) ;
+}
+
+rule handle-flag-value ( value * : properties * )
+{
+    local result ;
+    if $(value:G)
+    {
+        local matches = [ property.select $(value) : $(properties) ] ;
+        for local p in $(matches)
+        {
+            local att = [ feature.attributes $(p:G) ] ;
+            if dependency in $(att)
+            {
+                # the value of a dependency feature is a target
+                # and must be actualized
+                result += [ $(p:G=).actualize ] ;
+            }                
+            else if path in $(att) || free in $(att)
+            {
+                local values ;
+                # Treat features with && in the value
+                # specially -- each &&-separated element is considered
+                # separate value. This is needed to handle searched
+                # libraries, which must be in specific order.                    
+                if ! [ MATCH (&&) : $(p:G=) ]
+                {
+                    values = $(p:G=) ;
+                }
+                else                      
+                {
+                    values = [ regex.split $(p:G=) "&&" ] ;
+                }
+                if path in $(att)
+                {                                            
+                        result += [ sequence.transform path.native : $(values) ] ;
+                }
+                else
+                {
+                    result += $(values) ;
+                }                    
+            }    
+            else 
+            {
+                result += $(p:G=) ;
+            }
+        }        
+    }
+    else
+    {
+        result += $(values) ;
+    }      
+    return $(result) ;
+}
+
+
+rule set-target-variables ( rule-or-module targets + : properties * )
+{ 
+    for local f in $(.$(rule-or-module).flags) 
+    {
+        local variable = $(.$(rule-or-module).variable.$(f)) ;
+        local condition = $(.$(rule-or-module).condition.$(f)) ;
+        local values = $(.$(rule-or-module).values.$(f)) ;
+        local result ;
+        
+        if ! $(condition) ||
+          [ find-property-subset $(condition) : $(properties) ]
+        {
+            result += [ handle-flag-value $(values) : $(properties) ] ;
+        }
+
+        # Without this test, the assignment below would create a
+        # target variable even if $(result) is empty.  That is
+        # undesirable because the empty target variable would mask
+        # module globals intended to be used as defaults.
+        if $(result)-is-nonempty
+        {
+            $(variable) on $(targets) += $(result) ;
+        }
+    }
+    
+    # strip away last dot separated part and recurse.
+    local next = [ MATCH ^(.+)\\.([^\\.])* : $(rule-or-module) ] ;
+    if $(next)
+    {
+        set-target-variables $(next) $(targets) : $(properties) ;        
+    }    
+}
+
+.toolsets += $(toolset) ;
+
+# Registers a new toolset
+rule register ( toolset )
+{
+    feature.extend toolset : $(toolset) ;
+    .toolsets += $(toolset) ;
+}
+
+# Make toolset 'toolset', defined in a module of the same name,
+# inherit from 'base'
+# 1. The 'init' rule from 'base' is imported into 'toolset' with full
+#    name. Another 'init' is called, which forwards to the base one.
+# 2. All generators from 'base' are cloned. The ids are adjusted and 
+#    <toolset> property in requires is adjusted too
+# 3. All flags are inherited
+# 4. All rules are imported.
+rule inherit ( toolset : base )
+{
+    import $(base) ;
+    
+    inherit-generators $(toolset) : $(base) ;
+    inherit-flags $(toolset) : $(base) ;
+    inherit-rules $(toolset) : $(base) ;
+}
+
+rule inherit-generators ( toolset properties * : base : generators-to-ignore * )
+{
+    properties ?= <toolset>$(toolset) ;
+    local base-generators = [ generators.generators-for-toolset $(base) ] ;
+    for local g in $(base-generators)
+    {
+        local id = [ $(g).id ] ;
+        
+        if ! $(id) in $(generators-to-ignore)
+        {            
+            # Some generator names have multiple periods in their name, so
+            # $(id:B=$(toolset)) doesn't generate the right new-id name.
+            # e.g. if id = gcc.compile.c++, $(id:B=darwin) = darwin.c++,
+            # which is not what we want. Manually parse the base and suffix
+            # (if there's a better way to do this, I'd love to see it.)
+            # See also register in module generators.
+            local base = $(id) ;
+            local suffix = "" ;
+            while $(base:S)
+            {
+                suffix = $(base:S)$(suffix) ;
+                base = $(base:B) ;
+            }
+            local new-id = $(toolset)$(suffix) ;
+
+            generators.register [ $(g).clone $(new-id) : $(properties) ] ;
+        }        
+    }    
+}
+
+# properties listed in prohibited-properties won't
+# be inherited. Note that <debug-symbols>on and
+# <debug-symbols>off are two different properties
+rule inherit-flags ( toolset : base : prohibited-properties * )
+{
+    for local f in $(.module-flags.$(base))
+    {        
+        local rule-or-module = $(.rule-or-module.$(f)) ; 
+        if [ set.difference
+                $(.$(rule-or-module).condition.$(f)) :
+                $(prohibited-properties)
+           ] || ! $(.$(rule-or-module).condition.$(f))
+        {
+            local rule_ = [ MATCH "[^.]*\.(.*)" : $(rule-or-module) ] ;
+            local new-rule-or-module ;
+            if $(rule_)
+            {
+                new-rule-or-module = $(toolset).$(rule_) ;
+            }
+            else
+            {
+                new-rule-or-module = $(toolset) ;
+            }
+                                        
+            add-flag
+               $(new-rule-or-module)
+               : $(.$(rule-or-module).variable.$(f)) 
+               : $(.$(rule-or-module).condition.$(f))              
+               : $(.$(rule-or-module).values.$(f))
+               ;
+        }
+    }            
+}
+
+rule inherit-rules ( toolset : base )
+{
+    # It appears that "action" creates local rule... 
+    local base-generators = [ generators.generators-for-toolset $(base) ] ;
+    local rules ;
+    for local g in $(base-generators)
+    {
+        local id = [ MATCH "[^.]*\.(.*)" : [ $(g).id ] ] ;
+        rules += $(id) ;
+    }    
+    IMPORT $(base) : $(rules) : $(toolset) : $(rules) : localized ;
+    # Import the rules to the global scope
+    IMPORT $(toolset) : $(rules) : : $(toolset).$(rules) ;
+}
+
+
+
+local rule __test__ ( )
+{
+    import assert ;
+    local p = <b>0 <c>1 <d>2 <e>3 <f>4 ;
+    assert.result <c>1/<d>2/<e>3 : find-property-subset <c>1/<d>2/<e>3 <a>0/<b>0/<c>1 <d>2/<e>5 <a>9 : $(p) ;
+    assert.result : find-property-subset <a>0/<b>0/<c>9/<d>9/<e>5 <a>9 : $(p) ;
+}

Added: boost-jam/boost-build/branches/upstream/current/build/type.jam
===================================================================
--- boost-jam/boost-build/branches/upstream/current/build/type.jam	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/build/type.jam	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,294 @@
+#  Copyright (C) Vladimir Prus 2002. Permission to copy, use, modify, sell and
+#  distribute this software is granted provided this copyright notice appears in
+#  all copies. This software is provided "as is" without express or implied
+#  warranty, and with no claim as to its suitability for any purpose.
+
+#  Deals with target type declaration and defines target class which supports
+#  typed targets.
+
+import feature ;
+import generators : * ;
+import "class" : new ;
+import errors ;
+import property ;
+import scanner ;
+import project ;
+
+# This creates a circular dependency
+# project-test1 -> project -> project-root -> builtin -> type -> targets -> project
+# import targets ; 
+
+# The feature is optional so that it never implicitly added.
+# It's used only for internal purposes, and in all cases we
+# want to explicitly use it.
+feature.feature target-type : : composite optional ;
+
+# feature.feature base-target-type : : composite optional ;
+feature.feature main-target-type : : optional incidental ;
+feature.feature base-target-type : : composite optional free ;
+# feature.feature main-target-type : : composite optional incidental ;
+
+# Store suffixes for generated targets
+.suffixes = [ new property-map ] ;
+
+# Registers a target type, possible derived from a 'base-type'. 
+# If 'suffixes' are provided, they given all the suffixes that mean a file is of 'type'.
+# Also, the first element gives the suffix to be used when constructing and object of
+# 'type'.
+# If 'main' is given, a rule with the same name as the target type
+# and signature
+#     rule target-type ( name : sources * : requirements * : default-build )
+# will be added to the global scope.
+rule register ( type : suffixes * : base-type ? : main ? ) 
+{
+    # Type names cannot contain hyphens, because when used as
+    # feature-values they will be interpreted as composite features
+    # which need to be decomposed.
+    switch $(type)
+    {
+        case *-* : errors.error "type name \"$(type)\" contains a hyphen" ;
+    }
+    
+    if $(type) in $(.types)
+    {
+        errors.error "Type $(type) is already registered." ;
+    }
+    else
+    {
+        .types += $(type) ;
+        .bases.$(type) = $(base-type) ;
+
+        if $(suffixes)-not-empty
+        {            
+            # Generated targets of 'type' will use the first of 'suffixes'
+            # (this may be overriden)            
+            $(.suffixes).insert <target-type>$(type) : $(suffixes[1]) ;
+            # Specify mapping from suffixes to type
+            register-suffixes $(suffixes) : $(type) ;
+        }
+        
+        feature.extend target-type : $(type) ;
+        feature.extend main-target-type : $(type) ;
+        
+        feature.compose <target-type>$(type) : $(base-type:G=<base-target-type>) ; 
+        feature.extend base-target-type : $(type) ;
+#        feature.compose <target-type>$(type) : <base-target-type>$(type) ;
+        feature.compose <base-target-type>$(type) : <base-target-type>$(base-type) ;
+        
+        if $(main)
+        {
+            main-rule-name = [ type-to-rule-name $(type) ] ;            
+            .main-target-type.$(main-rule-name) = $(type) ;    
+            
+            IMPORT $(__name__) : main-target-rule : : $(main-rule-name) ;
+#            feature.compose <main-target-type>$(type) : <base-target-type>$(type) ;
+        }        
+    }
+}
+
+# Given type, returns name of main target rule which creates
+# targets of that type.
+rule type-to-rule-name ( type )
+{
+    # Lowercase everything. Convert underscores to dashes.ame.
+    import regex ;
+    local n = [ regex.split $(type:L) "_" ] ;
+    n = $(n:J=-) ;
+    return $(n) ;
+}
+
+# Returns a type, given the name of a main rule.
+rule type-from-rule-name ( main-target-name )
+{
+    return $(.main-target-type.$(main-target-name)) ;
+}
+
+
+
+# Specifies that targets with suffix from 'suffixes' has the type 'type'. 
+# If different type is already specified for any of syffixes,
+# issues an error.
+rule register-suffixes ( suffixes + : type )
+{
+    for local s in $(suffixes)
+    {        
+        if ! $(.type.$(s)) 
+        {
+            .type.$(s) = $(type) ; 
+        }
+        else if $(.type.$(s)) != type 
+        {
+            errors.error Attempting to specify type for suffix \"$(s)\" 
+              : "Old type $(.type.$(s)), New type $(type)" ;
+        }
+    }            
+}
+
+
+# Returns true iff type has been registered.
+rule registered ( type )
+{
+    if $(type) in $(.types)
+    {
+        return true ;
+    }
+}
+
+# Issues an error if 'type' is unknown.
+rule validate ( type )
+{
+    if ! $(type) in $(.types)
+    {
+        errors.error "Unknown target type $(type)" ;
+    }    
+}
+
+
+# Sets a scanner class that will be used for this 'type'.
+rule set-scanner ( type : scanner )
+{
+    if ! $(type) in $(.types)
+    {
+        error "Type" $(type) "is not declared" ;
+    }    
+    .scanner.$(type) = $(scanner) ;
+}
+
+# Returns a scanner instance appropriate to 'type' and 'properties'.
+rule get-scanner ( type : properties * )
+{
+    if $(.scanner.$(type)) {
+        return [ scanner.get $(.scanner.$(type)) : $(properties) ] ;
+    }    
+}
+
+# returns  type and all of its bases in order of their distance from type.
+rule all-bases ( type )
+{
+    local result = $(type) ;
+    while $(type)
+    {
+        type = $(.bases.$(type)) ;
+        result += $(type) ;
+    }
+    return $(result) ;
+}
+
+# Returns true if 'type' has 'base' as its direct or
+# indirect base.
+rule is-derived ( type base )
+{
+    if $(base) in [ all-bases $(type) ]
+    {
+        return true ;
+    }
+}
+
+# Returns true if 'type' is either derived from 'base',
+# or 'type' is equal to 'base'.
+rule is-subtype ( type base )
+{
+    if $(type) = $(base)
+    {
+        return true ;
+    }
+    else
+    {
+        return [ is-derived $(type) $(base) ] ;
+    }    
+}
+
+
+# Sets a target suffix that should be used when generating target 
+# of 'type' with the specified properties. Can be called with
+# empty properties if no suffix for 'type' was specified yet.
+# This does not automatically specify that files 'suffix' have
+# 'type' --- two different types can use the same suffix for
+# generating, but only one type should be auto-detected for
+# a file with that suffix. User should explicitly specify which
+# one.
+#
+# The 'suffix' parameter can be empty string ("") to indicate that
+# no suffix should be used.
+rule set-generated-target-suffix ( type : properties * : suffix )
+{
+    properties = <target-type>$(type) $(properties) ;
+    $(.suffixes).insert $(properties) : $(suffix) ;
+}    
+
+# Change the suffix previously registered for this type/properties 
+# combination. If suffix is not yet specified, sets it.
+rule change-generated-target-suffix ( type : properties * : suffix )
+{        
+    properties = <target-type>$(type) $(properties) ;    
+    local prev = [ $(.suffixes).find-replace $(properties) : $(suffix) ] ;
+    if ! $(prev)
+    {
+        set-generated-target-suffix $(type) : $(properties) : $(suffix) ;
+    }    
+}
+
+
+# Returns suffix that should be used when generating target of 'type',
+# with the specified properties. If not suffix were specified for
+# 'type', returns suffix for base type, if any.
+rule generated-target-suffix ( type : properties * )
+{
+    local result ;
+    local found ;
+    while $(type) && ! $(found)
+    {
+        result = [ $(.suffixes).find <target-type>$(type) $(properties) ] ;
+        # If the suffix is explicitly set to empty string, we consider suffix
+        # to be found. If we did not compare with "", there would be no
+        # way for user to set empty suffix.
+        if $(result)-is-not-empty
+        {
+            found = true ;
+        }
+        type = $(.bases.$(type)) ;
+    }
+    if $(result) = "" 
+    {
+        result = ;
+    }
+    return $(result) ;
+}
+
+# Returns file type given it's name. If there are several dots in filename,
+# tries each suffix. E.g. for name of "file.so.1.2" suffixes "2", "1", and 
+# "so"  will be tried.
+rule type ( filename ) 
+{
+    local type ;
+    while ! $(type) && $(filename:S) 
+    {
+        local suffix = $(filename:S) ;
+        type = $(.type$(suffix)) ;
+        filename = $(filename:S=) ;
+    }
+    return $(type) ;
+}
+
+
+
+rule main-target-rule ( name : sources * : requirements * : default-build * 
+                        : usage-requirements * )
+{
+    # First find required target type, which is equal to the name used
+    # to invoke us.
+    local bt = [ BACKTRACE 1 ] ;
+    local rulename = $(bt[4]) ;
+    
+    # This rule may be only called from Jamfile, and therefore, 
+    # CALLER_MODULE is Jamfile module, which is used to denote 
+    # a project.
+    local project = [ project.current ] ;
+        
+    # This is a circular module dependency, so it must be imported here
+    import targets ;
+    return [ targets.create-typed-target $(.main-target-type.$(rulename)) : $(project)
+      : $(name) : $(sources) : $(requirements) 
+      : $(default-build) : $(usage-requirements) ] ;        
+}
+

Added: boost-jam/boost-build/branches/upstream/current/build/version.jam
===================================================================
--- boost-jam/boost-build/branches/upstream/current/build/version.jam	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/build/version.jam	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,21 @@
+#  Copyright (C) Vladimir Prus 2002. Permission to copy, use, modify, sell and
+#  distribute this software is granted provided this copyright notice appears in
+#  all copies. This software is provided "as is" without express or implied
+#  warranty, and with no claim as to its suitability for any purpose.
+
+rule boost-build ( )
+{
+    return "V2 (Milestone 10)" ;
+}
+rule jam ( )
+{
+    local v = [ modules.peek : JAM_VERSION  ] ;
+    return $(v:J=.) ;
+}
+
+
+rule print ( )
+{
+    ECHO "Boost.Build" [ boost-build ] ;
+    ECHO "Boost.Jam" [ jam ] ;
+}

Added: boost-jam/boost-build/branches/upstream/current/build/virtual-target.jam
===================================================================
--- boost-jam/boost-build/branches/upstream/current/build/virtual-target.jam	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/build/virtual-target.jam	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,1177 @@
+#  Copyright (C) Vladimir Prus 2002. Permission to copy, use, modify, sell and
+#  distribute this software is granted provided this copyright notice appears in
+#  all copies. This software is provided "as is" without express or implied
+#  warranty, and with no claim as to its suitability for any purpose.
+
+#  Implements virtual targets, which correspond to actual files created during
+#  build, but are not yet targets in Jam sense. They are needed, for example,
+#  when searching for possible transormation sequences, when it's not known
+#  if particular target should be created at all.
+
+import "class" : new ;
+import path property-set utility sequence errors set ;
+
+#                       +--------------------------+
+#                       | virtual-target           |
+#                       +==========================+
+#                       | actualize                |
+#                       +--------------------------+
+#                       | actualize-action() = 0   |
+#                       | actualize-location() = 0 |
+#                       +----------------+---------+
+#                                        |
+#                                        ^
+#                                       / \
+#                                      +-+-+
+#                                        |
+#    +---------------------+     +-------+--------------+
+#    | action              |     | abstract-file-target |
+#    +=====================|   * +======================+
+#    | action-name         |  +--+ action               |
+#    | properties          |  |  +----------------------+
+#    +---------------------+--+  | actualize-action()   |
+#    | actualize()         |0..1 +-----------+----------+
+#    | path()              |                 |
+#    | adjust-properties() | sources         |
+#    | actualize-sources() | targets         |
+#    +------+--------------+                 ^
+#           |                               / \
+#           ^                              +-+-+
+#          / \                               |
+#         +-+-+                +-------------+-------------+
+#           |                  |                           |
+#           |           +------+---------------+  +--------+-------------+
+#           |           | file-target          |  | searched-lib-target  |
+#           |           +======================+  +======================+
+#           |           | actualize-location() |  | actualize-location() |
+#           |           +----------------------+  +----------------------+
+#           |
+#         +-+------------------------------+
+#         |                                |
+#    +----+----------------+     +---------+-----------+
+#    | compile-action      |     | link-action         |
+#    +=====================+     +=====================+
+#    | adjust-properties() |     | adjust-properties() |
+#    +---------------------+     | actualize-sources() |
+#                                +---------------------+
+#
+# The 'compile-action' and 'link-action' classes are defined not here,
+# but in builtin.jam modules. They are shown in the diagram to give
+# the big picture.
+
+# Potential target. It can be converted into jam target and used in
+# building, if needed. However, it can be also dropped, which allows
+# to search for different transformation and select only one.
+#
+class virtual-target 
+{
+    import virtual-target utility scanner ;    
+    
+    rule __init__ ( name  # Name of this target -- specifies the name of
+        : project # Project to which this target belongs
+    )
+    {    
+        self.name = $(name) ;
+        self.project = $(project) ;
+        self.dependencies = ;
+    }
+    
+    # Name of this target.
+    rule name ( ) { return $(self.name) ; }
+
+    # Project of this target.
+    rule project ( ) { return $(self.project) ; }
+
+    # Adds additional instances of 'virtual-target' that this
+    # one depends on.
+    rule depends ( d + )
+    {
+        self.dependencies = [ sequence.merge $(self.dependencies)
+                               : [ sequence.insertion-sort $(d) ] ] ;
+    }
+
+    rule dependencies ( )
+    {
+        return $(self.dependencies) ;
+    }
+
+    # Generates all the actual targets and sets up build actions for
+    # this target.
+    #
+    # If 'scanner' is specified, creates an additional target
+    # with the same location as actual target, which will depend on the
+    # actual target and be associated with 'scanner'. That additional
+    # target is returned. See the docs (#dependency_scanning) for rationale.
+    # Target must correspond to a file if 'scanner' is specified.
+    #
+    # If scanner is not specified, then actual target is returned.
+    rule actualize ( scanner ? )
+    {
+        local actual-name = [ actualize-no-scanner ] ;
+
+        if ! $(scanner)
+        {
+            return $(actual-name) ;
+        }
+        else
+        {
+            # Add the scanner instance to the grist for name.
+            local g = [ sequence.join
+                [ utility.ungrist $(actual-name:G) ] $(scanner) : - ] ;
+            local name = $(actual-name:G=$(g)) ;
+
+            if ! $(self.made.$(name)) {
+                self.made.$(name) = true ;
+
+                DEPENDS $(name) : $(actual-name) ;
+
+                actualize-location $(name) ;
+
+                scanner.install $(scanner) : $(name) $(__name__) ;
+            }
+            return $(name) ;
+        }
+
+    }
+
+# private: (overridables)
+
+    # Sets up build actions for 'target'. Should call appropriate rules
+    # and set target variables.
+    rule actualize-action ( target )
+    {
+        errors.error "method should be defined in derived classes" ;
+    }
+
+    # Sets up variables on 'target' which specify its location.
+    rule actualize-location ( target )
+    {
+        errors.error "method should be defined in derived classes" ;
+    }
+    
+    # If the target is generated one, returns the path where it will be
+    # generated. Otherwise, returns empty list.
+    rule path ( )
+    {
+        errors.error "method should be defined in derived classes" ;        
+    }
+    
+    # Return that actual target name that should be used
+    # (for the case where no scanner is involved)
+    rule actual-name ( )
+    {
+        errors.error "method should be defined in derived classes" ;
+    }
+
+# implementation
+    rule actualize-no-scanner ( )
+    {
+        local name = [ actual-name ] ;
+
+        # Do anything only on the first invocation
+        if ! $(self.made.$(name)) {
+            self.made.$(name) = true ;
+            
+            virtual-target.register-actual-name $(name) : $(__name__) ;            
+
+            for local i in $(self.dependencies) {
+                DEPENDS $(name) : [ $(i).actualize ] ;
+            }
+
+            actualize-location $(name) ;
+            actualize-action $(name) ;
+        }
+        return $(name) ;
+    }
+
+
+}
+
+
+# Target which correspond to a file. The exact mapping for file
+# is not yet specified in this class. (TODO: Actually, the class name
+# could be better...)
+#
+# May be a source file (when no action is specified), or
+# derived file (otherwise).
+#
+# The target's grist is concatenation of project's location,
+# properties of action (for derived files), and, optionally,
+# value identifying the main target.
+class abstract-file-target : virtual-target
+{
+    import project regex sequence path type ;
+    
+    rule __init__ ( name
+        : type ?  # Optional type for this target
+                  : project
+    )
+    {
+        virtual-target.__init__ $(name) : $(project) ;
+            
+        self.type = $(type) ;
+        self.action = ;
+    }
+    
+    rule type ( ) { return $(self.type) ; }
+    rule set-type ( type )
+    {
+        self.type = $(type) ;
+    }
+
+    # Sets the suffix. When generating target name, it will be used in preference to
+    # the suffix that is associated with 'type'
+    rule suffix ( suffix ? )
+    {
+        if $(suffix)
+        {
+            self.suffix = $(suffix) ;
+        }
+        return $(self.suffix) ;
+    }
+
+    # Sets the path. When generating target name, it will override any path
+    # computation from properties.
+    rule set-path ( path )
+    {
+        self.path = [ path.native $(path) ] ;
+    }
+
+    # If 'a' is supplied, sets action to 'a'.
+    # Returns the action currently set.
+    rule action ( a ? )
+    {
+        if $(a)
+        {
+            self.action = $(a) ;
+        }
+        return $(self.action) ;
+    }
+
+    # Sets/gets the 'root' flag. Target is root is it directly correspods to some
+    # variant of a main target.
+    rule root ( set ? )
+    {
+        if $(set)
+        {
+            self.root = true ;
+        }
+        return $(self.root) ;
+    }
+    
+    rule set-intermediate ( value ? )
+    {
+        self.intermediate = $(value) ;
+    }
+    
+    rule intermediate ( )      
+    {
+        return $(self.intermediate) ;
+    }
+    
+    
+
+    # Gets or sets the subvariant which created this target. Subvariant
+    # is set when target is brought into existance, and is never changed
+    # after that. In particual, if target is shared by subvariant, only 
+    # the first is stored.    
+    rule creating-subvariant ( s ? # If specified, specified the value to set,
+                                   # which should be instance of 'subvariant'
+                                   # class.
+                             )
+    {
+        if $(s) && ( ! $(self.creating-subvariant) && ! $(overwrite) )
+        {
+            if $(self.creating-subvariant)
+            {
+                errors.error "Attempt to change 'dg'" ;
+            }
+            else
+            {                
+                self.creatin-subvariant = $(s) ;
+            }            
+        }
+        return $(self.creatin-subvariant) ;
+    }
+
+    rule actualize-action ( target )
+    {
+        if $(self.action)
+        {
+            $(self.action).actualize ;
+        }
+    }
+          
+    # Return a human-readable representation of this target
+    #
+    # If this target has an action, that's:
+    #
+    #    { <action-name>-<self.name>.<self.type> <action-sources>... }
+    #
+    # otherwise, it's:
+    #
+    #    { <self.name>.<self.type> }
+    #
+    rule str ( )
+    {
+        local action = [ action ] ;
+        
+        local name-dot-type = [ sequence.join $(self.name) "."  $(self.type) ] ;
+        
+        if $(action)
+        {
+            local sources = [ $(action).sources ] ;
+            
+            local action-name =  [ $(action).action-name ] ;            
+
+            local ss ;            
+            for local s in $(sources)
+            {
+                ss += [ $(s).str ] ;
+            }
+            
+            return "{" $(action-name)-$(name-dot-type) $(ss) "}" ;
+        }
+        else
+        {
+            return "{" $(name-dot-type) "}" ;
+        }
+    }
+
+    rule less ( a )
+    {
+        if [ str ] < [ $(a).str ]
+        {
+            return true ;
+        }
+    }
+
+    rule equal ( a )
+    {
+        if [ str ] = [ $(a).str ]
+        {
+            return true ;
+        }
+    }
+
+# private:
+    rule actual-name ( )
+    {
+        if ! $(self.actual-name)
+        {            
+            local grist = [ grist ] ;
+            
+            local basename = [ actual-basename ] ;
+            self.actual-name = <$(grist)>$(basename) ;
+            
+        }
+        return $(self.actual-name) ;
+    }
+        
+    # Helper to 'actual-name', above. Compute unique prefix used to distinguish
+    # this target from other targets with the same name which create different
+    # file.
+    rule grist ( )
+    {
+        # Depending on target, there may be different approaches to generating
+        # unique prefixes. We'll generate prefixes in the form 
+        # <one letter approach code> <the actual prefix>
+        local path = [ path ] ;
+        if $(path)
+        {
+            # The target will be generated to a know path. Just use the path
+            # for identification, since path is as unique as it can get.
+            return p$(path) ;            
+        }
+        else
+        {
+            # File is either source, which will be searched for, or is not a file at
+            # all. Use the location of project for distinguishing.
+            local project-location = [ $(self.project).get location ] ;
+            local location-grist =
+              [ sequence.join [ regex.split $(project-location) "/" ] : "!" ] ;
+            
+            if $(self.action)
+            {
+                local ps = [ $(self.action).properties ] ;     
+                local property-grist = [ $(ps).as-path ] ;
+                location-grist = $(location-grist)/$(property-grist) ;
+            }            
+                        
+            return l$(location-grist) ;
+        }                
+    }
+        
+    # Helper to actual-name, above. Compute the 'basename' of the filename
+    # of the actual created file.
+    rule actual-basename ( )
+    {
+        local name = [ path.native $(self.name) ] ;
+        if $(self.suffix)
+        {
+            name = $(name).$(self.suffix) ;
+        }
+        else if $(self.type)
+        {
+            local properties ;
+            if $(self.action)
+            {
+                local ps = [ $(self.action).properties ] ;
+                properties = [ $(ps).raw ] ;
+            }                        
+            local suffix = [ type.generated-target-suffix $(self.type) :
+              $(properties) ] ;
+            if $(suffix)
+            {                
+                name = $(name).$(suffix) ;
+            }            
+        }
+        return $(name) ;        
+    }
+    
+
+}
+
+# File target with explicitly known location.
+#
+# The file path is determined as
+#    - value passed to the 'set-path' method, if any
+#    - for derived files, project's build dir, joined with components
+#      that describe action's properties. If the free properties
+#      are not equal to the project's reference properties
+#      an element with name of main target is added.
+#    - for source files, project's source dir
+#
+# The file suffix is
+#     - the value passed to the 'suffix' method, if any, or
+#     - the suffix which correspond to the target's type.
+#
+class file-target : abstract-file-target 
+{
+    import common ;    
+    import errors ;
+    
+    rule __init__ (
+      name
+        : type ?  # Optional type for this target
+        : project
+    )
+    {
+        abstract-file-target.__init__ $(name) : $(type) : $(project) ;   
+    }
+        
+    rule actualize-location ( target )
+    {
+        if $(self.action)
+        {
+            # This is a derived file.
+            local path = [ path ] ;
+            LOCATE on $(target) = $(path) ;                        
+
+            # Make sure the path exists.
+            DEPENDS $(target) : $(path) ;
+            common.MkDir $(path) ;
+        }
+        else
+        {
+            # This is a source file.
+            SEARCH on $(target) =
+              [ path.native [ $(self.project).get source-location ] ] ;
+        }        
+    }
+    
+    # Returns the directory for this target
+    rule path ( )
+    {
+        if ! $(self.path)
+        {
+            if $(self.action)
+            {                
+                local build-dir = [ $(self.project).get build-dir ] ;
+                if ! $(build-dir)
+                {
+                    build-dir = [ path.join 
+                        [ $(self.project).get location ]
+                        bin
+                    ] ;
+                }
+                
+                local path = [ path.join
+                    $(build-dir)
+                      [ $(self.action).path ]
+                ] ;
+                
+                # Store the computed path, so that it's not recomputed
+                # any more
+                self.path = [ path.native $(path) ] ;
+            }            
+        }
+        return $(self.path) ;
+     }
+
+}
+
+class notfile-target : abstract-file-target
+{
+    rule __init__ ( name : project )
+    {
+        abstract-file-target.__init__ $(name) : : $(project) ;
+    }
+    
+            
+    rule actualize-location ( target )
+    {
+        NOTFILE $(target) ;
+        ALWAYS $(target) ;
+    }    
+}    
+
+# Class which represents an action.
+# Both 'targets' and 'sources' should list instances of 'virtual-target'.
+# Action name should name a rule with this prototype
+#     rule action-name ( targets + : sources * : properties * )
+# Targets and sources are passed as actual jam targets. The rule may
+# not establish dependency relationship, but should do everything else.
+class action 
+{
+    import type toolset property-set indirect class path ;
+    
+    rule __init__ ( targets + : sources * : action-name + : property-set ? )
+    {        
+        self.targets = $(targets) ;
+        self.sources = $(sources) ;
+    
+        self.action-name = [ indirect.make-qualified $(action-name) ] ;
+        
+        if ! $(property-set) 
+        {
+            property-set = [ property-set.empty ] ;
+        }
+        
+        if ! [ class.is-instance $(property-set) ]
+        {        
+            errors.error "Property set instance required" ;
+        }
+        
+        self.properties = $(property-set) ;
+    }        
+    
+    rule targets ( )
+    {
+        return $(self.targets) ;
+    }
+
+    rule sources ( )
+    {
+        return $(self.sources) ;
+    }
+
+    rule action-name ( )
+    {
+        return $(self.action-name) ;
+    }
+
+    rule properties ( )
+    {
+        return $(self.properties) ;
+    }
+
+    # Generates actual build instructions.
+    rule actualize ( )
+    {
+        if ! $(self.actualized)
+        {
+            self.actualized = true ;
+
+            local ps = [ properties ] ;
+            local properties = [ adjust-properties [ $(ps).raw ] ] ;
+
+
+            local actual-targets ;
+            for local i in [ targets ]
+            {
+                actual-targets += [ $(i).actualize ] ;
+            }
+
+            actualize-sources [ sources ] ;
+
+            DEPENDS $(actual-targets) : $(self.actual-sources) $(self.dependency-only-sources) ;
+
+            # Action name can include additional argument to rule, which should not
+            # be passed to 'set-target-variables'
+            toolset.set-target-variables
+              [ indirect.get-rule $(self.action-name[1]) ] $(actual-targets)
+                : $(properties) ;
+            
+            indirect.call $(self.action-name) 
+              $(actual-targets) : $(self.actual-sources) : $(properties)
+                ;
+            
+            # Since we set up creating action here, we also set up
+            # action for cleaning up
+            common.Clean clean : $(actual-targets) ;
+        }
+    }
+
+    # Helper for 'actualize-sources'.
+    # For each passed source, actualizes it with the appropriate scanner.
+    # Returns the actualized virtual targets.
+    rule actualize-source-type ( sources * )
+    {
+        local result = ;
+        for local i in $(sources)
+        {
+            local scanner ;
+            if [ $(i).type ]
+            {
+                scanner =
+                  [ type.get-scanner [ $(i).type ] : $(properties) ] ;
+            }
+            result += [ $(i).actualize $(scanner) ] ;
+        }
+        
+        return $(result) ;
+    }
+    
+    # Creates actual jam targets for sources. Initialized two member
+    # variables:.
+    # 'self.actual-sources' -- sources which are passed to updating action
+    # 'self.dependency-only-sources' -- sources which are made dependencies, but
+    # are not used otherwise.
+    #
+    # New values will be *appended* to the variables. They may be non-empty,
+    # if caller wants it.
+    rule actualize-sources ( sources * )
+    {
+        local dependencies = [ $(self.properties).get <dependency> ] ;
+                
+        self.dependency-only-sources += [ actualize-source-type $(dependencies) ] ;
+        self.actual-sources += [ actualize-source-type $(sources) ] ;
+    }
+
+    rule path ( )
+    {
+        local p = [ $(self.properties).as-path ] ;
+        # Really, an ugly hack. Boost regression test system requires
+        # specific target paths, and it seems that changing it to handle
+        # other directory layout is really hard. For that reason,
+        # we teach V2 to do the things regression system requires.
+        # The value o '<location-prefix>' is predended to the path.
+        local prefix = [ $(self.properties).get <location-prefix> ] ;
+        if $(prefix)
+        {
+            p = [ path.join $(prefix) $(p) ] ;
+        }        
+        return $(p) ;
+    }
+
+    # Determined real properties when trying building with 'properties'.
+    # This is last chance to fix properties, for example to adjust includes
+    # to get generated headers correctly. Default implementation returns
+    # its argument.
+    rule adjust-properties ( properties * )
+    {
+        return $(properties) ;
+    }
+
+
+    rule set-targets ( targets * )
+    {
+        self.targets = $(targets) ;
+    }
+}
+
+# Action class which does nothing --- it produces the targets with
+# specific properties out of nowhere. It's needed to distinguish virtual
+# targets with different properties that are known to exist, and have no 
+# actions which create them.
+class null-action : action 
+{
+    rule __init__ ( targets + : property-set ? )
+    {
+        action.__init__ $(targets) : : .no-action : $(property-set) ;
+    }
+        
+    rule actualize ( )
+    {
+        if ! $(self.actualized)
+        {
+            self.actualized = true ;
+
+            for local i in [ targets ]
+            {
+                $(i).actualize ;
+            }
+        }        
+    }
+}
+
+
+# Creates a virtual target with approariate name and type from 'file'.
+# If a target with that name in that project was already created, returns that already
+# created target.
+# FIXME: more correct way would be to compute path to the file, based on name and source location
+# for the project, and use that path to determine if the target was already created.
+# TODO: passing project with all virtual targets starts to be annoying.
+rule from-file ( file : project )
+{
+    import type ; # had to do this here to break a circular dependency
+
+    # Check if we've created a target corresponding to this file.
+    local source-location = [ $(project).get source-location ] ;
+    local path = [ path.root [ path.root [ path.make $(file) ] $(source-location) ] 
+      [ path.pwd ] ] ;
+                
+    if $(.files.$(path))
+    {
+        return $(.files.$(path)) ;
+    }
+    else
+    {
+        local name = [ path.make $(file:S=) ] ;
+        local type = [ type.type $(file) ] ;
+        local result ;
+        if ! $(type)
+        {
+            # warning "cannot determine type for file $(file)" ;
+            result = [ new file-target $(file) :  : $(project) ] ;
+        }
+        else
+        {
+            local v = [ new file-target $(name) : $(type) : $(project) ] ;
+            $(v).suffix [ MATCH ^.(.*)$ : $(file:S) ] ;
+            result = $(v) ;
+        }
+        .files.$(path) = $(result) ;
+        return $(result) ;
+    }
+}
+
+# Registers a new virtual target. Checks if there's already registered target, with the same
+# name, type, project and subvariant properties, and also with the same sources
+# and equal action. If such target is found it is retured and 'target' is not registers.
+# Otherwise, 'target' is registered and returned.
+rule register ( target )
+{
+    local signature = [ sequence.join
+        [ $(target).actual-name ] : - ] ;    
+            
+    local result ;
+    for local t in $(.cache.$(signature))
+    {
+        local a1 = [ $(t).action ] ;
+        local a2 = [ $(target).action ] ;
+        
+        if ! $(result)
+        {
+            if ! $(a1) && ! $(a2)
+            {
+                result = $(t) ;
+            }
+            else 
+            {
+                if $(a1) && $(a2) && [ $(a1).action-name ] = [ $(a2).action-name ] && 
+                  [ $(a1).sources ] = [ $(a2).sources ]
+                {
+                    local ps1 = [ $(a1).properties ] ;
+                    local ps2 = [ $(a2).properties ] ;
+                    local p1 = [ $(ps1).base ] [ $(ps1).free ] [ $(ps1).dependency ] ;
+                    local p2 = [ $(ps2).base ] [ $(ps2).free ] [ $(ps2).dependency ] ;
+                    if $(p1) = $(p2) 
+                    {                        
+                        result = $(t) ;
+                    }                    
+                }
+            }                        
+        }
+    }
+    
+    if ! $(result)
+    {
+        .cache.$(signature) += $(target) ;     
+        result = $(target) ;
+    }
+
+    return $(result) ;
+}
+
+rule register-actual-name ( actual-name : virtual-target )
+{
+    if $(.actual.$(actual-name))
+    {
+        local cs1 = [ $(.actual.$(actual-name)).creating-subvariant ] ;
+        local cs2 = [ $(virtual-target).creating-subvariant ] ;
+        local cmt1 = [ $(cs1).main-target ] ;
+        local cmt2 = [ $(cs2).main-target ] ;
+        
+        
+        local action1 = [ $(.actual.$(actual-name)).action ] ;
+        local action2 = [ $(virtual-target).action ] ;
+        local properties-added ;
+        local properties-removed ;
+        if $(action1) && $(action2)
+        {
+            local p1 = [ $(action1).properties ] ;
+            p1 = [ $(p1).raw ] ;
+            local p2 = [ $(action2).properties ] ;
+            p2 = [ $(p2).raw ] ;
+            properties-removed = [ set.difference $(p1) : $(p2) ] ;
+            properties-removed ?= "none" ;
+            properties-added = [ set.difference $(p2) : $(p1) ] ;
+            properties-added ?= "none" ;
+        }        
+        errors.error "Duplicate name of actual target:" $(actual-name) 
+          : "previous virtual target" [ $(.actual.$(actual-name)).str ] 
+          : "created from" [ $(cmt1).location ]
+          : "another virtual target" [ $(virtual-target).str ]
+          : "created from" [ $(cmt2).location ]                
+          : "added properties: " $(properties-added) 
+          : "removed properties: " $(properties-removed) ;
+    }
+    else
+    {
+        .actual.$(actual-name) = $(virtual-target) ;
+    }        
+}
+
+
+# Traverses the dependency graph of 'target' and return all targets that will
+# be created before this one is created. If root of some dependency graph is
+# found during traversal, it's either included or not, dependencing of the
+# value of 'include-roots'. In either case, sources of root are not traversed.
+rule traverse ( target : include-roots ? : include-sources ? )
+{
+    local result ;
+    if [ $(target).action ]
+    {
+        local action = [ $(target).action ] ;
+        # This includes 'target' as well
+        result += [ $(action).targets ] ;
+
+        for local t in [ $(action).sources ]
+        {
+            if ! [ $(t).root ]
+            {
+                result += [ traverse $(t) : $(include-roots) : $(include-sources) ] ;
+            }
+            else if $(include-roots)
+            {
+                result += $(t) ;
+            }            
+        }
+    }
+    else if $(include-sources)
+    {
+        result = $(target) ;
+    }    
+    return $(result) ;
+}
+
+# Takes an 'action' instances and creates new instance of it
+# and all produced target. The rule-name and properties are set
+# to 'new-rule-name' and 'new-properties', if those are specified.
+# Returns the cloned action.
+rule clone-action ( action : new-project : new-action-name ? : new-properties ? )
+{
+    if ! $(new-action-name)
+    {
+        new-action-name = [ $(action).action-name ] ;
+    }
+    if ! $(new-properties)
+    {
+        new-properties = [ $(action).properties ] ;
+    }
+                    
+    local cloned-targets ;
+    for local target in [ $(action).targets ]
+    {
+        local n = [ $(target).name ] ;
+        local cloned-target = [ class.new file-target $(n:D=) : [ $(target).type ] 
+          : $(new-project) ] ;
+        local d = [ $(target).dependencies ] ;
+        if $(d)
+        {            
+            $(cloned-target).depends $(d) ;
+        }                    
+        $(cloned-target).root [ $(target).root ] ;
+        $(cloned-target).creating-subvariant [ $(target).creating-subvariant ] ;
+        
+        cloned-targets += $(cloned-target) ;
+    }        
+        
+    local action-class = [ modules.peek $(action) : __class__ ] ;
+    
+    local cloned-action = [ class.new $(action-class) $(cloned-targets) : 
+      [ $(action).sources ] : $(new-action-name) : $(new-properties) ] ;
+    
+    for local cloned-target in $(cloned-targets)
+    {        
+        $(cloned-target).action $(cloned-action) ;
+    }
+    
+    
+    return $(cloned-action) ;        
+}
+
+
+
+
+# Clones a dependency graph template, given one of its root,
+# and a new source target to instantinate the template with.
+#
+# If 'target's name is "%" and type is equal to 'new-source's
+# return 'new-source', otherwise created a new target:
+#  - if there "%" in target's name, its replaced with 'new-target's
+#  - project for new target is the same as for 'new-target'
+#  - other attributes are copied
+#
+# If 'dont-recurse' is not set, clones action, which results in
+# cloning of other targets, and, ultimately, cloning of the
+# entire dependency graph.
+#
+# The 'new-project' parameter tells what project should be assigned
+# for newly created non-source targets.
+rule clone-template ( target dont-recurse ? : new-source : new-project : dont-register ? )
+{
+    local name = [ $(new-source).name ] ;
+    local old-name = [ $(target).name ] ;
+    local new-name = $(old-name) ;
+    local m = [ MATCH (.*)(%)(.*) : $(old-name) ] ;
+    if $(m)
+    {
+        if [ $(target).action ]
+        {
+            new-name = [ sequence.join $(m[1]) $(name:D=) $(m[3]) ] ;
+        }
+        else
+        {
+            new-name = [ sequence.join $(m[1]) $(name) $(m[3]) ] ;
+        }
+    }
+
+    if $(old-name) = % && [ $(target).type ] = [ $(new-source).type ]
+    {
+        return $(new-source) ;
+    }
+    else
+    {
+        local cloned = [ new file-target $(new-name) : [ $(target).type ] :
+          $(new-project) ] ;
+        $(cloned).set-intermediate [ $(target).intermediate ] ;
+
+        if ! $(dont-recurse) && [ $(target).action ]
+        {
+            local cloned-action = [ clone-action-template
+                [ $(target).action ] $(target) $(cloned) : $(new-source) : $(new-project) ] ;
+
+            cloned-targets = $(cloned) ;
+            for t in [ $(cloned-action).targets ]
+            {
+                if $(t) != $(target)
+                {
+                    cloned-targets +=
+                      [ clone-template $(t) dont-recurse : $(new-source) : $(new-project) 
+                        # We don't want to pass new targets vis 'register' util we've
+                        # finished building them -- i.e. until we assign the action.
+                        # It might seem registering this not-yet ready target is
+                        # harmless, but in fact the 'register' logic expects than
+                        # registered target is never changed later.
+                        : dont-register ] ;
+                }
+            }
+            local cloned-targets2 ;
+            for local t in $(cloned-targets)
+            {
+                $(t).action $(cloned-action) ;
+
+                cloned-targets2 += [ register $(t) ] ;
+
+            }
+            
+            $(cloned-action).set-targets $(cloned-targets2) ;
+            cloned = $(cloned-targets2[1]) ;
+        }
+        else
+        {
+            if ! $(dont-register)
+            {                
+                cloned = [ register $(cloned) ] ;
+            }            
+        }
+        return $(cloned) ;
+    }
+}
+
+# Clones an action template: helper for clone-template above.
+local rule clone-action-template ( action from cloned-from : new-source : new-project )
+{
+    local targets ;
+    local sources ;
+
+    for local t in [ $(action).sources ]
+    {
+        sources += [ clone-template $(t) : $(new-source) : $(new-project) ] ;
+    }
+
+    local action-class = [ modules.peek $(action) : __class__ ] ;
+
+    local ps = [ $(action).properties ] ;
+    local cloned = [ new $(action-class) [ $(action).targets ] : $(sources)
+                     : [ $(action).action-name ] : $(ps) ] ;
+
+    return $(cloned) ;
+}
+
+class subvariant
+{
+    import sequence ;    
+    import type ;
+    
+    rule __init__ ( main-target # The instance of main-target class
+        : property-set                     # Properties requested for this target
+        : sources *
+        : build-properties                 # Actually used properties
+        : sources-usage-requirements       # Properties propagated from sources
+        : created-targets * )              # Top-level created targets
+    {        
+        self.main-target = $(main-target) ;        
+        self.properties = $(property-set) ;
+        self.sources = $(sources) ;
+        self.build-properties = $(build-properties) ;
+        self.sources-usage-requirements = $(sources-usage-requirements) ;
+        self.created-targets = $(created-targets) ;
+
+        # Pre-compose the list of other dependency graphs, on which this one
+        # depends
+        local deps = [ $(build-properties).get <implicit-dependency> ] ;
+        for local d in $(deps)
+        {
+            self.other-dg += [ $(d:G=).creating-subvariant ] ;
+        }
+        
+        self.other-dg = [ sequence.unique $(self.other-dg) ] ;
+    }
+    
+               
+    rule main-target ( )
+    {
+        return $(self.main-target) ;
+    }
+    
+    rule created-targets ( ) 
+    {
+        return $(self.created-targets) ;
+    }
+    
+    rule requested-properties ( )
+    {
+        return $(self.properties) ;
+    }
+    
+    rule build-properties ( )
+    {
+        return $(self.build-properties) ;
+    }
+        
+    rule sources-usage-requirements ( )
+    {
+        return $(self.sources-usage-requirements) ;
+    }
+    
+    rule set-usage-requirements ( usage-requirements )
+    {
+        self.usage-requirements = $(usage-requirements) ;
+    }
+    
+    rule usage-requirements ( )
+    {
+        return $(self.usage-requirements) ;
+    }
+            
+    # Returns all targets referenced by this subvariant,
+    # either directly or indirectly, and 
+    # either as sources, or as dependency properties.
+    rule all-referenced-targets ( )
+    {
+        # Find directly referenced targets.
+        local deps = [ $(self.build-properties).dependency ] ;
+        local all-targets = $(self.sources) $(deps:G=) ;
+        
+        # Find other subvariants.
+        local r ;
+        for local t in $(all-targets)
+        {            
+            r += [ $(t).creating-subvariant ] ;
+        }
+        r = [ sequence.unique $(r) ] ;
+        for local s in $(r) 
+        {
+            if $(s) != $(__name__)
+            {
+                all-targets += [ $(s).all-referenced-targets ] ;
+            }            
+        }
+        return $(all-targets) ;                        
+    }
+               
+    # Returns the properties which specify implicit include paths to
+    # generated headers. This traverses all targets in this subvariant,
+    # and subvariants referred by <implcit-dependecy>properties.
+    # For all targets which are of type 'target-type' (or for all targets,
+    # if 'target-type' is not specified), the result will contain
+    # <$(feature)>path-to-that-target.
+    rule implicit-includes ( feature : target-type ? )
+    {
+        local key = ii$(feature)-$(target-type:E="") ;
+        if ! $($(key))-is-nonempty
+        {
+            local target-paths = [ all-target-directories $(target-type) ] ;    
+            target-paths = [ sequence.unique $(target-paths) ] ;
+            local result = $(target-paths:G=$(feature)) ;
+            if ! $(result)
+            {
+                result = "" ;
+            }            
+            $(key) = $(result) ;
+        }
+        if $($(key)) = ""
+        {
+            return ;
+        }
+        else
+        {
+            return $($(key)) ;
+        }        
+    }
+        
+    rule all-target-directories ( target-type ? )
+    {
+        if ! $(self.target-directories)
+        {
+            compute-target-directories $(target-type) ;
+        }                
+        return $(self.target-directories) ;
+    }
+    
+    rule compute-target-directories ( target-type ? )
+    {   
+        local result ;
+        for local t in $(self.created-targets)
+        {
+            if $(target-type) && ! [ type.is-derived [ $(t).type ] $(target-type) ] 
+            {
+                # Skip target which is of wrong type.
+            }
+            else
+            {                
+                result = [ sequence.merge $(result) : [ $(t).path ] ] ;
+            }            
+        }
+        for local d in $(self.other-dg)
+        {
+            result += [ $(d).all-target-directories $(target-type) ] ;
+        }
+        self.target-directories = $(result) ;
+    }   
+}
+

Added: boost-jam/boost-build/branches/upstream/current/build-system.jam
===================================================================
--- boost-jam/boost-build/branches/upstream/current/build-system.jam	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/build-system.jam	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,184 @@
+#  (C) Copyright David Abrahams 2001-2003. Permission to copy, use,
+#  modify, sell and distribute this software is granted provided this
+#  copyright notice appears in all copies. This software is provided
+#  "as is" without express or implied warranty, and with no claim as
+#  to its suitability for any purpose.
+
+# This file is part of Boost.Build version 2.  You can think of it as
+# forming the main() routine.  It is invoked by the bootstrapping code
+# in bootstrap.jam.
+#
+# The version of bootstrap.jam invoking this lives in
+# tools/build/kernel until BBv1 is retired, so that BBv1 can have its
+# bootstrap.jam in this directory.
+
+import project ;
+import targets ;
+import sequence ;
+import modules ;
+import feature ;
+import property-set ;
+import build-request ;
+import errors : error ;
+import project-roots ;
+import "class" : new ;
+
+import builtin ;
+import make ;
+import os ;
+
+import version ;
+
+# Check if we can load 'test-config.jam'. If we can, load it and
+# ignore user configs.
+local test-config = [ GLOB [ modules.peek : BOOST_BUILD_PATH ] : test-config.jam ] ;
+if $(test-config)
+{
+    import test-config ;    
+}
+
+if ! $(test-config) && ! --ignore-config in [ modules.peek : ARGV ] 
+{    
+    module site-config 
+    {
+        import toolset : using ;
+    }
+
+    module user-config 
+    {
+        import toolset : using ;
+    }
+
+    local user-path = [ modules.peek : HOME ] [ modules.peek : BOOST_BUILD_PATH ] ;
+    if [ os.name ] in NT CYGWIN
+    {    
+        modules.load site-config : : [ modules.peek : SystemRoot ] $(user-path) ;
+        modules.load user-config : : $(user-path) ;    
+    }    
+    else
+    {
+        modules.load site-config : : /etc $(user-path) ;
+        modules.load user-config : : $(user-path) ;    
+    }
+}
+
+
+if --version in [ modules.peek : ARGV ]
+{
+    version.print ;
+    EXIT ;
+}
+
+# We always load project in "." so that 'use-project' directives has
+# any chance of been seen. Otherwise, we won't be able to refer to
+# subprojects using target ids.
+current-project = [ project.target [ project.load "." ] ] ;
+
+if [ MATCH (--dump-projects) : [ modules.peek : ARGV ] ]
+{
+    project-roots.print ;
+}
+
+if ! [ feature.values <toolset> ] 
+{
+    ECHO "warning: no toolsets are configured." ;
+    ECHO "warning: you won't be able to build C++ programs." ;
+    ECHO "warning: please consult the documentation." ;
+    ECHO ;
+}
+
+
+
+build-request = [ build-request.from-command-line [ modules.peek : ARGV ] ] ;
+
+properties = [ $(build-request).get-at 2 ] ;
+
+if $(properties) 
+{    
+    expanded = [ build-request.expand-no-defaults $(properties) ] ;
+    local xexpanded ;
+    for local e in $(expanded)
+    {
+        xexpanded += [ property-set.create [ feature.split $(e) ] ] ;
+    }
+    expanded = $(xexpanded) ;    
+}
+
+
+local target-ids = [ $(build-request).get-at 1 ] ;
+local targets
+local clean ;
+
+
+if "--clean" in [ modules.peek : ARGV ]
+{
+    clean = true ;
+}
+
+for local id in $(target-ids)
+{
+    if $(id) = clean
+    {
+        clean = true ;
+    }
+    else
+    {
+        local t = [ targets.find $(id) : $(current-project) ] ;
+        if ! $(t)
+        {
+            error target $(id) does not exist ;
+        }
+        else
+        {
+            targets += $(t) ;
+        }                
+    }    
+}
+
+if ! $(targets)
+{
+    targets += [ project.target [ project.module-name "." ] ] ; 
+}
+
+virtual-targets = ;
+
+if $(expanded) 
+{        
+    for local p in $(expanded)
+    {
+        for local t in $(targets)
+        {   
+            local g = [ $(t).generate $(p) ] ;
+            virtual-targets += $(g[2-]) ;
+        }        
+    }
+}
+else
+{
+    for local t in $(targets)
+    {        
+        local g = [ $(t).generate [ property-set.empty ] ] ;
+        virtual-targets += $(g[2-]) ;
+    }    
+}
+
+
+actual-targets = ;
+for t in $(virtual-targets)
+{
+    actual-targets += [ $(t).actualize ] ;
+}
+NOTFILE all ;
+DEPENDS all : $(actual-targets) ;
+
+if $(clean)
+{
+    UPDATE clean ;
+}
+else
+{
+    UPDATE all ;
+}
+
+
+


Property changes on: boost-jam/boost-build/branches/upstream/current/build-system.jam
___________________________________________________________________
Name: svn:executable
   + 

Added: boost-jam/boost-build/branches/upstream/current/debian/boost-build.docs
===================================================================
--- boost-jam/boost-build/branches/upstream/current/debian/boost-build.docs	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/debian/boost-build.docs	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,4 @@
+boost_build_v2.html
+index_v2.html
+boost.png
+doc
\ No newline at end of file

Added: boost-jam/boost-build/branches/upstream/current/debian/boost-build.examples
===================================================================
--- boost-jam/boost-build/branches/upstream/current/debian/boost-build.examples	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/debian/boost-build.examples	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1 @@
+example/*
\ No newline at end of file

Added: boost-jam/boost-build/branches/upstream/current/debian/changelog
===================================================================
--- boost-jam/boost-build/branches/upstream/current/debian/changelog	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/debian/changelog	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,6 @@
+boost-build (2.0.m10-1) unstable; urgency=low
+
+  * Initial Release.
+
+ -- Vladimir Prus <ghost at cs.msu.su>  Wed, 14 Aug 2002 14:08:00 +0400
+

Added: boost-jam/boost-build/branches/upstream/current/debian/conffiles
===================================================================
--- boost-jam/boost-build/branches/upstream/current/debian/conffiles	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/debian/conffiles	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1 @@
+/etc/site-config.jam

Added: boost-jam/boost-build/branches/upstream/current/debian/control
===================================================================
--- boost-jam/boost-build/branches/upstream/current/debian/control	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/debian/control	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,13 @@
+Source: boost-build
+Section: devel
+Priority: optional
+Maintainer: Vladimir Prus <ghost at cs.msu.su>
+Build-Depends: debhelper (>> 3.0.0), docbook-to-man, bison
+Standards-Version: 3.5.2
+
+Package: boost-build
+Architecture: all
+Depends: ${shlibs:Depends}, bjam (>> 3.1.9-1)
+Description: Build system
+ Boost.Build is a build system with a simple and high-level language.   
+ It supports build variants, and several different compilers and tools. 

Added: boost-jam/boost-build/branches/upstream/current/debian/copyright
===================================================================

Added: boost-jam/boost-build/branches/upstream/current/debian/excludes
===================================================================
--- boost-jam/boost-build/branches/upstream/current/debian/excludes	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/debian/excludes	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,14 @@
+boost.css
+boost_build_v2.html
+index_v2.html
+boost.png
+generators_prototype.py
+hacking.txt
+release_procedure.txt
+site-config.jam
+roll.sh
+debian
+doc
+example
+test
+CVS
\ No newline at end of file

Added: boost-jam/boost-build/branches/upstream/current/debian/rules
===================================================================
--- boost-jam/boost-build/branches/upstream/current/debian/rules	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/debian/rules	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,56 @@
+#!/usr/bin/make -f
+# Sample debian/rules that uses debhelper.
+# This file is public domain software, originally written by Joey Hess. 
+
+# Uncomment this to turn on verbose mode.
+#export DH_VERBOSE=1
+
+build:
+clean:
+binary-arch: 
+
+binary-indep: 
+	dh_testdir
+	dh_testroot
+
+	dh_clean -k
+	dh_installdirs usr/share/boost-build etc
+
+	# Add here commands to install the package into debian/<packagename>
+	(tar --exclude-from debian/excludes -cpf - * ) | (cd `pwd`/debian/tmp/usr/share/boost-build && tar xpf - )
+	chmod a-x -R `pwd`/debian/tmp/usr/share/boost-build
+
+	dh_installchangelogs
+	dh_installdocs -XCVS
+	mv `pwd`/debian/tmp/usr/share/doc/boost-build/index_v2.html `pwd`/debian/tmp/usr/share/doc/boost-build/index.html 
+
+	(tar --exclude make --exclude CVS -cpf - example/* ) | ( cd `pwd`/debian/tmp/usr/share/doc/boost-build && tar xpf - )
+
+	sed 's/#  using gcc/using gcc/' user-config.jam > `pwd`/debian/tmp/etc/site-config.jam
+
+#	dh_install
+#	dh_installmenu
+#	dh_installdebconf	
+#	dh_installlogrotate
+#	dh_installemacsen
+#	dh_installcatalogs
+#	dh_installpam
+#	dh_installmime
+#	dh_installinit
+#	dh_installcron
+#	dh_installinfo
+#	dh_undocumented
+	dh_installman
+	dh_link
+	dh_compress
+	dh_fixperms
+#	dh_perl
+#	dh_python
+#	dh_makeshlibs
+	dh_installdeb
+	dh_gencontrol
+	dh_md5sums
+	dh_builddeb
+
+binary: binary-indep binary-arch
+.PHONY: build clean binary-indep binary-arch binary install


Property changes on: boost-jam/boost-build/branches/upstream/current/debian/rules
___________________________________________________________________
Name: svn:executable
   + 

Added: boost-jam/boost-build/branches/upstream/current/doc/Jamfile.v2
===================================================================
--- boost-jam/boost-build/branches/upstream/current/doc/Jamfile.v2	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/doc/Jamfile.v2	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,19 @@
+
+project tools/build/v2/doc 
+    ;
+
+boostbook userman : src/userman.xml 
+   : <xsl:param>toc.section.depth=1
+     <xsl:param>doc.standalone=true 
+     <xsl:param>nav.layout=none
+   ;
+   
+if ! $(BOOST_ROOT)
+{   
+    BOOST_ROOT = [ modules.peek : BOOST_ROOT ] ;   
+}    
+      
+# Copy stylesheet and images from 'official' docs location
+stage html : $(BOOST_ROOT)/doc/html/boostbook.css ;
+stage html/images
+    : [ path.glob $(BOOST_ROOT)/doc/html/images : *.png ] ;

Added: boost-jam/boost-build/branches/upstream/current/doc/catalog.xml
===================================================================
--- boost-jam/boost-build/branches/upstream/current/doc/catalog.xml	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/doc/catalog.xml	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<!DOCTYPE catalog 
+  PUBLIC "-//OASIS/DTD Entity Resolution XML Catalog V1.0//EN"
+  "http://www.oasis-open.org/committees/entity/release/1.0/catalog.dtd">
+<catalog xmlns="urn:oasis:names:tc:entity:xmlns:xml:catalog">
+  <rewriteURI uriStartString="http://www.boost.org/tools/boostbook/dtd/" rewritePrefix="file:///home/ghost/Work/boost/tools/boostbook/dtd//"/>
+  <rewriteURI uriStartString="http://docbook.sourceforge.net/release/xsl/current/" rewritePrefix="file:///home/ghost/build/docbook/xsl/"/>
+  <rewriteURI uriStartString="http://www.oasis-open.org/docbook/xml/4.2/" rewritePrefix="file:///home/ghost/build/docbook/dtd/"/>
+</catalog>

Added: boost-jam/boost-build/branches/upstream/current/doc/development_plan.html
===================================================================
--- boost-jam/boost-build/branches/upstream/current/doc/development_plan.html	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/doc/development_plan.html	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,125 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+
+<html>
+  <head>
+    <meta name="generator" content=
+    "HTML Tidy for Linux/x86 (vers 1st April 2002), see www.w3.org">
+    <meta name="generator" content="Microsoft FrontPage 5.0">
+    <meta http-equiv="Content-Type" content=
+    "text/html; charset=windows-1252">
+    <!-- tidy options: &dash;&dash;tidy-mark false -i -wrap 78 !-->
+
+    <title>Boost Build System V2</title>
+  </head>
+
+  <body bgcolor="#FFFFFF" text="#000000">
+    <img src="../../../../boost.png" alt="boost.png (6897 bytes)" align="center"
+    width="277" height="86"> <!-- sf logo -->
+     
+
+    <h1>Boost Build Development Plan</h1>
+
+    <ul>
+      <li>
+        <b>Milestone 2</b> (October 25, 2002) 
+
+        <p>Boost buildable with gcc and also usable as part of another
+        project.</p>
+      </li>
+
+      <li>
+        <b>Milestone 3</b> (May 21, 2003) 
+
+        <p>Two gcc versions and two other compilers are supported. Some other
+        tools (e.g. lex and BoostBook) are implemented.</p>
+      </li>
+
+      <li>
+        <b>Milestone 4</b> (June 18, 2003) 
+
+        <p>More tools implemented.</p>
+      </li>
+
+      <li>
+        <b>Milestone 5</b> (Jule 2, 2003) 
+
+        <p>Improvements and bugfixes with dependency scanning. Support for
+        i18n tools. Testing framework for Boost.</p>
+      </li>
+
+      <li>
+        <b>Milestone 6</b> (Jule 22, 2003)
+
+        <p>Bugfixes.</p>
+      </li>
+
+      <li>
+        <b>Milestone 7</b> (Aug 1, 2003)
+
+        <p>Optimizations.</p>
+      </li>
+
+      <li>
+        <b>Milestone 8</b> (Oct 15, 2003)
+
+        <p>Implementation of regression testing framework was
+          implemented. Handling of dependencies to generated headers was
+          optimized. Algorithms for link-compatibility checking and selecting
+          main target alternatives were improved.</p>
+      </li>
+
+      <li>
+        <b>Milestone 9.1</b> (Nov 06, 2003)
+
+        <p>Performance was considerably improved. The syntax for linking a
+        library into a library was simplified. The 'stage' rule can traverse
+        dependencies of the targets it installs. Regression testing support
+        now works on Windows. Some toolsets were improved. Bugs in project
+        loading and suffix determination were fixed.
+      </li>
+
+      <li>
+        <b>Milestone 10</b> (TBD)
+
+        <p>Remaining features for <a href="http://boost.org">C++ Boost</a>:
+        improved installation, Python support. Uniform toolset initialization
+        scheme. Many bugfixes</p>
+      </li>
+
+      
+      <li>
+        <b>Alpha</b> (TBD) 
+
+        <p>Optimization. Using buildable tools: consider using bison, which
+        is itself built with Boost.Build.</p>
+      </li>
+
+      <li>
+        <b>Beta</b> (TBD) 
+
+        <p>Feature-complete milestone.</p>
+      </li>
+
+      <li>
+        <b>2.0 Release</b> (TBD) 
+
+        <p>Bugfixes</p>
+      </li>
+    </ul>
+    <hr>
+
+    <p>&copy; Copyright Vladimir Prus 2002-2003. Permission to copy, use,
+    modify, sell and distribute this document is granted provided this
+    copyright notice appears in all copies. This document is provided "as is"
+    without express or implied warranty, and with no claim as to its
+    suitability for any purpose.</p>
+
+    <p>Revised 
+    <!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %B, %Y" startspan
+                                        -->23 Aug, 2004 
+    <!--webbot bot="Timestamp" endspan i-checksum="13972"
+                                        -->
+    </p>
+  </body>
+</html>
+

Added: boost-jam/boost-build/branches/upstream/current/doc/html/HTML.manifest
===================================================================
--- boost-jam/boost-build/branches/upstream/current/doc/html/HTML.manifest	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/doc/html/HTML.manifest	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,41 @@
+index.html
+bbv2/howto.html
+bbv2/installation.html
+bbv2/tutorial.html
+bbv2/tutorial/properties.html
+bbv2/tutorial/hierarchy.html
+bbv2/tutorial/libs.html
+bbv2/tutorial/depends.html
+bbv2/tutorial/linkage.html
+bbv2/tutorial/conditions.html
+bbv2/tutorial/prebuilt.html
+bbv2/advanced.html
+bbv2/advanced/jamfiles.html
+bbv2/advanced/build_process.html
+bbv2/advanced/builtins/targets.html
+bbv2/advanced/builtins/features.html
+bbv2/advanced/differences_to_v1.html
+bbv2/extender.html
+bbv2/extending/targets.html
+bbv2/extending/tools.html
+bbv2/extending/features.html
+bbv2/extending/rules.html
+bbv2/extending/toolset_modules.html
+bbv2/reference.html
+bbv2/reference/jamfiles.html
+bbv2/reference/buildprocess.html
+bbv2/reference/definitions.html
+bbv2/reference/generators.html
+bbv2/faq.html
+bbv2/faq/s02.html
+bbv2/faq/s03.html
+bbv2/faq/s04.html
+bbv2/faq/external.html
+bbv2/faq/s06.html
+bbv2/faq/s07.html
+bbv2/faq/dll-path.html
+bbv2/recipies/site-config.html
+bbv2/arch.html
+bbv2/arch/build.html
+bbv2/arch/tools.html
+bbv2/arch/targets.html

Added: boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/advanced/build_process.html
===================================================================
--- boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/advanced/build_process.html	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/advanced/build_process.html	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,168 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+<title>Build process</title>
+<link rel="stylesheet" href="../../boostbook.css" type="text/css">
+<meta name="generator" content="DocBook XSL Stylesheets V1.61.3">
+<link rel="home" href="../../index.html" title="Part I. Boost.Build v2 User Manual">
+<link rel="up" href="../advanced.html" title="Chapter 4. User documentation">
+<link rel="previous" href="jamfiles.html" title="Writing Jamfiles">
+<link rel="next" href="builtins/targets.html" title="Builtin target types">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<table cellpadding="2" width="100%"><td valign="top"><img alt="boost.png (6897 bytes)" width="277" height="86" src="../../../../boost.png"></td></table>
+<hr>
+<div class="spirit-nav">
+<a accesskey="p" href="jamfiles.html"><img src="../../images/prev.png" alt="Prev"></a><a accesskey="u" href="../advanced.html"><img src="../../images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../images/home.png" alt="Home"></a><a accesskey="n" href="builtins/targets.html"><img src="../../images/next.png" alt="Next"></a>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div><div><h2 class="title" style="clear: both">
+<a name="bbv2.advanced.build_process"></a>Build process</h2></div></div>
+<div></div>
+</div>
+<div class="toc"><dl>
+<dt><a href="build_process.html#id2536467">Build request</a></dt>
+<dt><a href="build_process.html#id2536509">Building a main target</a></dt>
+<dt><a href="build_process.html#id2536623">Building a project</a></dt>
+</dl></div>
+<p>When you've described your targets, you want Boost.Build to run the
+      right tools and create the needed targets. This section will describe
+      two things: how you specify what to build, and how the main targets are
+      actually constructed.
+    </p>
+<p>The most important thing to note is that in Boost.Build, unlike
+      other build tools, the targets you declare do not correspond to specific
+      files. What you declare in Jamfiles is more like "metatarget". Depending
+      on the properties that you specify on the command line, each
+      "metatarget" will produce a set of real targets corresponding to the
+      requested properties. It is quite possible that the same metatarget is
+      build several times with different properties, and will, of course,
+      produce different files.
+    </p>
+<div class="tip" style="margin-left: 0.5in; margin-right: 0.5in;">
+<h3 class="title">Tip</h3>
+<p>
+        This means that for Boost.Build, you cannot directly obtain build
+        variant from Jamfile. There could be several variants requested by the
+        user, and each target can be build with different properties. 
+      </p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div><div><h3 class="title">
+<a name="id2536467"></a>Build request</h3></div></div>
+<div></div>
+</div>
+<p>
+        The command line specifies which targets to build and with what
+        properties. For example:
+</p>
+<pre class="programlisting">
+bjam app1 lib1//lib1 toolset=gcc variant=debug optimization=full
+</pre>
+<p>
+        would build two targets, "app1" and "lib1//lib1" with the specified
+        properties. You can refer to any targets, using 
+        <a href="../reference/definitions.html#bbv2.reference.ids" title="Target identifiers and references">target id</a> and specify arbitrary
+        properties. Some of the properties are very common, and for them the name
+        of the property can be omitted. For example, the above can be written as:
+</p>
+<pre class="programlisting">
+bjam app1 lib1//lib1 gcc debug optimization=full
+</pre>
+<p>
+        The complete syntax which has some additional shortcuts if described <a href="../reference.html#bbv2.reference.commandline" title="Command line">here</a>.
+      </p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div><div><h3 class="title">
+<a name="id2536509"></a>Building a main target</h3></div></div>
+<div></div>
+</div>
+<p>When you request, directly or indirectly, a build of a main target
+        with specific requirements, the following steps are made. Some brief
+        explanation is provided, and more detailes are given in the <a href="../reference/buildprocess.html" title="Build process">reference</a>.
+        </p>
+<div class="orderedlist"><ol type="1">
+<li><p>Applying default build. If the default-build
+          property of a target specifies a value of a feature which is not
+          present in the build request, that value is added.</p></li>
+<li><p>Selecting the main target alternative to use. For
+              each alternative we look how many properties are present both in
+              alternative's requirements, and in build request. The
+              alternative with large number of matching properties is selected.
+            </p></li>
+<li><p>Determining "common" properties. The build request
+              is <a href="../reference/definitions.html#bbv2.reference.variants.proprefine" title="Property refinement">refined</a>
+              with target's requirements. The conditional properties in
+              requirements are handled as well. Finally, default values of
+              features are added.
+            </p></li>
+<li><p>Building targets referred by the sources list and
+              dependency properties. The list of sources and the properties
+              can refer to other target using <a href="../reference/definitions.html#bbv2.reference.ids" title="Target identifiers and references">target references</a>. For each
+              reference, we take all <a href="../reference/definitions.html#bbv2.reference.features.attributes.propagated">propagated</a>
+              properties, refine them by explicit properties specified in the
+              target reference, and pass the resulting properties as build
+              request to the other target.              
+            </p></li>
+<li><p>Adding the usage requirements produces when building
+              dependencies to the "common" properties. When dependencies are
+              built in the previous step, they return both the set of created
+              "real" targets, and usage requirements. The usage requirements
+              are added to the common properties and the resulting property
+              set will be used for building the current target.              
+            </p></li>
+<li><p>Building the target using generators. To convert the
+              sources to the desired type, Boost.Build uses "generators" ---
+              objects which correspond to tools like compilers and
+              linkers. Each generator declares what type of targets in can
+              produce and what type of sources it requires. Using this
+              information, Boost.Build determines which generators must be run
+              to produce a specific target from specific sources. When
+              generators are run, they return the "real" targets.
+            </p></li>
+<li><p>Computing the usage requirements to be returned. The
+          conditional properties in usage requirements are expanded and the
+          result is returned.</p></li>
+</ol></div>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div><div><h3 class="title">
+<a name="id2536623"></a>Building a project</h3></div></div>
+<div></div>
+</div>
+<p>Often, user request a build of a complete project, not just one
+        main target. In fact, invoking <b class="command">bjam</b> without
+        parameters builds the project defined in the current directory.</p>
+<p>When a project is build, the build request is passed without
+        modification to all main targets in that project. It's is possible to
+        prevent implicit building of a target in a project with the
+        <tt class="computeroutput">explicit</tt> rule:
+</p>
+<pre class="programlisting">
+explicit hello_test ;
+</pre>
+<p>
+        would cause the <tt class="computeroutput">hello_test</tt> target to be built only if
+        explicitly requested by the user or by some other target.
+      </p>
+<p>The Jamfile for a project can include a number of
+      <tt class="computeroutput">build-project</tt> rule calls, that specify additional projects
+      to be built.
+      </p>
+</div>
+</div>
+<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
+<td align="left"></td>
+<td align="right"><small></small></td>
+</tr></table>
+<hr>
+<div class="spirit-nav">
+<a accesskey="p" href="jamfiles.html"><img src="../../images/prev.png" alt="Prev"></a><a accesskey="u" href="../advanced.html"><img src="../../images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../images/home.png" alt="Home"></a><a accesskey="n" href="builtins/targets.html"><img src="../../images/next.png" alt="Next"></a>
+</div>
+</body>
+</html>

Added: boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/advanced/builtins/features.html
===================================================================
--- boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/advanced/builtins/features.html	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/advanced/builtins/features.html	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,119 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+<title>Builtin features</title>
+<link rel="stylesheet" href="../../../boostbook.css" type="text/css">
+<meta name="generator" content="DocBook XSL Stylesheets V1.61.3">
+<link rel="home" href="../../../index.html" title="Part I. Boost.Build v2 User Manual">
+<link rel="up" href="../../advanced.html" title="Chapter 4. User documentation">
+<link rel="previous" href="targets.html" title="Builtin target types">
+<link rel="next" href="../differences_to_v1.html" title="Differences to Boost.Build V1">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<table cellpadding="2" width="100%"><td valign="top"><img alt="boost.png (6897 bytes)" width="277" height="86" src="../../../../../boost.png"></td></table>
+<hr>
+<div class="spirit-nav">
+<a accesskey="p" href="targets.html"><img src="../../../images/prev.png" alt="Prev"></a><a accesskey="u" href="../../advanced.html"><img src="../../../images/up.png" alt="Up"></a><a accesskey="h" href="../../../index.html"><img src="../../../images/home.png" alt="Home"></a><a accesskey="n" href="../differences_to_v1.html"><img src="../../../images/next.png" alt="Next"></a>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div><div><h2 class="title" style="clear: both">
+<a name="bbv2.advanced.builtins.features"></a>Builtin features</h2></div></div>
+<div></div>
+</div>
+<div class="variablelist"><dl>
+<dt><span class="term"><tt class="literal">variant</tt></span></dt>
+<dd>
+<p>
+            The feature which combines several low-level features in
+            order to make building most common variants simple.
+          </p>
+<p><span class="bold"><b>Allowed values:</b></span><tt class="literal">debug</tt>, <tt class="literal">release</tt>,
+            <tt class="literal">profile</tt></p>
+<p>The value <tt class="literal">debug</tt> expands to</p>
+<pre class="programlisting">
+            &lt;optimization&gt;off &lt;debug-symbols&gt;on &lt;inlining&gt;off &lt;runtime-debugging&gt;on
+          </pre>
+<p>The value <tt class="literal">release</tt> expands to</p>
+<pre class="programlisting">
+            &lt;optimization&gt;speed &lt;debug-symbols&gt;off &lt;inlining&gt;full &lt;runtime-debugging&gt;off
+          </pre>
+<p>The value <tt class="literal">profile</tt> expands to the same as
+            <tt class="literal">release</tt>, plus:</p>
+<pre class="programlisting">
+            &lt;profiling&gt;on &lt;debug-symbols&gt;on
+          </pre>
+<p><span class="bold"><b>Rationale:</b></span> Runtime debugging is on in debug build
+            to suit expectations of people used various IDEs. It's
+            assumed other folks don't have any specific expectation in
+            this point.</p>
+</dd>
+<dt>
+<a name="bbv2.advanced.builtins.features.link"></a><span class="term"><tt class="literal">link</tt></span>
+</dt>
+<dd>
+<p>
+            Feature which controls how libraries are built.
+          </p>
+<p><span class="bold"><b>Allowed values:</b></span><tt class="literal">shared</tt>,
+            <tt class="literal">static</tt></p>
+</dd>
+<dt><span class="term"><tt class="literal">source</tt></span></dt>
+<dd>
+            Tthe &lt;source&gt;X feature has the same effect on building a target
+            as putting X in the list of sources. The feature
+            is sometimes more convenient: you can put &lt;source&gt;X in
+            the requirements for a project and it will be linked to all
+            executables.
+          </dd>
+<dt><span class="term"><tt class="literal">library</tt></span></dt>
+<dd>
+            This feature is equivalent to the &lt;source&gt; feature, and exists
+            for backward compatibility reasons.
+          </dd>
+<dt><span class="term"><tt class="literal">use</tt></span></dt>
+<dd>
+            Causes the target referenced by the value of this feature
+            to be constructed and adds it's usage requirements to build
+            properties. The constructed targets are not used in any other
+            way. The primary use case is when you use some library and want
+            it's usage requirements (such as include paths) to be applied,
+            but don't want to link to the library.
+          </dd>
+<dt><span class="term"><tt class="literal">dll-path</tt></span></dt>
+<dd>
+            Specify an additional path where shared libraries should be
+            searched where the executable or shared library is run. This
+            feature only affect Unix compilers. Plase see the <a href="../../faq/dll-path.html" title="Why are the dll-path and
+    hardcode-dll-paths properties useful?
+    ">FAQ entry</a> for details.
+          </dd>
+<dt><span class="term"><tt class="literal">hardcode-dll-paths</tt></span></dt>
+<dd>
+<p>
+            Controls automatic generation of dll-path properties.
+          </p>
+<p><span class="bold"><b>Allowed values:</b></span><tt class="literal">true</tt>, <tt class="literal">false</tt>.  This property
+            is specific to Unix systems. If an executable is build with
+            <tt class="computeroutput">&lt;hardcode-dll-paths&gt;true</tt>, the generated binary
+            will contain the list of all the paths to the used shared
+            libraries. As the result, the executable can be run without
+            changing system paths to shared libraries, or installing the
+            libraries to system paths. This is very convenient during
+            development. Plase see the <a href="../../faq/dll-path.html" title="Why are the dll-path and
+    hardcode-dll-paths properties useful?
+    ">FAQ entry</a> for details.
+          </p>
+</dd>
+</dl></div>
+</div>
+<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
+<td align="left"></td>
+<td align="right"><small></small></td>
+</tr></table>
+<hr>
+<div class="spirit-nav">
+<a accesskey="p" href="targets.html"><img src="../../../images/prev.png" alt="Prev"></a><a accesskey="u" href="../../advanced.html"><img src="../../../images/up.png" alt="Up"></a><a accesskey="h" href="../../../index.html"><img src="../../../images/home.png" alt="Home"></a><a accesskey="n" href="../differences_to_v1.html"><img src="../../../images/next.png" alt="Next"></a>
+</div>
+</body>
+</html>

Added: boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/advanced/builtins/targets.html
===================================================================
--- boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/advanced/builtins/targets.html	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/advanced/builtins/targets.html	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,321 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+<title>Builtin target types</title>
+<link rel="stylesheet" href="../../../boostbook.css" type="text/css">
+<meta name="generator" content="DocBook XSL Stylesheets V1.61.3">
+<link rel="home" href="../../../index.html" title="Part I. Boost.Build v2 User Manual">
+<link rel="up" href="../../advanced.html" title="Chapter 4. User documentation">
+<link rel="previous" href="../build_process.html" title="Build process">
+<link rel="next" href="features.html" title="Builtin features">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<table cellpadding="2" width="100%"><td valign="top"><img alt="boost.png (6897 bytes)" width="277" height="86" src="../../../../../boost.png"></td></table>
+<hr>
+<div class="spirit-nav">
+<a accesskey="p" href="../build_process.html"><img src="../../../images/prev.png" alt="Prev"></a><a accesskey="u" href="../../advanced.html"><img src="../../../images/up.png" alt="Up"></a><a accesskey="h" href="../../../index.html"><img src="../../../images/home.png" alt="Home"></a><a accesskey="n" href="features.html"><img src="../../../images/next.png" alt="Next"></a>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div><div><h2 class="title" style="clear: both">
+<a name="bbv2.advanced.builtins.targets"></a>Builtin target types</h2></div></div>
+<div></div>
+</div>
+<div class="toc"><dl>
+<dt><a href="targets.html#id2536681">Programs</a></dt>
+<dt><a href="targets.html#id2536744">Libraries</a></dt>
+<dt><a href="targets.html#bbv2.builtins.alias">Alias</a></dt>
+<dt><a href="targets.html#bbv2.builtins.stage">Installing</a></dt>
+<dt><a href="targets.html#bbv2.builtins.testing">Testing</a></dt>
+</dl></div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div><div><h3 class="title">
+<a name="id2536681"></a>Programs</h3></div></div>
+<div></div>
+</div>
+<p>Programs are created using the <tt class="computeroutput">exe</tt> rule, which
+        follows the <a href="../jamfiles.html#bbv2.main-target-rule-syntax">common
+          syntax</a>. For example:
+</p>
+<pre class="programlisting">
+exe hello : hello.cpp some_library.lib /some_project//library 
+          : &lt;threading&gt;multi 
+          ;
+</pre>
+<p>
+        This will create an executable file from the sources -- in this case,
+        one C++ file, one library file present in the same directory, and
+        another library which is created by Boost.Build. Generally, sources
+        can include C and C++ files, object files and libraries. Boost.Build
+        will automatically try to convert targets of other types.
+      </p>
+<div class="tip" style="margin-left: 0.5in; margin-right: 0.5in;">
+<h3 class="title">Tip</h3>
+<p>         
+          On Windows, if an application uses dynamic libraries, and both
+          the application and the libraries are built by Boost.Build, its not
+          possible to immediately run the application, because the
+          <tt class="literal">PATH</tt> environment variable should include the path
+          to the libraries. It means you have to either add the paths
+          manually, or place the application and the libraries to the same
+          directory, for example using the <a href="targets.html#bbv2.builtins.stage" title="Installing">
+            stage</a> rule.
+      </p>
+</div>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div><div><h3 class="title">
+<a name="id2536744"></a>Libraries</h3></div></div>
+<div></div>
+</div>
+<p>Libraries are created using the <tt class="computeroutput">lib</tt> rule, which
+        follows the <a href="../jamfiles.html#bbv2.main-target-rule-syntax">common
+          syntax</a>. For example:
+</p>
+<pre class="programlisting">
+lib helpers : helpers.cpp : &lt;include&gt;boost : : &lt;include&gt;. ;
+</pre>
+<p>In the most common case, the <tt class="computeroutput">lib</tt> creates a library
+        from the specified sources. Depending on the value of
+        &lt;link&gt; feature the library will be either static or
+        shared. There are two other cases. First is when the library is
+        installed somewhere in compiler's search paths, and should be
+        searched by the compiler (typically, using the <tt class="option">-l</tt>
+        option). The second case is where the library is available as a 
+        prebuilt file and the full path is known.          
+        </p>
+<p>
+        The syntax for these case is given below:
+</p>
+<pre class="programlisting">
+lib z : : &lt;name&gt;z &lt;search&gt;/home/ghost ;            
+lib compress : : &lt;file&gt;/opt/libs/compress.a ;
+</pre>
+<p>
+        The <tt class="computeroutput">name</tt> property specifies the name which should be
+        passed to the <tt class="option">-l</tt> option, and the <tt class="computeroutput">file</tt>
+        property specifies the file location. The <tt class="computeroutput">search</tt> feature
+        specifies paths where the library should be searched. That feature can
+        be specified several time, or can be omitted -- in which case only
+        default compiler paths will be searched.
+      </p>
+<p>The difference between using the <tt class="computeroutput">file</tt> feature as
+        opposed to the <tt class="computeroutput">name</tt> name feature together with the
+        <tt class="computeroutput">search</tt> feature is that <tt class="computeroutput">file</tt> is more
+        precise. A specific file will be used. On the other hand, the
+        <tt class="computeroutput">search</tt> feature only adds a library path, and the
+        <tt class="computeroutput">name</tt> feature gives the basic name of the library. The
+        search rules are specific to the linker. For example, given these
+        definition:
+</p>
+<pre class="programlisting">
+lib a : : &lt;variant&gt;release &lt;file&gt;/pool/release/a.so ;
+lib a : : &lt;variant&gt;debug &lt;file&gt;/pool/debug/a.so ;
+lib b : : &lt;variant&gt;release &lt;file&gt;/pool/release/b.so ;
+lib b : : &lt;variant&gt;debug &lt;file&gt;/pool/debug/b.so ;
+</pre>
+<p>
+        It's possible to use release version of <tt class="computeroutput">a</tt> and debug
+        version of <tt class="computeroutput">b</tt>. Had we used the <tt class="computeroutput">name</tt> and
+        <tt class="computeroutput">search</tt> features, the linker would always pick either
+        release or debug versions.
+      </p>
+<p>
+        For convenience, the following syntax is allowed:
+</p>
+<pre class="programlisting">
+lib z ;
+lib gui db aux ;
+</pre>
+<p>
+          and is does exactly the same as:
+</p>
+<pre class="programlisting">
+lib z : : &lt;name&gt;z ;            
+lib giu : : &lt;name&gt;gui ;            
+lib db : : &lt;name&gt;db ;            
+lib aux : : &lt;name&gt;aux ;            
+</pre>
+<p>When a library uses another library you should put that another
+        library in the list of sources. This will do the right thing in all
+        cases. For portability, you should specify library dependencies even
+        for searched and prebuilt libraries, othewise, static linking on
+        Unix won't work. For example:
+</p>
+<pre class="programlisting">
+lib z ;
+lib png : z : &lt;name&gt;png ;
+</pre>
+<div class="note" style="margin-left: 0.5in; margin-right: 0.5in;">
+<h3 class="title">Note</h3>
+<p>When a library (say, <tt class="computeroutput">a</tt>), which has another
+          library, (say, <tt class="computeroutput">b</tt>) is linked dynamically, the <tt class="computeroutput">b</tt>
+          library will be incorporated in <tt class="computeroutput">a</tt>. (If <tt class="computeroutput">b</tt>
+          is dynamic library as well, then <tt class="computeroutput">a</tt> will only refer to
+          it, and not include any extra code.) When the <tt class="computeroutput">a</tt>
+          library is linked statically, Boost.Build will assure that all
+          executables which link to <tt class="computeroutput">a</tt> will also link to
+          <tt class="computeroutput">b</tt>.
+        </p>
+</div>
+<p>One feature of Boost.Build which is very important for libraries
+        is usage requirements. For example, if you write:
+</p>
+<pre class="programlisting">
+lib helpers : helpers.cpp : : : &lt;include&gt;. ;
+</pre>
+<p>
+        then compiler include path for all targets which use
+        <tt class="computeroutput">helpers</tt> will contain the directory where the target is
+        defined.path to "helpers.cpp". So, the user need only to add
+        <tt class="computeroutput">helpers</tt> to the list of sources, and don't bother about
+        other requirements. This allows to greatly simplify Jamfiles.
+      </p>
+<div class="note" style="margin-left: 0.5in; margin-right: 0.5in;">
+<h3 class="title">Note</h3>
+<p>If you don't want shared libraries to include all libraries
+          which are specified in sources (especially statically linked ones),
+          you'd need to use the following:
+</p>
+<pre class="programlisting">
+lib b : a.cpp ;
+lib a : a.cpp : &lt;use&gt;b : : &lt;library&gt;b ;
+</pre>
+<p>
+          This specifies that <tt class="computeroutput">a</tt> uses <tt class="computeroutput">b</tt>, and causes
+          all executables which link to <tt class="computeroutput">a</tt> also link to
+          <tt class="computeroutput">b</tt>. In this case, even for shared linking, the
+          <tt class="computeroutput">a</tt> library won't even refer to <tt class="computeroutput">b</tt>.
+        </p>
+</div>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div><div><h3 class="title">
+<a name="bbv2.builtins.alias"></a>Alias</h3></div></div>
+<div></div>
+</div>
+<p>The <tt class="computeroutput">alias</tt> rule follows the <a href="../jamfiles.html#bbv2.main-target-rule-syntax">common syntax</a>. For
+        example:
+</p>
+<pre class="programlisting">
+alias core : im reader writer ;
+</pre>
+<p>
+        will build the sources and return the generated source targets
+        without modification. 
+      </p>
+<p>
+        The <tt class="computeroutput">alias</tt> rule is a convenience tool. If you often build
+        the same group of targets at the same time, you can define the alias
+        to save typing.        
+      </p>
+<p>
+        Another use of the <tt class="computeroutput">alias</tt> rule is to change build
+        properties. For example, if you always want static linking for a
+        specific C++ Boost library, you can write the following:
+</p>
+<pre class="programlisting">
+alias boost_thread : /boost/thread//boost_thread : &lt;link&gt;static ;
+</pre>
+<p>
+        and use only the <tt class="computeroutput">boost_thread</tt> alias in your Jamfiles.
+      </p>
+<p>
+        It is also allowed to specify usage requirements for the
+        <tt class="computeroutput">alias</tt> target. If you write the following:
+</p>
+<pre class="programlisting">
+alias header_only_library : : : :  &lt;include&gt;/usr/include/header_only_library ; 
+</pre>
+<p>
+        then using <tt class="computeroutput">header_only_library</tt> in sources will only add an
+        include path. Also note that when there are some sources, their usage
+        requirements are propagated, too. For example:
+</p>
+<pre class="programlisting">
+lib lib : lib.cpp : : : &lt;include&gt;. ;
+alias lib_alias ;
+exe main : main.cpp lib_alias ;
+</pre>
+<p>
+        will compile <tt class="filename">main.cpp</tt> with the additional include.
+      </p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div><div><h3 class="title">
+<a name="bbv2.builtins.stage"></a>Installing</h3></div></div>
+<div></div>
+</div>
+<p>For installing the built target you should use the
+        <tt class="computeroutput">stage</tt> rule follows the <a href="../jamfiles.html#bbv2.main-target-rule-syntax">common syntax</a>. For
+        example:
+</p>
+<pre class="programlisting">
+stage dist : hello helpers ;
+</pre>
+<p>
+        will cause the targets <tt class="computeroutput">hello</tt> and <tt class="computeroutput">helpers</tt> to
+        be moved to the <tt class="filename">dist</tt> directory. The directory can
+        be changed with the <tt class="computeroutput">location</tt> property:
+</p>
+<pre class="programlisting">
+stage dist : hello helpers : &lt;location&gt;/usr/bin ;
+</pre>
+<p>
+        Specifying the names of all libraries to install can be boring. The
+        <tt class="computeroutput">stage</tt> allows to specify only the top-level executable
+        targets to install, and automatically install all dependencies:
+</p>
+<pre class="programlisting">
+stage dist : hello 
+           : &lt;traverse-dependencies&gt;on &lt;include-type&gt;EXE
+             &lt;include-type&gt;LIB
+           ;
+</pre>
+<p>
+        will find all targets that <tt class="computeroutput">hello</tt> depends on, and install
+        all of the which are either executables or libraries.
+      </p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div><div><h3 class="title">
+<a name="bbv2.builtins.testing"></a>Testing</h3></div></div>
+<div></div>
+</div>
+<p>Boost.Build has convenient support for running unit tests. The
+        simplest way is the <tt class="computeroutput">unit-test</tt> rule, which follows the
+        <a href="../jamfiles.html#bbv2.main-target-rule-syntax">common syntax</a>. For
+        example:
+</p>
+<pre class="programlisting">
+unit-test helpers_test : helpers_test.cpp helpers ;
+</pre>
+<p>The <tt class="computeroutput">unit-test</tt> rule behaves like the
+        <tt class="computeroutput">exe</tt> rule, but after the executable is created it is
+        run. If the executable returns error, the build system will also
+        return error and will try running the executable on the next
+        invocation until it runs successfully. This behaviour ensures that you
+        can't miss a unit test failure.
+      </p>
+<p>There are rules for more elaborate testing: <tt class="computeroutput">compile</tt>,
+        <tt class="computeroutput">compile-fail</tt>, <tt class="computeroutput">run</tt> and
+        <tt class="computeroutput">run-fail</tt>. They are more suitable for automated testing, and
+        are not covered here yet.
+      </p>
+</div>
+</div>
+<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
+<td align="left"></td>
+<td align="right"><small></small></td>
+</tr></table>
+<hr>
+<div class="spirit-nav">
+<a accesskey="p" href="../build_process.html"><img src="../../../images/prev.png" alt="Prev"></a><a accesskey="u" href="../../advanced.html"><img src="../../../images/up.png" alt="Up"></a><a accesskey="h" href="../../../index.html"><img src="../../../images/home.png" alt="Home"></a><a accesskey="n" href="features.html"><img src="../../../images/next.png" alt="Next"></a>
+</div>
+</body>
+</html>

Added: boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/advanced/differences_to_v1.html
===================================================================
--- boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/advanced/differences_to_v1.html	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/advanced/differences_to_v1.html	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,129 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+<title>Differences to Boost.Build V1</title>
+<link rel="stylesheet" href="../../boostbook.css" type="text/css">
+<meta name="generator" content="DocBook XSL Stylesheets V1.61.3">
+<link rel="home" href="../../index.html" title="Part I. Boost.Build v2 User Manual">
+<link rel="up" href="../advanced.html" title="Chapter 4. User documentation">
+<link rel="previous" href="builtins/features.html" title="Builtin features">
+<link rel="next" href="../extender.html" title="Chapter 5. Extender Manual">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<table cellpadding="2" width="100%"><td valign="top"><img alt="boost.png (6897 bytes)" width="277" height="86" src="../../../../boost.png"></td></table>
+<hr>
+<div class="spirit-nav">
+<a accesskey="p" href="builtins/features.html"><img src="../../images/prev.png" alt="Prev"></a><a accesskey="u" href="../advanced.html"><img src="../../images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../images/home.png" alt="Home"></a><a accesskey="n" href="../extender.html"><img src="../../images/next.png" alt="Next"></a>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div><div><h2 class="title" style="clear: both">
+<a name="bbv2.advanced.differences_to_v1"></a>Differences to Boost.Build V1</h2></div></div>
+<div></div>
+</div>
+<div class="toc"><dl>
+<dt><a href="differences_to_v1.html#bbv2.advanced.differences_to_v1.configuration">Configuration</a></dt>
+<dt><a href="differences_to_v1.html#bbv2.advanced.differences_to_v1.jamfiles">Writing Jamfiles</a></dt>
+<dt><a href="differences_to_v1.html#bbv2.advanced.differences_to_v1.build_process">Build process</a></dt>
+</dl></div>
+<p>While Boost.Build V2 is based on the same ideas as Boost.Build V1,
+    some of the syntax was changed, and some new important features were
+    added. This chapter describes most of the changes.</p>
+<div class="section" lang="en">
+<div class="titlepage">
+<div><div><h3 class="title">
+<a name="bbv2.advanced.differences_to_v1.configuration"></a>Configuration</h3></div></div>
+<div></div>
+</div>
+<p>In V1, there were two methods to configure a toolset. One is to
+      set some environment variable, or use "-s" command line option to set
+      variable inside BJam. Another method was creating new toolset module,
+      which would set the variables and then invoke basic toolset. Neither
+      method is necessary now, the "using" rule provides a consistent way to
+      initialize toolset, including several versions. See <a href="../advanced.html#bbv2.advanced.configuration" title="Configuration">section on configuraton</a> for
+      details.
+      </p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div><div><h3 class="title">
+<a name="bbv2.advanced.differences_to_v1.jamfiles"></a>Writing Jamfiles</h3></div></div>
+<div></div>
+</div>
+<p>Probably one of the most important differences in V2 Jamfiles is
+      the project requirements. In V1, if several targets have the same
+      requirements (for example, common include path), it was necessary to
+      manually write that requirements, or use a helper rule. In V2, the
+      common properties can be specified with the "requirements" project
+      attribute, as documented <a href="jamfiles.html#bbv2.advanced.projects" title="Projects">here</a>.
+      </p>
+<p>The <a href="../tutorial/libs.html" title="Libraries and Dependent Targets">usage requirements</a>
+      is also important mechanism to simplify Jamfile. If a library requires
+      all clients to use specific includes, or macros when compiling the
+      code which depends on the library, this information can be cleanly
+      represented.</p>
+<p>The difference between "lib" and "dll" targets in V1 is completely
+      eliminated in V2. There's only one target -- "lib", which can create
+      either static or shared library depending on the value of the 
+        <a href="builtins/features.html#bbv2.advanced.builtins.features.link">&lt;link&gt;
+      feature</a>. If your target should be only build in one variant, you
+      can add &lt;link&gt;shared or &lt;link&gt;static to requirements.
+      </p>
+<p>The syntax for referring to other targets was changed a bit. While
+      in V1 one would use:
+</p>
+<pre class="programlisting">
+exe a : a.cpp &lt;lib&gt;../foo/bar ;
+</pre>
+<p> 
+        the V2 syntax is:
+</p>
+<pre class="programlisting">
+exe a : a.cpp ../foo//bar ;
+</pre>
+<p>
+        Note that you don't need to specify the type of other target, but the
+        last element should be separated to double slash, to indicate that
+        you're referring to target "bar" in project "../foo", and not to
+        project "../foo/bar".
+        </p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div><div><h3 class="title">
+<a name="bbv2.advanced.differences_to_v1.build_process"></a>Build process</h3></div></div>
+<div></div>
+</div>
+<p>The command line syntax in V2 is completely different. For example
+</p>
+<pre class="programlisting">
+bjam -sTOOLS=msvc -sBUILD=release some_target
+</pre>
+<p>
+        now becomes:
+</p>
+<pre class="programlisting">
+bjam toolset=msvc variant=release some_target
+</pre>
+<p>
+        or, using shortcuts, just:
+</p>
+<pre class="programlisting">
+bjam msvc release some_target
+</pre>
+<p>
+      See <a href="../reference.html#bbv2.reference.commandline" title="Command line">the reference</a> for
+      complete description of the syntax.
+      </p>
+</div>
+</div>
+<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
+<td align="left"></td>
+<td align="right"><small></small></td>
+</tr></table>
+<hr>
+<div class="spirit-nav">
+<a accesskey="p" href="builtins/features.html"><img src="../../images/prev.png" alt="Prev"></a><a accesskey="u" href="../advanced.html"><img src="../../images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../images/home.png" alt="Home"></a><a accesskey="n" href="../extender.html"><img src="../../images/next.png" alt="Next"></a>
+</div>
+</body>
+</html>

Added: boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/advanced/jamfiles.html
===================================================================
--- boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/advanced/jamfiles.html	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/advanced/jamfiles.html	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,428 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+<title>Writing Jamfiles</title>
+<link rel="stylesheet" href="../../boostbook.css" type="text/css">
+<meta name="generator" content="DocBook XSL Stylesheets V1.61.3">
+<link rel="home" href="../../index.html" title="Part I. Boost.Build v2 User Manual">
+<link rel="up" href="../advanced.html" title="Chapter 4. User documentation">
+<link rel="previous" href="../advanced.html" title="Chapter 4. User documentation">
+<link rel="next" href="build_process.html" title="Build process">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<table cellpadding="2" width="100%"><td valign="top"><img alt="boost.png (6897 bytes)" width="277" height="86" src="../../../../boost.png"></td></table>
+<hr>
+<div class="spirit-nav">
+<a accesskey="p" href="../advanced.html"><img src="../../images/prev.png" alt="Prev"></a><a accesskey="u" href="../advanced.html"><img src="../../images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../images/home.png" alt="Home"></a><a accesskey="n" href="build_process.html"><img src="../../images/next.png" alt="Next"></a>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div><div><h2 class="title" style="clear: both">
+<a name="bbv2.advanced.jamfiles"></a>Writing Jamfiles</h2></div></div>
+<div></div>
+</div>
+<div class="toc"><dl>
+<dt><a href="jamfiles.html#bbv2.advanced.overview">Overview</a></dt>
+<dt><a href="jamfiles.html#bbv2.advanced.targets">Main targets</a></dt>
+<dt><a href="jamfiles.html#bbv2.advanced.projects">Projects</a></dt>
+<dt><a href="jamfiles.html#bbv2.advanced.other-rules">Additional Jamfile rules</a></dt>
+<dt><a href="jamfiles.html#bbv2.advanced.project-root">Project root</a></dt>
+</dl></div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div><div><h3 class="title">
+<a name="bbv2.advanced.overview"></a>Overview</h3></div></div>
+<div></div>
+</div>
+<p>Jamfiles are the thing which is most important to the user,
+      bacause they declare the targets which should be build. Jamfiles are
+      also used for organizing targets -- each Jamfile is a separate project,
+      which can be build independently from the other projects.</p>
+<p>Jamfile mostly contain calls to Boost.Build functions, which do
+        all the work, specifically:
+        </p>
+<div class="itemizedlist"><ul type="disc">
+<li><p><a href="jamfiles.html#bbv2.advanced.targets" title="Main targets">declare main
+                targets</a></p></li>
+<li><p><a href="jamfiles.html#bbv2.advanced.projects" title="Projects">define
+            project properties</a></p></li>
+<li><p><a href="jamfiles.html#bbv2.advanced.other-rules" title="Additional Jamfile rules">do various other
+            things</a></p></li>
+</ul></div>
+<p>In addition to Jamfiles, Boost.Build has another user-editable
+        file, project-root.jam, which is mostly useful to declare constants
+        global to all the projects. It is described in more detail <a href="jamfiles.html#bbv2.advanced.project-root" title="Project root">below</a>.
+      </p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div><div><h3 class="title">
+<a name="bbv2.advanced.targets"></a>Main targets</h3></div></div>
+<div></div>
+</div>
+<p><a name="bbv2.advanced.targets.main"></a><span class="emphasis"><em>Main target</em></span> is a user-defined named
+        entity which can be build, for example a named executable file.
+        Declaring a main target is usually done using one of <a href="builtins/targets.html" title="Builtin target types">main target functions</a>.
+        The user can also declare <a href="doc/extending.html#main_target_rules" target="_top">custom main target
+          function</a>.</p>
+<p>Most main targets rules in Boost.Build use similiar
+        syntax:</p>
+<a name="bbv2.main-target-rule-syntax"></a><pre class="programlisting">
+function-name main-target-name 
+    : sources 
+    : requirements 
+    : default-build 
+    : usage-requirements 
+    ;
+</pre>
+<div class="itemizedlist"><ul type="disc">
+<li>
+            "main-target-name" is the name used to request the target
+            on command line and to use it from other main targets. Main
+            target name may contain alphanumeric characters and symbols '-'
+            and '_';
+          </li>
+<li>
+            "sources" is the list of source files and other main
+            targets that must be combined. 
+          </li>
+<li>
+            "requirements" is the list of properties that must always
+            be present when this main target is built.
+          </li>
+<li>
+            "default-build" is the list of properties that will be used
+            unless some other value of the same feature is already
+            specified.
+          </li>
+<li>
+            "usage-requirements" is the list of properties that will be
+            propagated to all main targets that use this one, i.e. to all
+            dependents.
+          </li>
+</ul></div>
+<p>Note that the actual requirements, default-build and
+        usage-requirements attributes for a target are obtained by combining
+        the explicitly specified one with those specified for the project
+        where a target is declared.
+      </p>
+<p>          
+        Some main target rules have shorter list of parameters, and
+        you should consult their documentation for details.
+      </p>
+<p>The list of sources specifies what should be processed to get
+        the resulting targets. Most of the time, it's just a list of
+        files. Sometimes, you'd want to use all files with the same
+        extension as sources, in which case you can use the "glob"
+        rule. Here are two examples:
+</p>
+<pre class="programlisting">
+exe a : a.cpp ;
+exe b : [ glob *.cpp ] ;
+</pre>
+<p>
+        Unless you specify a files with absolute path, the name is
+        considered relative to the source directory -- which is typically
+        the same as directory when Jamfile is located, but can be changed as
+        described <a href="jamfiles.html#bbv2.advanced.projects.attributes.projectrule">here</a></p>
+<p>
+        The list of sources can also reference other main targets. The
+        targets in the same project can be referred by using the name, and
+        targets in other project need to specify directory or a symbolic
+        name of the other project. For example:
+</p>
+<pre class="programlisting">
+lib helper : helper.cpp ;
+exe a : a.cpp helper ;
+exe b : b.cpp ..//utils ;
+exe c : c.cpp /boost/program_options//program_opions ;
+</pre>
+<p>
+        The first exe uses the library defined in the same project. The
+        second one uses some target (most likely library) defined by Jamfile
+        one level higher. Finally, the third target uses some <a href="http://boost.org" target="_top">C++ Boost</a> library, using the
+        symbolic name to refer to it. More information about it can be found
+        in <a href="../tutorial/libs.html" title="Libraries and Dependent Targets">tutorial</a> and in 
+        <a href="../reference/definitions.html#bbv2.reference.ids" title="Target identifiers and references">target id reference</a>.          
+      </p>
+<p>Requirements are the properties that should always be present when
+        building a target. Typically, they are includes and defines:
+</p>
+<pre class="programlisting">
+exe hello : hello.cpp : &lt;include&gt;/opt/boost &lt;define&gt;MY_DEBUG ;
+</pre>
+<p>
+        In special circumstances, other properties can be used, for example if
+        a library does not work if it's shared, or a file can't be compiled
+        with optimization due to a compiler bug, one can use
+</p>
+<pre class="programlisting">
+lib util : util.cpp : &lt;link&gt;static ;
+obj main : main.cpp : &lt;optimization&gt;off ;
+</pre>
+<p>Sometimes, requirements are necessary only for a specific
+        compiler, or build variant. The 
+        <a href="../../">conditional
+        properties</a> can be used in that case:
+</p>
+<pre class="programlisting">
+lib util : util.cpp : &lt;toolset&gt;msvc:&lt;link&gt;static ;
+</pre>
+<p>
+        In means when whenever <tt class="computeroutput">&lt;toolset&gt;msvc</tt> property is
+        in build properties, the <tt class="computeroutput">&lt;link&gt;static</tt> property will
+        be included as well. The conditional requirements can be "chained":
+</p>
+<pre class="programlisting">
+lib util : util.cpp : &lt;toolset&gt;msvc:&lt;link&gt;static 
+                      &lt;link&gt;static:&lt;define&gt;STATIC_LINK ;
+</pre>
+<p>
+        will set of static link and the <tt class="computeroutput">STATIC_LINK</tt> define on the
+        <tt class="computeroutput">msvc</tt> toolset.
+      </p>
+<p>The default-build attribute is
+        a set of properties which should be used if build request does not
+        specify a value. For example:
+</p>
+<pre class="programlisting">
+exe hello : hello.cpp : : &lt;threading&gt;multi ;
+</pre>
+<p>
+        would build the target in multi-threaded mode, unless the user
+        explicitly requests single-threaded version. The difference between
+        requirements and default-build is that requirements cannot be
+        overriden in any way.
+      </p>
+<p>A target of the same name can be declared several times. In that
+        case is declaration is called an
+        <i class="firstterm">alternative</i>. When the target is build, one of
+        the alternatives will be selected and use. Alternatives need not be
+        defined by the same main target rule. The following is OK:
+</p>
+<pre class="programlisting">
+lib helpers : helpers.hpp ;
+alias helpers : helpers.lib : &lt;toolset&gt;msvc ;
+</pre>
+<p>Building of the same main target can differ greatly from
+        platform to platform. For example, you might have different list
+        of sources for different compilers, or different options for those
+        compilers. Two approaches to this are explained in the 
+        <a href="../tutorial/conditions.html" title="Conditions and alternatives">tutorial</a>.
+      </p>
+<p>Sometimes a main target is really needed only by some other main
+        target. For example, a rule that declares a test-suite uses a main
+        target that represent test, but those main targets are rarely needed
+        by themself.</p>
+<p>It is possible to declare target inline, i.e. the "sources"
+        parameter may include call to other main rules. For example:</p>
+<pre class="programlisting">
+exe hello : hello.cpp 
+    [ obj helpers : helpers.cpp : &lt;optimization&gt;off ] ;
+</pre>
+<p>
+        Will cause "helpers.cpp" to be always compiled without
+        optimization. It's possible to request main targets declared
+        inline, but since they are considered local, they are renamed to
+        "parent-main-target_name..main-target-name". In the example above,
+        to build only helpers, one should run "bjam hello..helpers".
+      </p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div><div><h3 class="title">
+<a name="bbv2.advanced.projects"></a>Projects</h3></div></div>
+<div></div>
+</div>
+<p>As mentioned before, targets are grouped into project, and each
+        Jamfile is a separate project. Projects are useful because it allows
+        to group related targets together, define properties common to all
+        those targets, and assign a symbolic name to the project, allowing to
+        easily refer to the targets in the project. Two last goals are
+        accompished with the "project" rule.
+      </p>
+<p>The rule has this syntax
+</p>
+<pre class="programlisting">
+project id : &lt;attributes&gt; ;
+</pre>
+<p>
+        Here, attributes is a sequence of (attribute-name,
+        attribute-value) pairs. The list of attribute names along with its
+        handling is also shown in the table below. For example, it is
+        possible to write:
+</p>
+<pre class="programlisting">
+project tennis 
+    : requirements &lt;threading&gt;multi 
+    : default-build release
+    ;
+</pre>
+<p>The possible attributes are listed below.</p>
+<p><span class="emphasis"><em>Project id</em></span> is a short way to denote a project, as
+        opposed to the Jamfile's pathname. It is a hierarchical path,
+        unrelated to filesystem, such as "boost/thread". <a href="../reference/definitions.html#bbv2.reference.ids" title="Target identifiers and references">Target references</a> make use of project ids to
+        specify a target.</p>
+<p><span class="emphasis"><em>Source location</em></span> specifies the directory where sources
+        for the project are located.</p>
+<p><span class="emphasis"><em>Project requirements</em></span> are requirements that apply to
+        all the targets in the projects as well as all subprojects.</p>
+<p><span class="emphasis"><em>Default build</em></span> is the build request that should be
+        used when no build request is specified explicitly.</p>
+<p><a name="bbv2.advanced.projects.attributes.projectrule"></a>
+        The default values for those attributes are
+        given in the table below.
+
+        </p>
+<div class="table">
+<a name="id2536169"></a><p class="title"><b>Table 4.1. </b></p>
+<table class="table" summary="">
+<colgroup>
+<col>
+<col>
+<col>
+<col>
+</colgroup>
+<thead><tr>
+<th>Attribute</th>
+<th>Name for the 'project' rule</th>
+<th>Default value</th>
+<th>Handling by the 'project' rule</th>
+</tr></thead>
+<tbody>
+<tr>
+<td>Project id</td>
+<td>none</td>
+<td>none</td>
+<td>Assigned from the first parameter of the 'project' rule.
+                  It is assumed to denote absolute project id.</td>
+</tr>
+<tr>
+<td>Source location</td>
+<td><tt class="literal">source-location</tt></td>
+<td>The location of jamfile for the project</td>
+<td>Sets to the passed value</td>
+</tr>
+<tr>
+<td>Requirements</td>
+<td><tt class="literal">requirements</tt></td>
+<td>The parent's requirements</td>
+<td>The parent's requirements are refined with the passed
+                  requirement and the result is used as the project
+                  requirements.</td>
+</tr>
+<tr>
+<td>Default build</td>
+<td><tt class="literal">default-build</tt></td>
+<td>none</td>
+<td>Sets to the passed value</td>
+</tr>
+<tr>
+<td>Build directory</td>
+<td><tt class="literal">build-dir</tt></td>
+<td>If parent has a build dir set, the value of it, joined
+                  with the relative path from parent to the current project.
+                  Otherwise, empty</td>
+<td>Sets to the passed value, interpreted as relative to the
+                  project's location.</td>
+</tr>
+</tbody>
+</table>
+</div>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div><div><h3 class="title">
+<a name="bbv2.advanced.other-rules"></a>Additional Jamfile rules</h3></div></div>
+<div></div>
+</div>
+<p>There's a number of other helper rules which can be used in
+      Jamfile, described in the following table.</p>
+<div class="table">
+<a name="id2536280"></a><p class="title"><b>Table 4.2. </b></p>
+<table class="table" summary="">
+<colgroup>
+<col>
+<col>
+</colgroup>
+<thead><tr>
+<th>Rule</th>
+<th>Semantic</th>
+</tr></thead>
+<tbody>
+<tr>
+<td><a href="jamfiles.html#bbv2.advanced.projects.attributes.projectrule">project</a></td>
+<td>Define project attributes.</td>
+</tr>
+<tr>
+<td><a href="../../">use-project</a></td>
+<td>Make another project known.</td>
+</tr>
+<tr>
+<td><a href="../../">build-project</a></td>
+<td>Build another project when this one is built.</td>
+</tr>
+<tr>
+<td><a href="../../">explicit</a></td>
+<td>States that the target should be built only by explicit
+                request.</td>
+</tr>
+<tr>
+<td>glob</td>
+<td>Takes a list of wildcards, and returns the list of files
+                which match any of the wildcards.</td>
+</tr>
+</tbody>
+</table>
+</div>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div><div><h3 class="title">
+<a name="bbv2.advanced.project-root"></a>Project root</h3></div></div>
+<div></div>
+</div>
+<p>Each project is also associated with <span class="emphasis"><em>project root</em></span>.
+        That's a root for a tree of projects, which specifies some global
+        properties.</p>
+<p>
+          Project root for a projects is the nearest parent directory
+          which contains a file called
+          <tt class="filename">project-root.jam</tt>. That file defines
+          certain properties which apply to all projects under project
+          root. It can:
+
+        </p>
+<div class="itemizedlist"><ul type="disc">
+<li>
+              configure toolsets, via call to <tt class="literal">toolset.using</tt>
+</li>
+<li>
+              refer to other projects, via the <tt class="literal">use-project</tt>
+              rule
+            </li>
+<li>
+              declare constants, via the <tt class="literal">constant</tt> and
+              <tt class="literal">path-constant</tt> rules.
+            </li>
+</ul></div>
+<p>To facilitate declaration of simple projects, Jamfile and
+        project-root can be merged together. To achieve this effect, the
+        project root file should call the <tt class="literal">project</tt> rule. The
+        semantic is precisely the same as if the call was made in
+        Jamfile, except that project-root.jam will start to serve as
+        Jamfile. The Jamfile in the directory of project-root.jam will be
+        ignored, and project-root.jam will be able to declare main
+        targets as usual.</p>
+</div>
+</div>
+<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
+<td align="left"></td>
+<td align="right"><small></small></td>
+</tr></table>
+<hr>
+<div class="spirit-nav">
+<a accesskey="p" href="../advanced.html"><img src="../../images/prev.png" alt="Prev"></a><a accesskey="u" href="../advanced.html"><img src="../../images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../images/home.png" alt="Home"></a><a accesskey="n" href="build_process.html"><img src="../../images/next.png" alt="Next"></a>
+</div>
+</body>
+</html>

Added: boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/advanced.html
===================================================================
--- boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/advanced.html	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/advanced.html	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,168 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+<title>Chapter 4. User documentation</title>
+<link rel="stylesheet" href="../boostbook.css" type="text/css">
+<meta name="generator" content="DocBook XSL Stylesheets V1.61.3">
+<link rel="home" href="../index.html" title="Part I. Boost.Build v2 User Manual">
+<link rel="up" href="../index.html" title="Part I. Boost.Build v2 User Manual">
+<link rel="previous" href="tutorial/prebuilt.html" title="Prebuilt targets">
+<link rel="next" href="advanced/jamfiles.html" title="Writing Jamfiles">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<table cellpadding="2" width="100%"><td valign="top"><img alt="boost.png (6897 bytes)" width="277" height="86" src="../../../boost.png"></td></table>
+<hr>
+<div class="spirit-nav">
+<a accesskey="p" href="tutorial/prebuilt.html"><img src="../images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../images/home.png" alt="Home"></a><a accesskey="n" href="advanced/jamfiles.html"><img src="../images/next.png" alt="Next"></a>
+</div>
+<div class="chapter" lang="en">
+<div class="titlepage">
+<div><div><h2 class="title">
+<a name="bbv2.advanced"></a>Chapter 4. User documentation</h2></div></div>
+<div></div>
+</div>
+<div class="toc">
+<p><b>Table of Contents</b></p>
+<dl>
+<dt><a href="advanced.html#bbv2.advanced.configuration">Configuration</a></dt>
+<dt><a href="advanced/jamfiles.html">Writing Jamfiles</a></dt>
+<dt><a href="advanced/build_process.html">Build process</a></dt>
+<dt><a href="advanced/builtins/targets.html">Builtin target types</a></dt>
+<dt><a href="advanced/builtins/features.html">Builtin features</a></dt>
+<dt><a href="advanced/differences_to_v1.html">Differences to Boost.Build V1</a></dt>
+</dl>
+</div>
+<p>This section will provide the information necessary to create your own
+  projects using Boost.Build. The information provided here is relatively
+  high-level, and <a href="reference.html" title="Chapter 6. Detailed reference">detailed reference</a> as
+  well as the on-line help system must be used to obtain
+  low-level documentation (see the <a href="reference.html#bbv2.reference.init.options.help">help option</a>).</p>
+<p>The Boost.Build actually consists of two parts - Boost.Jam, which is a
+  build engine with its own interpreted language, and Boost.Build itself,
+  implemented in Boost.Jam's language. The chain of event which happen when
+  you type "bjam" on the command is:
+      </p>
+<div class="orderedlist"><ol type="1">
+<li><p>Boost.Jam tries to find Boost.Build and loads the top-level
+          module. The exact process is described in the <a href="reference.html#bbv2.reference.init" title="Initialization">section on
+          initialization</a></p></li>
+<li><p>Boost.Build top-level module loads user-defined configuration
+          files, "user-config.jam" and "site-config.jam", which define
+          available toolsets.</p></li>
+<li><p>The Jamfile in the current directory is read. That in turn
+          might cause reading of further Jamfiles. As a result, a tree of
+          projects is created, with targets inside projects.</p></li>
+<li><p>Finally, using build request specified on the command line,
+          Boost.Build decides which targets should be built, and how. That
+          information is passed back to Boost.Jam, which takes care of
+          actually running commands.</p></li>
+</ol></div>
+<p>So, to be able to successfully use Boost.Build, you'd need to know only
+      three things:
+      </p>
+<div class="itemizedlist"><ul type="disc">
+<li><p><a href="advanced.html#bbv2.advanced.configuration" title="Configuration">
+              How to configure Boost.Build</a></p></li>
+<li><p><a href="advanced/jamfiles.html" title="Writing Jamfiles">
+              How to write Jamfiles</a></p></li>
+<li><p><a href="advanced/build_process.html" title="Build process">
+              How the build process works</a></p></li>
+</ul></div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div><div><h2 class="title" style="clear: both">
+<a name="bbv2.advanced.configuration"></a>Configuration</h2></div></div>
+<div></div>
+</div>
+<p>The Boost.Build configuration is specified in the file
+    "user-config.jam". You can edit the one which comes with Boost.Build, or
+    create a copy in your home directory and edit that. (See the <a href="reference.html#bbv2.reference.init.config" title="Table 6.1. Search paths for configuration files">reference</a> for the exact search
+    paths.) The primary function of that file is to declarate which compilers
+    and other tools are available. The simplest syntax to configure a tool is:
+</p>
+<pre class="programlisting">
+using &lt;tool-name&gt; ;        
+</pre>
+<p>
+      The "using" rule is given a name of tool, and will make that tool
+      available to Boost.Build. For example, "using gcc ;" will make available
+      the gcc compiler.      
+    </p>
+<p>
+      Since nothing but tool name is specified, Boost.Build will pick some
+      default settings -- for example will use gcc found in path, or look in
+      some known installation locations. For ordinary users, this is quite
+      fine. In case you have several version of a compiler, or it's located in
+      some unusual location, or you need to tweak the configuration, you'd
+      need to pass additional parameters to the "using" rule. Generally, 
+      for every tool module, the parameters differ, and you can obtain the documentaiton
+      by running
+</p>
+<pre class="programlisting">
+bjam --help &lt;tool-name&gt;.init         
+</pre>
+<p>
+      on the command line. However, for all compilers the meaning of the first
+      three parameters is the same: version, invocation command and options.
+    </p>
+<p>The "version" parameter identifies the compiler, in case you have
+    several. It can have any form you like, but it's recommended that you use
+    a numeric identifier, like "7.1". The "invocation command"
+    parameter is the command which must be executed to run the compiler. This
+    might be just compiler name, or a name with a path in it. Here are some
+    examples. 
+    </p>
+<p>To configure a compiler installed in non-standard location and not
+    present in path, you can do the following:
+</p>
+<pre class="programlisting">
+using msvc : : Z:/Programs/Microsoft Visual Studio/vc98/bin/cl.exe ;
+</pre>
+<p>To configure several versions of a compiler, the following can be used.
+</p>
+<pre class="programlisting">
+using gcc : 3.3 ;
+using gcc : 3.4 : g++-3.4 ;
+using gcc : 3.2 : g++-3.2 ;
+</pre>
+<p>
+        Note that in the first call to "using", the compiler found in path
+      will be used, and there's no need to explicitly specify the command.
+    </p>
+<p>As shown above, both "version" and "invocation command" parameters
+      are optional, but there's an important restriction: if you configure the
+      same compiler more then once, you must pass the "version" parameter
+      every time. For example, the following is not allowed:
+</p>
+<pre class="programlisting">
+using gcc ;
+using gcc : 3.4 : g++-3.4 ;
+</pre>
+<p>
+      because the first "using" does not specify the version. 
+    </p>
+<p>The <tt class="computeroutput">options</tt> parameter is used to fine-tune the
+      configuration. All compilers allow to pass four option, intentionally
+      similiar in spelling to builtin features: <tt class="computeroutput">cflags</tt>,
+      <tt class="computeroutput">cxxflags</tt>, <tt class="computeroutput">compileflags</tt> and
+      <tt class="computeroutput">linkflags</tt>. They specify additional options which will be
+      always passed to the corresponding tools. The <tt class="computeroutput">cflags</tt> option
+      applies only to the C compiler, the <tt class="computeroutput">cxxflags</tt> option applies
+      only to the C++ compiler and the <tt class="computeroutput">compileflags</tt> options
+      applies to both. For example, to use 64 bit mode with gcc you can use:
+</p>
+<pre class="programlisting">
+using gcc : 3.4 : : &lt;compileflags&gt;-m64 &lt;linkflags&gt;-m64 ;
+</pre>
+</div>
+</div>
+<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
+<td align="left"></td>
+<td align="right"><small></small></td>
+</tr></table>
+<hr>
+<div class="spirit-nav">
+<a accesskey="p" href="tutorial/prebuilt.html"><img src="../images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../images/home.png" alt="Home"></a><a accesskey="n" href="advanced/jamfiles.html"><img src="../images/next.png" alt="Next"></a>
+</div>
+</body>
+</html>

Added: boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/arch/build.html
===================================================================
--- boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/arch/build.html	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/arch/build.html	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,116 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+<title>The build layer</title>
+<link rel="stylesheet" href="../../boostbook.css" type="text/css">
+<meta name="generator" content="DocBook XSL Stylesheets V1.61.3">
+<link rel="home" href="../../index.html" title="Part I. Boost.Build v2 User Manual">
+<link rel="up" href="../arch.html" title="Appendix A. Boost.Build v2 architecture">
+<link rel="previous" href="../arch.html" title="Appendix A. Boost.Build v2 architecture">
+<link rel="next" href="tools.html" title="The tools layer">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<table cellpadding="2" width="100%"><td valign="top"><img alt="boost.png (6897 bytes)" width="277" height="86" src="../../../../boost.png"></td></table>
+<hr>
+<div class="spirit-nav">
+<a accesskey="p" href="../arch.html"><img src="../../images/prev.png" alt="Prev"></a><a accesskey="u" href="../arch.html"><img src="../../images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../images/home.png" alt="Home"></a><a accesskey="n" href="tools.html"><img src="../../images/next.png" alt="Next"></a>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div><div><h2 class="title" style="clear: both">
+<a name="bbv2.arch.build"></a>The build layer</h2></div></div>
+<div></div>
+</div>
+<p>The build layer has just four main parts -- abstract targets,
+      virtual targets, generators and properties. The abstract targets,
+      represented by the "abstract-target" class, correspond to main targets
+      -- which, as you recall, can produce different files depending on
+      properties. Virtual targets, represented by the 'virtual-target' class
+      correspond to real files. The abstract-target class has a method
+      'generate', which is given a set of properties and produces virtual
+      targets for those properties.       
+    </p>
+<p>There are several classes derived from "abstract-target". The
+      "main-target" class represents top-level main target, the "project-target"
+      acts like container for all main targets, and "basic-target" class is a
+      base class for all further target types.
+    </p>
+<p>Since each main target can have several alternatives, all top-level
+      target objects are just containers, referring to "real" main target
+      classes. The type is that container is "main-target". For example, given:
+</p>
+<pre class="programlisting">
+alias a ;
+lib a : a.cpp : &lt;toolset&gt;gcc ;
+</pre>
+<p>
+      we would have one-top level instance of "main-target-class", which will
+      contain one instance of "alias-target-class" and one instance of
+      "lib-target-class". The "generate" method of "main-target" decides
+      which of the alternative should be used, and call "generate" on the
+      corresponding instance.
+</p>
+<p>Each alternative is a instance of a class derived from
+    "basic-target". The "basic-target.generate" does several things that are
+    always should be done:
+      </p>
+<div class="itemizedlist"><ul type="disc">
+<li><p>Determines what properties should be used for building the
+          target. This includes looking at requested properties, requirements,
+          and usage requirements of all sources.</p></li>
+<li><p>Builds all sources</p></li>
+<li><p>Computes the usage requirements which should be passes back.</p></li>
+</ul></div>
+<p>
+      For the real work of constructing virtual target, a new method
+      "construct" is called.
+    </p>
+<p>The "construct" method can be implemented in any way by classes
+      derived from "basic-target", but one specific derived class plays the
+      central role -- "typed-target". That class holds the desired type of file
+      to be produces, and calls the generators modules to do the job.
+    </p>
+<p>Generators are Boost.Build abstractions for a tool. For example, one
+      can register a generator which converts target of type CPP into target of
+      type OBJ. When run with on a virtual target with CPP type, the generator
+      will construct the virtual target of type OBJ. The "generators" module
+      implements an algorithm, which given a list of sources, the desired type
+      and a list of properties, find all the generators which can perform the conversion.
+    </p>
+<p>The virtual targets which are produces by the main targets form a
+      graph. Targets which are produces from other ones refer to an instance of
+      "action" class, which in turn refers to action's sources, which can
+      further refer to actions. The sources, which are not produces from
+      anything, don't refer to any actions.
+    </p>
+<p>When all virtual targets are produced, they are "actualized". This
+    means that the real file names are computed, and the commands that should
+    be run are generated. This is done by "virtual-target.actualize" and
+    "action.actualize" methods. The first is conceptually simple, while the
+    second need additional explanation. The commands in bjam are generated in
+    two-stage process. First, a rule with the appropriate name (for example
+    "gcc.compile") is called and is given the names of targets. The rule sets
+    some variables, like "OPTIONS". After that, the command string is taken,
+    and variable are substitutes, so use of OPTIONS inside the command string
+    become the real compile options. 
+    </p>
+<p>Boost.Build added a third stage to simplify things. It's now
+    possible to automatically convert properties to appropriate assignments to
+    variables. For example, &lt;debug-symbols&gt;on would add "-g" to the
+    OPTIONS variable, without requiring to manually add this logic to
+    gcc.compile. This functionality is part of the "toolset" module.
+    </p>
+<p>When target paths are computed and the commands are set, Boost.Build
+    just gives control to bjam, which controls the execution of
+    commands.</p>
+</div>
+<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
+<td align="left"></td>
+<td align="right"><small></small></td>
+</tr></table>
+<hr>
+<div class="spirit-nav">
+<a accesskey="p" href="../arch.html"><img src="../../images/prev.png" alt="Prev"></a><a accesskey="u" href="../arch.html"><img src="../../images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../images/home.png" alt="Home"></a><a accesskey="n" href="tools.html"><img src="../../images/next.png" alt="Next"></a>
+</div>
+</body>
+</html>

Added: boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/arch/targets.html
===================================================================
--- boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/arch/targets.html	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/arch/targets.html	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,406 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+<title>Targets</title>
+<link rel="stylesheet" href="../../boostbook.css" type="text/css">
+<meta name="generator" content="DocBook XSL Stylesheets V1.61.3">
+<link rel="home" href="../../index.html" title="Part I. Boost.Build v2 User Manual">
+<link rel="up" href="../arch.html" title="Appendix A. Boost.Build v2 architecture">
+<link rel="previous" href="tools.html" title="The tools layer">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<table cellpadding="2" width="100%"><td valign="top"><img alt="boost.png (6897 bytes)" width="277" height="86" src="../../../../boost.png"></td></table>
+<hr>
+<div class="spirit-nav">
+<a accesskey="p" href="tools.html"><img src="../../images/prev.png" alt="Prev"></a><a accesskey="u" href="../arch.html"><img src="../../images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../images/home.png" alt="Home"></a>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div><div><h2 class="title" style="clear: both">
+<a name="bbv2.arch.targets"></a>Targets</h2></div></div>
+<div></div>
+</div>
+<div class="toc"><dl><dt><a href="targets.html#bbv2.arch.depends">Dependency scanning</a></dt></dl></div>
+<p>NOTE: THIS SECTION IS NOT EXPECTED TO BE READ!
+        There are two user-visible kinds of targets in Boost.Build.
+  First are "abstract" &#8212; they correspond to things declared
+  by user, for example, projects and executable files. The primary
+  thing about abstract target is that it's possible to request them
+  to be build with a particular values of some properties. Each
+  combination of properties may possible yield different set of
+  real file, so abstract target do not have a direct correspondence
+  with files.</p>
+<p>File targets, on the contary, are associated with concrete
+  files. Dependency graphs for abstract targets with specific
+  properties are constructed from file targets. User has no was to
+  create file targets, however it can specify rules that detect
+  file type for sources, and also rules for transforming between
+  file targets of different types. That information is used in
+  constructing dependency graph, as desribed in the "next section".
+  [ link? ] <span class="bold"><b>Note:</b></span>File targets are not
+  the same as targets in Jam sense; the latter are created from
+  file targets at the latest possible moment. <span class="bold"><b>Note:</b></span>"File
+  target" is a proposed name for what we call virtual targets. It
+  it more understandable by users, but has one problem: virtual
+  targets can potentially be "phony", and not correspond to any
+  file.</p>
+<div class="section" lang="en">
+<div class="titlepage">
+<div><div><h3 class="title">
+<a name="bbv2.arch.depends"></a>Dependency scanning</h3></div></div>
+<div></div>
+</div>
+<div class="toc"><dl>
+<dt><a href="targets.html#id2541586">Support for different scanning algorithms</a></dt>
+<dt><a href="targets.html#id2541595">Ability to scan the same file several times</a></dt>
+<dt><a href="targets.html#id2541654">Proper detection of dependencies on generated files.</a></dt>
+<dt><a href="targets.html#id2541833">Proper detection of dependencies from generated files</a></dt>
+</dl></div>
+<p>Dependency scanning is the process of finding implicit
+  dependencies, like "#include" statements in C++. The requirements
+  for right dependency scanning mechanism are:</p>
+<div class="itemizedlist"><ul type="disc">
+<li>
+        Support for different scanning algorithms. C++ and XML have
+    quite different syntax for includes and rules for looking up
+    included files.
+      </li>
+<li>
+        Ability to scan the same file several times. For example,
+    single C++ file can be compiled with different include
+    paths.
+      </li>
+<li>
+        Proper detection of dependencies on generated files.
+      </li>
+<li>
+        Proper detection of dependencies from generated file.
+      </li>
+</ul></div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div><div><h4 class="title">
+<a name="id2541586"></a>Support for different scanning algorithms</h4></div></div>
+<div></div>
+</div>
+<p>Different scanning algorithm are encapsulated by objects
+  called "scanners". Please see the documentation for "scanner"
+  module for more details.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div><div><h4 class="title">
+<a name="id2541595"></a>Ability to scan the same file several times</h4></div></div>
+<div></div>
+</div>
+<p>As said above, it's possible to compile a C++ file twice, with
+  different include paths. Therefore, include dependencies for
+  those compilations can be different. The problem is that bjam
+  does not allow several scans of the same target.</p>
+<p>The solution in Boost.Build is straigtforward. When a virtual
+  target is converted to bjam target (via
+  <tt class="literal">virtual-target.actualize</tt> method), we specify the scanner
+  object to be used. The actualize method will create different
+  bjam targets for different scanners.</p>
+<p>All targets with specific scanner are made dependent on target
+  without scanner, which target is always created. This is done in
+  case the target is updated. The updating action will be
+  associated with target without scanner, but if sources for that
+  action are touched, all targets &#8212; with scanner and without
+  should be considered outdated.</p>
+<p>For example, assume that "a.cpp" is compiled by two compilers
+  with different include path. It's also copied into some install
+  location. In turn, it's produced from "a.verbatim". The
+  dependency graph will look like:</p>
+<pre class="programlisting">
+a.o (&lt;toolset&gt;gcc)  &lt;--(compile)-- a.cpp (scanner1) ----+
+a.o (&lt;toolset&gt;msvc) &lt;--(compile)-- a.cpp (scanner2) ----|
+a.cpp (installed copy)    &lt;--(copy) ----------------------- a.cpp (no scanner)
+                                                                 ^
+                                                                 |
+                       a.verbose --------------------------------+
+</pre>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div><div><h4 class="title">
+<a name="id2541654"></a>Proper detection of dependencies on generated files.</h4></div></div>
+<div></div>
+</div>
+<p>This requirement breaks down to the following ones.</p>
+<div class="orderedlist"><ol type="1">
+<li>
+        If when compiling "a.cpp" there's include of "a.h", the
+    "dir" directory is in include path, and a target called "a.h"
+    will be generated to "dir", then bjam should discover the
+    include, and create "a.h" before compiling "a.cpp".
+      </li>
+<li>
+      Since almost always Boost.Build generates targets to a
+    "bin" directory, it should be supported as well. I.e. in the
+    scanario above, Jamfile in "dir" might create a main target,
+    which generates "a.h". The file will be generated to "dir/bin"
+    directory, but we still have to recornize the dependency.
+      </li>
+</ol></div>
+<p>The first requirement means that when determining what "a.h"
+  means, when found in "a.cpp", we have to iterate over all
+  directories in include paths, checking for each one:</p>
+<div class="orderedlist"><ol type="1">
+<li>
+        If there's file "a.h" in that directory, or
+      </li>
+<li>
+        If there's a target called "a.h", which will be generated
+    to that directory.
+      </li>
+</ol></div>
+<p>Classic Jam has built-in facilities for point (1) above, but
+  that's not enough. It's hard to implement the right semantic
+  without builtin support. For example, we could try to check if
+  there's targer called "a.h" somewhere in dependency graph, and
+  add a dependency to it. The problem is that without search in
+  include path, the semantic may be incorrect. For example, one can
+  have an action which generated some "dummy" header, for system
+  which don't have the native one. Naturally, we don't want to
+  depend on that generated header on platforms where native one is
+  included.</p>
+<p>There are two design choices for builtin support. Suppose we
+  have files a.cpp and b.cpp, and each one includes header.h,
+  generated by some action. Dependency graph created by classic jam
+  would look like:</p>
+<pre class="programlisting">
+a.cpp -----&gt; &lt;scanner1&gt;header.h  [search path: d1, d2, d3]
+
+
+                  &lt;d2&gt;header.h  --------&gt; header.y
+                  [generated in d2]
+           
+b.cpp -----&gt; &lt;scanner2&gt;header.h [ search path: d1, d2, d4]
+</pre>
+<p>
+In this case, Jam thinks all header.h target are not
+realated. The right dependency graph might be:
+
+</p>
+<pre class="programlisting">
+a.cpp ---- 
+          \
+           \     
+            &gt;----&gt;  &lt;d2&gt;header.h  --------&gt; header.y
+           /       [generated in d2]
+          / 
+b.cpp ----
+</pre>
+<p>
+
+or
+
+</p>
+<pre class="programlisting">
+a.cpp -----&gt; &lt;scanner1&gt;header.h  [search path: d1, d2, d3]
+                          |
+                       (includes)
+                          V
+                  &lt;d2&gt;header.h  --------&gt; header.y
+                  [generated in d2]
+                          ^
+                      (includes)  
+                          |
+b.cpp -----&gt; &lt;scanner2&gt;header.h [ search path: d1, d2, d4]
+</pre>
+<p>
+The first alternative was used for some time. The problem
+however is: what include paths should be used when scanning
+header.h? The second alternative was suggested by Matt Armstrong.
+It has similiar effect: add targets which depend on
+&lt;scanner1&gt;header.h will also depend on &lt;d2&gt;header.h.
+But now we have two different target with two different scanners,
+and those targets can be scanned independently. The problem of
+first alternative is avoided, so the second alternative is
+implemented now.
+        </p>
+<p>The second sub-requirements is that targets generated to "bin"
+  directory are handled as well. Boost.Build implements
+  semi-automatic approach. When compiling C++ files the process
+  is:</p>
+<div class="orderedlist"><ol type="1">
+<li>
+        The main target to which compiled file belongs is found.
+      </li>
+<li>
+        All other main targets that the found one depends on are
+    found. Those include main target which are used as sources, or
+    present as values of "dependency" features.
+      </li>
+<li>
+        All directories where files belonging to those main target
+    will be generated are added to the include path.
+      </li>
+</ol></div>
+<p>After this is done, dependencies are found by the approach
+  explained previously.</p>
+<p>Note that if a target uses generated headers from other main
+  target, that main target should be explicitly specified as
+  dependency property. It would be better to lift this requirement,
+  but it seems not very problematic in practice.</p>
+<p>For target types other than C++, adding of include paths must
+  be implemented anew.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div><div><h4 class="title">
+<a name="id2541833"></a>Proper detection of dependencies from generated files</h4></div></div>
+<div></div>
+</div>
+<div class="toc"><dl>
+<dt><a href="targets.html#id2541934">File targets</a></dt>
+<dt><a href="targets.html#id2541969">Target paths</a></dt>
+</dl></div>
+<p>Suppose file "a.cpp" includes "a.h" and both are generated by
+  some action. Note that classic jam has two stages. In first stage
+  dependency graph graph is build and actions which should be run
+  are determined. In second stage the actions are executed.
+  Initially, neither file exists, so the include is not found. As
+  the result, jam might attempt to compile a.cpp before creating
+  a.h, and compilation will fail.</p>
+<p>The solution in Boost.Jam is to perform additional dependency
+  scans after targets are updated. This break separation between
+  build stages in jam &#8212; which some people consider a good
+  thing &#8212; but I'm not aware of any better solution.</p>
+<p>In order to understand the rest of this section, you better
+  read some details about jam dependency scanning, available
+  <a href="http://public.perforce.com:8080/@md=d&amp;cd=//public/jam/src/&amp;ra=s&amp;c=kVu@//2614?ac=10" target="_top">
+  at this link</a>.</p>
+<p>Whenever a target is updated, Boost.Jam rescans it for
+  includes. Consider this graph, created before any actions are
+  run.</p>
+<pre class="programlisting">
+A -------&gt; C ----&gt; C.pro
+     /
+B --/         C-includes   ---&gt; D
+</pre>
+<p>
+Both A and B have dependency on C and C-includes (the latter
+dependency is not shown). Say during building we've tried to create
+A, then tried to create C and successfully created C.
+        </p>
+<p>In that case, the set of includes in C might well have
+  changed. We do not bother to detect precisely which includes were
+  added or removed. Instead we create another internal node
+  C-includes-2. Then we determine what actions should be run to
+  update the target. In fact this mean that we perform logic of
+  first stage while already executing stage.</p>
+<p>After actions for C-includes-2 are determined, we add
+  C-includes-2 to the list of A's dependents, and stage 2 proceeds
+  as usual. Unfortunately, we can't do the same with target B,
+  since when it's not visited, C target does not know B depends on
+  it. So, we add a flag to C which tells and it was rescanned. When
+  visiting B target, the flag is notices and C-includes-2 will be
+  added to the list of B's dependencies.</p>
+<p>Note also that internal nodes are sometimes updated too.
+  Consider this dependency graph:</p>
+<pre class="programlisting">
+a.o ---&gt; a.cpp
+            a.cpp-includes --&gt;  a.h (scanned)
+                                   a.h-includes ------&gt; a.h (generated)
+                                                                 |
+                                                                 |
+            a.pro &lt;-------------------------------------------+
+</pre>
+<p>Here, out handling of generated headers come into play. Say
+  that a.h exists but is out of date with respect to "a.pro", then
+  "a.h (generated)" and "a.h-includes" will be marking for
+  updating, but "a.h (scanned)" won't be marked. We have to rescan
+  "a.h" file after it's created, but since "a.h (generated)" has no
+  scanner associated with it, it's only possible to rescan "a.h"
+  after "a.h-includes" target was updated.</p>
+<p>Tbe above consideration lead to decision that we'll rescan a
+  target whenever it's updated, no matter if this target is
+  internal or not.</p>
+<div class="warning" style="margin-left: 0.5in; margin-right: 0.5in;">
+<h3 class="title">Warning</h3>
+<p>
+    The remainder of this document is not indended to be read at
+    all. This will be rearranged in future.
+    </p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div><div><h5 class="title">
+<a name="id2541934"></a>File targets</h5></div></div>
+<div></div>
+</div>
+<p>
+  As described above, file targets corresponds
+  to files that Boost.Build manages. User's may be concerned about
+  file targets in three ways: when declaring file target types,
+  when declaring transformations between types, and when
+  determining where file target will be placed. File targets can
+  also be connected with actions, that determine how the target is
+  created. Both file targets and actions are implemented in the
+  <tt class="literal">virtual-target</tt> module.
+          </p>
+<div class="section" lang="en">
+<div class="titlepage">
+<div><div><h6 class="title">
+<a name="id2541953"></a>Types</h6></div></div>
+<div></div>
+</div>
+<p>A file target can be given a file, which determines
+  what transformations can be applied to the file. The
+  <tt class="literal">type.register</tt> rule declares new types. File type can
+  also be assigned a scanner, which is used to find implicit
+  dependencies. See "dependency scanning" [ link? ] below.</p>
+</div>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div><div><h5 class="title">
+<a name="id2541969"></a>Target paths</h5></div></div>
+<div></div>
+</div>
+<p>To distinguish targets build with different properties, they
+  are put in different directories. Rules for determining target
+  paths are given below:</p>
+<div class="orderedlist"><ol type="1">
+<li>
+        All targets are placed under directory corresponding to the
+    project where they are defined.
+      </li>
+<li>
+        Each non free, non incidental property cause an additional
+    element to be added to the target path. That element has the
+    form <tt class="literal">&lt;feature-name&gt;-&lt;feature-value&gt;</tt> for
+    ordinary features and <tt class="literal">&lt;feature-value&gt;</tt> for
+    implicit ones. [Note about composite features].
+      </li>
+<li>
+        If the set of free, non incidental properties is different
+    from the set of free, non incidental properties for the project
+    in which the main target that uses the target is defined, a
+    part of the form <tt class="literal">main_target-&lt;name&gt;</tt> is added to
+    the target path. <span class="bold"><b>Note:</b></span>It would be nice to completely
+    track free features also, but this appears to be complex and
+    not extremely needed.
+      </li>
+</ol></div>
+<p>For example, we might have these paths:</p>
+<pre class="programlisting">
+debug/optimization-off
+debug/main-target-a
+</pre>
+</div>
+</div>
+</div>
+</div>
+<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
+<td align="left"></td>
+<td align="right"><small></small></td>
+</tr></table>
+<hr>
+<div class="spirit-nav">
+<a accesskey="p" href="tools.html"><img src="../../images/prev.png" alt="Prev"></a><a accesskey="u" href="../arch.html"><img src="../../images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../images/home.png" alt="Home"></a>
+</div>
+</body>
+</html>

Added: boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/arch/tools.html
===================================================================
--- boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/arch/tools.html	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/arch/tools.html	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,35 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+<title>The tools layer</title>
+<link rel="stylesheet" href="../../boostbook.css" type="text/css">
+<meta name="generator" content="DocBook XSL Stylesheets V1.61.3">
+<link rel="home" href="../../index.html" title="Part I. Boost.Build v2 User Manual">
+<link rel="up" href="../arch.html" title="Appendix A. Boost.Build v2 architecture">
+<link rel="previous" href="build.html" title="The build layer">
+<link rel="next" href="targets.html" title="Targets">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<table cellpadding="2" width="100%"><td valign="top"><img alt="boost.png (6897 bytes)" width="277" height="86" src="../../../../boost.png"></td></table>
+<hr>
+<div class="spirit-nav">
+<a accesskey="p" href="build.html"><img src="../../images/prev.png" alt="Prev"></a><a accesskey="u" href="../arch.html"><img src="../../images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../images/home.png" alt="Home"></a><a accesskey="n" href="targets.html"><img src="../../images/next.png" alt="Next"></a>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div><div><h2 class="title" style="clear: both">
+<a name="bbv2.arch.tools"></a>The tools layer</h2></div></div>
+<div></div>
+</div>
+<p>Write me!</p>
+</div>
+<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
+<td align="left"></td>
+<td align="right"><small></small></td>
+</tr></table>
+<hr>
+<div class="spirit-nav">
+<a accesskey="p" href="build.html"><img src="../../images/prev.png" alt="Prev"></a><a accesskey="u" href="../arch.html"><img src="../../images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../images/home.png" alt="Home"></a><a accesskey="n" href="targets.html"><img src="../../images/next.png" alt="Next"></a>
+</div>
+</body>
+</html>

Added: boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/arch.html
===================================================================
--- boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/arch.html	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/arch.html	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,61 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+<title>Appendix A. Boost.Build v2 architecture</title>
+<link rel="stylesheet" href="../boostbook.css" type="text/css">
+<meta name="generator" content="DocBook XSL Stylesheets V1.61.3">
+<link rel="home" href="../index.html" title="Part I. Boost.Build v2 User Manual">
+<link rel="up" href="../index.html" title="Part I. Boost.Build v2 User Manual">
+<link rel="previous" href="recipies/site-config.html" title="Targets in site-config.jam">
+<link rel="next" href="arch/build.html" title="The build layer">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<table cellpadding="2" width="100%"><td valign="top"><img alt="boost.png (6897 bytes)" width="277" height="86" src="../../../boost.png"></td></table>
+<hr>
+<div class="spirit-nav">
+<a accesskey="p" href="recipies/site-config.html"><img src="../images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../images/home.png" alt="Home"></a><a accesskey="n" href="arch/build.html"><img src="../images/next.png" alt="Next"></a>
+</div>
+<div class="appendix" lang="en">
+<div class="titlepage">
+<div><div><h2 class="title">
+<a name="bbv2.arch"></a>Appendix A. Boost.Build v2 architecture</h2></div></div>
+<div></div>
+</div>
+<div class="toc">
+<p><b>Table of Contents</b></p>
+<dl>
+<dt><a href="arch.html#bbv2.arch.overview">Overview</a></dt>
+<dt><a href="arch/build.html">The build layer</a></dt>
+<dt><a href="arch/tools.html">The tools layer</a></dt>
+<dt><a href="arch/targets.html">Targets</a></dt>
+</dl>
+</div>
+<div class="sidebar"><p>This document is work-in progress. Don't expect much from it
+      yet.</p></div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div><div><h2 class="title" style="clear: both">
+<a name="bbv2.arch.overview"></a>Overview</h2></div></div>
+<div></div>
+</div>
+<p>The Boost.Build code is structured in four different components:
+    "kernel", "util", "build" and "tools". The first two are relatively
+    uninteresting, so we'll focus on the remaining pair. The "build" component
+    provides classes necessary to declare targets, determine which properties
+    should be used for their building, and for creating the dependency
+    graph. The "tools" component provides user-visible functionality. It
+    mostly allows to declare specific kind of main targets, and declare
+    avaiable tools, which are then used when creating the dependency graph.
+    </p>
+</div>
+</div>
+<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
+<td align="left"></td>
+<td align="right"><small></small></td>
+</tr></table>
+<hr>
+<div class="spirit-nav">
+<a accesskey="p" href="recipies/site-config.html"><img src="../images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../images/home.png" alt="Home"></a><a accesskey="n" href="arch/build.html"><img src="../images/next.png" alt="Next"></a>
+</div>
+</body>
+</html>

Added: boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/extender.html
===================================================================
--- boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/extender.html	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/extender.html	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,122 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+<title>Chapter 5. Extender Manual</title>
+<link rel="stylesheet" href="../boostbook.css" type="text/css">
+<meta name="generator" content="DocBook XSL Stylesheets V1.61.3">
+<link rel="home" href="../index.html" title="Part I. Boost.Build v2 User Manual">
+<link rel="up" href="../index.html" title="Part I. Boost.Build v2 User Manual">
+<link rel="previous" href="advanced/differences_to_v1.html" title="Differences to Boost.Build V1">
+<link rel="next" href="extending/targets.html" title="Target types">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<table cellpadding="2" width="100%"><td valign="top"><img alt="boost.png (6897 bytes)" width="277" height="86" src="../../../boost.png"></td></table>
+<hr>
+<div class="spirit-nav">
+<a accesskey="p" href="advanced/differences_to_v1.html"><img src="../images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../images/home.png" alt="Home"></a><a accesskey="n" href="extending/targets.html"><img src="../images/next.png" alt="Next"></a>
+</div>
+<div class="chapter" lang="en">
+<div class="titlepage">
+<div><div><h2 class="title">
+<a name="bbv2.extender"></a>Chapter 5. Extender Manual</h2></div></div>
+<div></div>
+</div>
+<div class="toc">
+<p><b>Table of Contents</b></p>
+<dl>
+<dt><a href="extender.html#bbv2.extender.intro">Introduction</a></dt>
+<dt><a href="extending/targets.html">Target types</a></dt>
+<dt><a href="extending/tools.html">Tools and generators</a></dt>
+<dt><a href="extending/features.html">Features</a></dt>
+<dt><a href="extending/rules.html">Main target rules</a></dt>
+<dt><a href="extending/toolset_modules.html">Toolset modules</a></dt>
+</dl>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div><div><h2 class="title" style="clear: both">
+<a name="bbv2.extender.intro"></a>Introduction</h2></div></div>
+<div></div>
+</div>
+<p>This document explains how to extend Boost.Build to accomodate
+  your local requirements. Let's start with quite simple, but
+  realistic example.</p>
+<p>Say you're writing an application which generates C++ code. If
+  you ever did this, you know that it's not nice. Embedding large
+  portions of C++ code in string literals is very awkward. A much
+  better solution is:</p>
+<div class="orderedlist"><ol type="1">
+<li>
+        Write the template of the code to be generated, leaving
+    placeholders at the points which will change
+      </li>
+<li>
+        Access the template in your application and replace
+    placeholders with appropriate text.
+      </li>
+<li>Write the result.</li>
+</ol></div>
+<p>It's quite easy to achieve. You write special verbatim files,
+  which are just C++, except that the very first line of the file
+  gives a name of variable that should be generated. A simple tool
+  is created which takes verbatim file and creates a cpp file with
+  a single char* variable, which name is taken from the first line
+  of verbatim file, and which value is properly quoted content of
+  the verbatim file.</p>
+<p>Let's see what Boost.Build can do.</p>
+<p>First off, Boost.Build has no idea about "verbatim files". So,
+  you must register a new type. The following code does it:</p>
+<pre class="programlisting">
+import type ;
+type.register VERBATIM : verbatim ;
+</pre>
+<p>The first parameter to 'type.register' gives the name of
+  declared type. By convention, it's uppercase. The second
+  parameter is suffix for this type. So, if Boost.Build sees
+  "code.verbatim" in the list of sources, it knows that it's of
+  type <tt class="literal">VERBATIM</tt>.</p>
+<p>Lastly, you need a tool to convert verbatim files to C++. Say
+  you've sketched such a tool in Python. Then, you have to inform
+  Boost.Build about the tool. The Boost.Build concept which
+  represents a tool is <span class="emphasis"><em>generator</em></span>.</p>
+<p>First, you say that generator 'inline-file' is able to convert
+  VERBATIM type into C++:</p>
+<pre class="programlisting">
+import generators ;
+generators.register-standard verbatim.inline-file : VERBATIM : CPP ;
+</pre>
+<p>Second, you must specify the commands to be run to actually
+  perform convertion:</p>
+<pre class="programlisting">
+actions inline-file
+{
+    "./inline-file.py" $(&lt;) $(&gt;)
+}
+</pre>
+<p>Now, we're ready to tie it all together. Put all the code
+  above in file "verbatim.jam", add "import verbatim ;" to
+  "project-root.jam", and it's possible to write the following in
+  Jamfile:</p>
+<pre class="programlisting">
+exe codegen : codegen.cpp class_template.verbatim usage.verbatim ;
+</pre>
+<p>
+The verbatim files will be automatically converted into C++
+and linked it.
+  </p>
+<p>In the subsequent sections, we will extend this example, and review
+        all the mechanisms in detail. The complete code is available in <a href="../../example/customization" target="_top">example/customization</a>
+        directory.
+      </p>
+</div>
+</div>
+<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
+<td align="left"></td>
+<td align="right"><small></small></td>
+</tr></table>
+<hr>
+<div class="spirit-nav">
+<a accesskey="p" href="advanced/differences_to_v1.html"><img src="../images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../images/home.png" alt="Home"></a><a accesskey="n" href="extending/targets.html"><img src="../images/next.png" alt="Next"></a>
+</div>
+</body>
+</html>

Added: boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/extending/features.html
===================================================================
--- boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/extending/features.html	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/extending/features.html	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,235 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+<title>Features</title>
+<link rel="stylesheet" href="../../boostbook.css" type="text/css">
+<meta name="generator" content="DocBook XSL Stylesheets V1.61.3">
+<link rel="home" href="../../index.html" title="Part I. Boost.Build v2 User Manual">
+<link rel="up" href="../extender.html" title="Chapter 5. Extender Manual">
+<link rel="previous" href="tools.html" title="Tools and generators">
+<link rel="next" href="rules.html" title="Main target rules">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<table cellpadding="2" width="100%"><td valign="top"><img alt="boost.png (6897 bytes)" width="277" height="86" src="../../../../boost.png"></td></table>
+<hr>
+<div class="spirit-nav">
+<a accesskey="p" href="tools.html"><img src="../../images/prev.png" alt="Prev"></a><a accesskey="u" href="../extender.html"><img src="../../images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../images/home.png" alt="Home"></a><a accesskey="n" href="rules.html"><img src="../../images/next.png" alt="Next"></a>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div><div><h2 class="title" style="clear: both">
+<a name="bbv2.extending.features"></a>Features</h2></div></div>
+<div></div>
+</div>
+<p>
+        Often, we need to control the options passed the invoked tools. This 
+        is done with features. Consider an example:
+</p>
+<pre class="programlisting">
+# Declare a new feature
+import feature : feature ;
+feature verbatim-options : : free ;
+
+# Cause the value of the 'verbatim-options' feature to be
+# available as 'OPTIONS' variable inside verbatim.inline-file
+import toolset : flags ;
+flags verbatim.inline-file OPTIONS &lt;verbatim-options&gt; ;
+
+# Use the "OPTIONS" variable
+actions inline-file
+{
+    "./inline-file.py" $(OPTIONS) $(&lt;) $(&gt;)
+}
+</pre>
+<p>
+        We first define a new feature. Then, the <tt class="computeroutput">flags</tt> invocation
+        says that whenever verbatin.inline-file action is run, the value of
+        the <tt class="computeroutput">verbatim-options</tt> feature will be added to the
+        <tt class="computeroutput">OPTIONS</tt> variable, an can be used inside the action body.
+        You'd need to consult online help (--help) to find all the features of
+        the <tt class="computeroutput">toolset.flags</tt> rule.
+      </p>
+<p>
+      Although you can define any set of features and interpret their values
+      in any way, Boost.Build suggests the following coding standard for
+      designing features.
+    </p>
+<p>Most features should have a fixed set of values, which is portable
+      (tool neutral) across the class of tools they are designed to work
+      with. The user does not have to adjust the values for a exact tool.  For
+      example, <tt class="computeroutput">&lt;optimization&gt;speed</tt> has the same meaning for
+      all C++ compilers and the user does not have to worry about the exact
+      options which are passed to the compiler's command line.
+    </p>
+<p>
+      Besides such portable features there are special 'raw' features which
+      allow the user to pass any value to the command line parameters for a
+      particular tool, if so desired. For example, the
+      <tt class="computeroutput">&lt;cxxflags&gt;</tt> feature allows to pass any command line
+      options to a C++ compiler. The <tt class="computeroutput">&lt;include&gt;</tt> feature
+      allows to pass any value to the <tt class="computeroutput">-I</tt> and the interpretation
+      is tool-specific. (There an <a href="../faq/external.html" title="Can I get output of external program as a variable in a Jamfile?
+    ">example</a> of very smart usage of that
+      feature).  Of course one should always strive to use the portable
+      features but these should still be provided as a backdoor just to make
+      sure Boost.Build does not take away any control from the user. 
+    </p>
+<p>
+      Some of the reasons why portable features are better are:
+      </p>
+<div class="itemizedlist"><ul type="disc">
+<li><p>Since a portable feature have a fixed set of value, you will
+            be able to build your project with two different settings of the
+            feature. Boost.Build will automatically use two different
+            directories for produced files. If you pass raw compiler options,
+            Boost.Build assumes you know what you are doing, and would not
+            care about what options are passed.
+          </p></li>
+<li><p>Unlike "raw" features, you don't need to use specific
+            compiler flags in Jamfile, and it will more likely work on other systems.
+          </p></li>
+</ul></div>
+<h3>
+<a name="id2538586"></a>Steps for adding a feauture</h3>
+<p>Adding a feature requires three steps:
+
+        </p>
+<div class="orderedlist"><ol type="1">
+<li>
+<p>Declaring a feature. For that, the "feature.feature"
+              rule is used. You should have to decide on the set of <a href="../reference/definitions.html#bbv2.reference.features.attributes" title="Feature Attributes">feature
+              attributes</a>:
+
+              </p>
+<div class="itemizedlist"><ul type="disc">
+<li><p>if feature has several values, and
+                    significally affects build, make it "propagated", so that
+                    whole project is build with the same value by
+                    default</p></li>
+<li><p>if a feature does not have a fixed list of
+                    values, it must be "free".</p></li>
+<li><p>if feature is used to refer to a path, it must
+                be "path".</p></li>
+<li><p>if feature is used to refer to some target, it
+                must be "dependency".</p></li>
+</ul></div>
+</li>
+<li><p>Converting the feature value into variable. To use
+              feature in build action, it must be converted into a variable,
+              accessible in build action. This is accomplished by
+              "toolset.flags" rule.</p></li>
+<li><p>Using the variable. The variable set in step 2 can
+              be used in build action to form command parameters or
+              files.</p></li>
+</ol></div>
+<h3>
+<a name="id2538645"></a>Another example</h3>
+<p>Here's an another example.
+        Let's see how we can make a feature which refers to a target. For example,
+        when linking dynamic libraries on windows, one sometimes needs to specify
+        "DEF file", telling what functions should be exported. It would be nice to
+        use this file like this:
+</p>
+<pre class="programlisting">
+        lib a : a.cpp : &lt;def-file&gt;a.def ;
+</pre>
+<p>
+        Actually, this feature is already supported, but anyway...
+      </p>
+<div class="orderedlist"><ol type="1">
+<li>
+<p>Since the feature refers to a target, it must be "dependency".
+</p>
+<pre class="programlisting">
+feature def-file : : free dependency ;
+</pre>
+</li>
+<li>
+<p>One of the toolsets which cares about DEF files is
+msvc. The following line should be added to it.
+
+</p>
+<pre class="programlisting">
+flags msvc.link DEF_FILE &lt;def-file&gt; ;
+</pre>
+</li>
+<li>
+<p>Since the DEF_FILE variable is not used by the
+msvc.link action, we need to modify it to be:
+
+</p>
+<pre class="programlisting">
+actions link bind DEF_FILE
+{
+    $(.LD) .... /DEF:$(DEF_FILE) ....
+}
+</pre>
+<p> Note the "bind DEF_FILE" part. It tells bjam that DEF_FILE
+            refers to a file, otherwise the variable will contain internal
+            target name, which is not likely to make sense for the linker.
+          </p>
+<p>
+            We've almost done, but should stop for a small workaround. Add the following
+            code to msvc.jam
+
+</p>
+<pre class="programlisting">
+rule link
+{
+    DEPENDS $(&lt;) : [ on $(&lt;) return $(DEF_FILE) ] ;
+}
+</pre>
+<p>
+
+            This is needed to accomodate some bug in bjam, which hopefully
+            will be fixed one day.</p>
+</li>
+</ol></div>
+<h3>
+<a name="id2538721"></a>Variants and composite features.</h3>
+<p>Sometimes you want to create a shorcut for some set of
+        features. For example, <tt class="computeroutput">release</tt> is a value of the
+        <tt class="computeroutput">variant</tt> and is a shortcut for a set of features.
+        </p>.
+
+      <p>It is possible to define your build variants. For example:
+</p>
+<pre class="programlisting">
+variant crazy : &lt;optimization&gt;speed &lt;inlining&gt;off
+                &lt;debug-symbols&gt;on &lt;profiling&gt;on ;
+</pre>
+<p>
+        will define a new variant with the specified set of properties. You
+        can also extend an existing variant:
+</p>
+<pre class="programlisting">
+variant super_release : release : &lt;define&gt;USE_ASM ;
+</pre>
+<p>
+        In this case, <tt class="computeroutput">super_release</tt> will expand to all properties
+        specified by <tt class="computeroutput">release</tt>, and the additional one you've specified.
+      </p>
+<p>You are not restricted to using the <tt class="computeroutput">variant</tt> feature
+      only. Here's example which defines a brand new feature:
+</p>
+<pre class="programlisting">
+feature parallelism : mpi fake none : composite link-incompatible ;
+feature.compose &lt;parallelism&gt;mpi : &lt;library&gt;/mpi//mpi/&lt;parallelism&gt;none ;
+feature.compose &lt;parallelism&gt;fake : &lt;library&gt;/mpi//fake/&lt;parallelism&gt;none ;
+</pre>
+<p>
+        This will allow you to specify value of feature
+        <tt class="computeroutput">parallelism</tt>, which will expand to link to the necessary
+        library. 
+      </p>
+</div>
+<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
+<td align="left"></td>
+<td align="right"><small></small></td>
+</tr></table>
+<hr>
+<div class="spirit-nav">
+<a accesskey="p" href="tools.html"><img src="../../images/prev.png" alt="Prev"></a><a accesskey="u" href="../extender.html"><img src="../../images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../images/home.png" alt="Home"></a><a accesskey="n" href="rules.html"><img src="../../images/next.png" alt="Next"></a>
+</div>
+</body>
+</html>

Added: boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/extending/rules.html
===================================================================
--- boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/extending/rules.html	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/extending/rules.html	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,89 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+<title>Main target rules</title>
+<link rel="stylesheet" href="../../boostbook.css" type="text/css">
+<meta name="generator" content="DocBook XSL Stylesheets V1.61.3">
+<link rel="home" href="../../index.html" title="Part I. Boost.Build v2 User Manual">
+<link rel="up" href="../extender.html" title="Chapter 5. Extender Manual">
+<link rel="previous" href="features.html" title="Features">
+<link rel="next" href="toolset_modules.html" title="Toolset modules">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<table cellpadding="2" width="100%"><td valign="top"><img alt="boost.png (6897 bytes)" width="277" height="86" src="../../../../boost.png"></td></table>
+<hr>
+<div class="spirit-nav">
+<a accesskey="p" href="features.html"><img src="../../images/prev.png" alt="Prev"></a><a accesskey="u" href="../extender.html"><img src="../../images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../images/home.png" alt="Home"></a><a accesskey="n" href="toolset_modules.html"><img src="../../images/next.png" alt="Next"></a>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div><div><h2 class="title" style="clear: both">
+<a name="bbv2.extending.rules"></a>Main target rules</h2></div></div>
+<div></div>
+</div>
+<p>
+      The main target rule is what creates a top-level target, for example "exe" or
+      "lib". It's quite likely that you'll want to declare your own and
+      there are as many as three ways to do that.
+    </p>
+<p>The first is the simplest, but is sufficient in a number of
+      cases. Just write a wrapper rule, which will redirect to any of the
+      existing rules. For example, you have only one library per directory and
+      want all cpp files in the directory to be compiled. You can achieve this
+      effect with:
+</p>
+<pre class="programlisting">
+lib codegen : [ glob *.cpp ] ;
+</pre>
+<p>
+      but what if you want to make it even simple. Then, you add the following
+      definition to the project-root.jam file:
+</p>
+<pre class="programlisting">
+rule glib ( name : extra-sources * : requirements * )
+{
+    lib $(name) : [ glob *.cpp ] $(extra-sources) : $(requirements) ;
+}
+</pre>
+<p>
+which would allow to reduce Jamfile to
+</p>
+<pre class="programlisting">
+glib codegen ;
+</pre>
+<p>The second approach is suitable when your target rule should just
+      produce a target of specific type. Then, when declaring a type you
+      should tell Boost.Build that a main target rule should be created.
+      For example, if you create a module "obfuscate.jam" containing:
+
+</p>
+<pre class="programlisting">
+import type ;
+type.register OBFUSCATED_CPP  : ocpp : : main ;
+
+import generators ;
+generators.register-standard obfuscate.file : CPP : OBFUSCATED_CPP ;
+</pre>
+<p>
+      and import that module, you'll be able to use the rule "obfuscated-cpp"
+      in Jamfiles, which will convert source to the OBFUSCATED_CPP type.
+    </p>
+<p>
+      The remaining method is to declare your own main target class. The
+      simplest example of this can be found in "build/alias.jam" file. The
+      current V2 uses this method when transformations are relatively
+      complex. However, we might deprecate this approach. If you find that you
+      need to use it (that is, the first two approaches are not sufficient),
+      please let us know by posting to the mailing list.
+    </p>
+</div>
+<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
+<td align="left"></td>
+<td align="right"><small></small></td>
+</tr></table>
+<hr>
+<div class="spirit-nav">
+<a accesskey="p" href="features.html"><img src="../../images/prev.png" alt="Prev"></a><a accesskey="u" href="../extender.html"><img src="../../images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../images/home.png" alt="Home"></a><a accesskey="n" href="toolset_modules.html"><img src="../../images/next.png" alt="Next"></a>
+</div>
+</body>
+</html>

Added: boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/extending/targets.html
===================================================================
--- boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/extending/targets.html	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/extending/targets.html	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,112 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+<title>Target types</title>
+<link rel="stylesheet" href="../../boostbook.css" type="text/css">
+<meta name="generator" content="DocBook XSL Stylesheets V1.61.3">
+<link rel="home" href="../../index.html" title="Part I. Boost.Build v2 User Manual">
+<link rel="up" href="../extender.html" title="Chapter 5. Extender Manual">
+<link rel="previous" href="../extender.html" title="Chapter 5. Extender Manual">
+<link rel="next" href="tools.html" title="Tools and generators">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<table cellpadding="2" width="100%"><td valign="top"><img alt="boost.png (6897 bytes)" width="277" height="86" src="../../../../boost.png"></td></table>
+<hr>
+<div class="spirit-nav">
+<a accesskey="p" href="../extender.html"><img src="../../images/prev.png" alt="Prev"></a><a accesskey="u" href="../extender.html"><img src="../../images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../images/home.png" alt="Home"></a><a accesskey="n" href="tools.html"><img src="../../images/next.png" alt="Next"></a>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div><div><h2 class="title" style="clear: both">
+<a name="bbv2.extending.targets"></a>Target types</h2></div></div>
+<div></div>
+</div>
+<div class="toc"><dl><dt><a href="targets.html#bbv2.extending.scanners">Scanners</a></dt></dl></div>
+<p>The first thing we did in the <a href="../extender.html#bbv2.extender.intro" title="Introduction">intruduction</a> was declaring a
+      new target type:
+</p>
+<pre class="programlisting">
+import type ;
+type.register VERBATIM : verbatim ;
+</pre>
+<p>
+        The type is the most important property of a target. Boost.Build can
+        automatically generate necessary build actions only because you
+        specify the desired type (using the different main target rules), and
+        because Boost.Build can guess the type of sources from their
+        extensions.        
+      </p>
+<p>The first two parameters for the <tt class="computeroutput">type.register</tt> rule
+        are the name of new type and the list of extensions associated with
+        it. A file with an extension from the list will have the given target
+        type. In the case where a target of the declared type is generated
+        from other sources, the first specified extension will be used. This
+        behaviour can be changed using the
+        <tt class="computeroutput">type.set-generated-target-suffix</tt> rule.
+      </p>
+<p>
+        Something about 'main' types.
+      </p>
+<p>Something about base types.
+      </p>
+<div class="section" lang="en">
+<div class="titlepage">
+<div><div><h3 class="title">
+<a name="bbv2.extending.scanners"></a>Scanners</h3></div></div>
+<div></div>
+</div>
+<p>
+          Sometimes, a file can refer to other files via some include
+          mechanism. To make Boost.Build track dependencies to the included
+          files, you need to provide a scanner. The primary limitation is that
+          only one scanner can be assigned to a target type.
+        </p>
+<p>First, we need to declare a new class for the scanner:
+</p>
+<pre class="programlisting">
+class verbatim-scanner : common-scanner
+{
+    rule pattern ( )
+    {
+        return "//###include[ ]*\"([^\"]*)\"" ;
+    }
+}
+</pre>
+<p>         
+          All the complex logic is in the <tt class="computeroutput">common-scanner</tt> class,
+          and you only need to override the method which returns the regular
+          expression to be used for scanning. The paranthethis in the regular
+          expression indicate which part of the string is the name of the
+          included file. 
+        </p>
+<p>After that, we need to register our scanner class:
+</p>
+<pre class="programlisting">
+scanner.register verbatim-scanner : include ;
+</pre>
+<p>
+            The value of the second parameter, in this case
+            <tt class="computeroutput">include</tt>, specifies which properties contain the list
+            of paths which should be searched for the included files.
+         </p>
+<p>Finally, we assign the new scaner to the <tt class="computeroutput">VERBATIM</tt>
+        target type:
+</p>
+<pre class="programlisting">
+type.set-scanner VERBATIM : verbatim-scanner ;
+</pre>
+<p>
+          That's enough for scanning include dependencies.
+        </p>
+</div>
+</div>
+<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
+<td align="left"></td>
+<td align="right"><small></small></td>
+</tr></table>
+<hr>
+<div class="spirit-nav">
+<a accesskey="p" href="../extender.html"><img src="../../images/prev.png" alt="Prev"></a><a accesskey="u" href="../extender.html"><img src="../../images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../images/home.png" alt="Home"></a><a accesskey="n" href="tools.html"><img src="../../images/next.png" alt="Next"></a>
+</div>
+</body>
+</html>

Added: boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/extending/tools.html
===================================================================
--- boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/extending/tools.html	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/extending/tools.html	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,228 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+<title>Tools and generators</title>
+<link rel="stylesheet" href="../../boostbook.css" type="text/css">
+<meta name="generator" content="DocBook XSL Stylesheets V1.61.3">
+<link rel="home" href="../../index.html" title="Part I. Boost.Build v2 User Manual">
+<link rel="up" href="../extender.html" title="Chapter 5. Extender Manual">
+<link rel="previous" href="targets.html" title="Target types">
+<link rel="next" href="features.html" title="Features">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<table cellpadding="2" width="100%"><td valign="top"><img alt="boost.png (6897 bytes)" width="277" height="86" src="../../../../boost.png"></td></table>
+<hr>
+<div class="spirit-nav">
+<a accesskey="p" href="targets.html"><img src="../../images/prev.png" alt="Prev"></a><a accesskey="u" href="../extender.html"><img src="../../images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../images/home.png" alt="Home"></a><a accesskey="n" href="features.html"><img src="../../images/next.png" alt="Next"></a>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div><div><h2 class="title" style="clear: both">
+<a name="bbv2.extending.tools"></a>Tools and generators</h2></div></div>
+<div></div>
+</div>
+<p>
+        This section will describe how Boost.Build can be extended to support
+        new tools.
+      </p>
+<p>For each additional tool, a Boost.Build object called generator
+        must be created. That object has specific types of targets which it
+        accepts an produces. Using that information, Boost.Build is able
+        to automatically invoke the generator. For example, if you declare a
+        generator which takes a target of the type <tt class="literal">D</tt> and
+        produces a target of the type <tt class="literal">OBJ</tt>, when placing a
+        file with extention <tt class="literal">.d</tt> in a list of sources will
+        cause Boost.Build to invoke your generator, and then to link the
+        resulting object file into an application. (Of course, this requires
+        that you specify that the <tt class="literal">.d</tt> extension corresponds
+        to the <tt class="literal">D</tt> type.)
+      </p>
+<p>Each generator should be an instance of a class derived from the
+        <tt class="computeroutput">generator</tt> class. In the simplest case, you don't need to
+        create a derived class, but simply create an instance of the
+        <tt class="computeroutput">generator</tt> class. Let's review the example we've seen in the
+        <a href="../extender.html#bbv2.extender.intro" title="Introduction">introduction</a>.
+</p>
+<pre class="programlisting">
+import generators ;
+generators.register-standard verbatim.inline-file : VERBATIM : CPP ;
+actions inline-file
+{
+    "./inline-file.py" $(&lt;) $(&gt;)
+}
+</pre>
+<p>We declare a standard generator, specifying its id, the source type
+        and the target type. When invoked, the generator will create a target
+        of type <tt class="literal">CPP</tt> which will have the source target of
+        type <tt class="literal">VERBATIM</tt> as the only source. But what command
+        will be used to actually generate the file? In bjam, actions are
+        specified using named "actions" blocks and the name of the action
+        block should be specified when creating targets. By convention,
+        generators use the same name of the action block as their own id. So,
+        in above example, the "inline-file" actions block will be use to
+        convert the source into the target.
+      </p>
+<p>
+        There are two primary kinds of generators: standard and composing,
+        which are registered with the
+        <tt class="computeroutput">generators.register-standard</tt> and the
+        <tt class="computeroutput">generators.register-composing</tt> rules, respectively. For
+        example:
+</p>
+<pre class="programlisting">
+generators.register-standard verbatim.inline-file : VERBATIM : CPP ;
+generators.register-composing mex.mex : CPP LIB : MEX ;
+</pre>
+<p>
+        The first generators takes a <span class="emphasis"><em>single</em></span> source of type
+        <tt class="computeroutput">VERBATIM</tt> and produces a result. The second generator
+        takes any number of sources, which can have either the
+        <tt class="computeroutput">CPP</tt> or the <tt class="computeroutput">LIB</tt> type. Composing generators
+        are typically used for generating top-level target type. For example,
+        the first generator invoked when building an <tt class="computeroutput">exe</tt> target
+        is a composing generator corresponding to the proper linker.
+      </p>
+<p>You should also know about two specific function for registering
+        generators: <tt class="computeroutput">generators.register-c-compiler</tt> and
+        <tt class="computeroutput">generators.register-linker</tt>. The first sets up header
+        dependecy scanning for C files, and the seconds handles various
+        complexities like searched libraries. For that reason, you should always
+        use those functions when adding support for compilers and linkers.
+      </p>
+<p>(Need a note about UNIX)</p>
+<h3>
+<a name="id2538271"></a>Custom generator classes</h3>
+<p>The standard generators allows you to specify source and target
+        types, action, and a set of flags. If you need anything more complex,
+        you need to create a new generator class with your own logic. Then,
+        you have to create an instance of that class and register it. Here's
+        an example how you can create your own generator class:
+</p>
+<pre class="programlisting">
+class custom-generator : generator
+{
+    rule __init__ ( * : * )
+    {
+        generator.__init__ $(1) : $(2) : $(3) : $(4) : $(5) : $(6) : $(7) : $(8) : $(9) ;
+    }
+}
+
+generators.register 
+  [ new custom-generator verbatim.inline-file : VERBATIM : CPP ] ;
+</pre>
+<p>
+        This generator will work exactly like the
+        <tt class="computeroutput">verbatim.inline-file</tt> generator we've defined above, but
+        it's possible to customize the behaviour by overriding methods of the
+        <tt class="computeroutput">generator</tt> class.
+      </p>
+<p>There are two methods of interest. The <tt class="computeroutput">run</tt> methods is
+        responsible for overall process - it takes a number of source targets,
+        converts them the the right types, and creates the result. The
+        <tt class="computeroutput">generated-targets</tt> method is called when all sources are
+        converted to the right types to actually create the result.
+      </p>
+<p>The <tt class="computeroutput">generated-target</tt> method can be overridden when you
+        want to add additional properties to the generated targets or use
+        additional sources. For example (which is real), you have a tool for
+        analysing programs, which should be given a name of executable and the
+        list of all sources. Naturally, you don't want to list all source
+        files manually. Here's how the <tt class="computeroutput">generated-target</tt> method
+        can find the list of sources automatically:
+</p>
+<pre class="programlisting">
+class itrace-generator : generator {
+....
+    rule generated-targets ( sources + : property-set : project name ? )
+    {
+        local leafs ;
+        local temp = [ virtual-target.traverse $(sources[1]) : : include-sources ] ;
+        for local t in $(temp)
+        {
+            if ! [ $(t).action ]
+            {
+                leafs += $(t) ;
+            }
+        }
+        return [ generator.generated-targets $(sources) $(leafs)
+          : $(property-set) : $(project) $(name) ] ;
+    }
+}
+generators.register [ new itrace-generator nm.itrace : EXE : ITRACE ] ;
+</pre>
+<p>
+        The <tt class="computeroutput">generated-targets</tt> rule will be called with a single
+        source target of type <tt class="literal">EXE</tt>. The call to the
+        <tt class="computeroutput">virtual-target.traverse</tt> will return all targets the
+        executable depends on, and we further find files which are not
+        produced from anything. The found targets are added to the sources.
+      </p>
+<p>The <tt class="computeroutput">run</tt> method can be overriden to completely
+        customize the way generator works. In particular, the conversion of
+        sources to the desired types can be completely customized. Here's
+        another real example. Tests for the Boost Python library usually
+        consist of two parts: a Python program and a C++ file. The C++ file is
+        compiled to Python extension which is loaded by the Python
+        program. But in the likely case that both files have the same name,
+        the created Python extension must be renamed. Otherwise, Python
+        program will import itself, not the extension. Here's how it can be
+        done:
+</p>
+<pre class="programlisting">
+rule run ( project name ? : property-set : sources * : multiple ? )
+{       
+    local python ;
+    for local s in $(sources)
+    {
+        if [ $(s).type ] = PY
+        {
+            python = $(s) ;
+        }
+    }
+    
+    local libs ;
+    for local s in $(sources)
+    {
+        if [ type.is-derived [ $(s).type ] LIB ]
+        {
+            libs += $(s) ;
+        }
+    }
+    
+    local new-sources ;
+    for local s in $(sources)
+    {
+        if [ type.is-derived [ $(s).type ] CPP ] 
+        {
+            local name = [ $(s).name ] ;
+            if $(name) = [ $(python).name ] 
+            {
+                name = $(name)_ext ;
+            }                                
+            new-sources += [ generators.construct $(project) $(name) :
+              PYTHON_EXTENSION : $(property-set) : $(s) $(libs) ] ;
+        }
+    }
+        
+    result = [ construct-result $(python) $(new-sources) : $(project) $(name) 
+                 : $(property-set) ] ;        
+}    
+</pre>
+<p>        
+        First, we separate all source into python files, libraries and C++
+        sources. For each C++ source we create a separate Python extension by
+        calling <tt class="computeroutput">generators.construct</tt> and passing the C++ source
+        and the libraries. At this point, we also change the extension's name,
+        if necessary.        
+      </p>
+</div>
+<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
+<td align="left"></td>
+<td align="right"><small></small></td>
+</tr></table>
+<hr>
+<div class="spirit-nav">
+<a accesskey="p" href="targets.html"><img src="../../images/prev.png" alt="Prev"></a><a accesskey="u" href="../extender.html"><img src="../../images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../images/home.png" alt="Home"></a><a accesskey="n" href="features.html"><img src="../../images/next.png" alt="Next"></a>
+</div>
+</body>
+</html>

Added: boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/extending/toolset_modules.html
===================================================================
--- boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/extending/toolset_modules.html	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/extending/toolset_modules.html	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,107 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+<title>Toolset modules</title>
+<link rel="stylesheet" href="../../boostbook.css" type="text/css">
+<meta name="generator" content="DocBook XSL Stylesheets V1.61.3">
+<link rel="home" href="../../index.html" title="Part I. Boost.Build v2 User Manual">
+<link rel="up" href="../extender.html" title="Chapter 5. Extender Manual">
+<link rel="previous" href="rules.html" title="Main target rules">
+<link rel="next" href="../reference.html" title="Chapter 6. Detailed reference">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<table cellpadding="2" width="100%"><td valign="top"><img alt="boost.png (6897 bytes)" width="277" height="86" src="../../../../boost.png"></td></table>
+<hr>
+<div class="spirit-nav">
+<a accesskey="p" href="rules.html"><img src="../../images/prev.png" alt="Prev"></a><a accesskey="u" href="../extender.html"><img src="../../images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../images/home.png" alt="Home"></a><a accesskey="n" href="../reference.html"><img src="../../images/next.png" alt="Next"></a>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div><div><h2 class="title" style="clear: both">
+<a name="bbv2.extending.toolset_modules"></a>Toolset modules</h2></div></div>
+<div></div>
+</div>
+<p>If your extensions will be used only on one project, they can be
+      placed in a separate <tt class="filename">.jam</tt> file which will be
+      imported by your <tt class="filename">project-root.jam</tt>. If the
+      extensions will be used on many projects, the users will thank you for 
+      a finishing touch.
+    </p>
+<p>The standard way to use a tool in Boost.Build is the
+      <tt class="computeroutput">using</tt> rule. To make it work, you module should provide an
+      <tt class="computeroutput">init</tt> rule. The rule will be called with the same parameters
+      which were passed to the <tt class="computeroutput">using</tt> rule. The set of allowed
+      parameters is determined by you. For example, you can allow the user to
+      specify paths, tool version, or tool options.
+    </p>
+<p>Here are some guidelines which help to make Boost.Build more
+      consistent:
+      </p>
+<div class="itemizedlist"><ul type="disc">
+<li><p>The <tt class="computeroutput">init</tt> rule should never fail. Even if
+          user provided a wrong path, you should emit a warning and go
+          on. Configuration may be shared between different machines, and
+          wrong values on one machine can be OK on another.
+          </p></li>
+<li>
+<p>Prefer specifying command to be executed to specifying
+            path. First of all, this gives more control: it's possible to
+            specify
+</p>
+<pre class="programlisting">
+/usr/bin/g++-snapshot
+time g++
+</pre>
+<p>
+            as the command. Second, while some tools have a logical
+            "installation root", it better if user don't have to remember if
+            a specific tool requires a full command or a path.            
+          </p>
+</li>
+<li>
+<p>Check for multiple initialization. A user can try to
+            initialize the module several times. You need to check for this
+            and decide what to do. Typically, unless you support several
+            versions of a tool, duplicate initialization is a user error. If
+            tool version can be specified during initialization, make sure the
+            version is either always specified, or never specified (in which
+            case the tool is initialied only once). For example, if you allow:
+</p>
+<pre class="programlisting">
+using yfc ;
+using yfc : 3.3 ;
+using yfc : 3.4 ;
+</pre>
+<p>
+            Then it's not clear if the first initialization corresponds to
+            version 3.3 of the tool, version 3.4 of the tool, or some other
+            version. This can lead to building twice with the same version.
+            </p>
+</li>
+<li>
+<p>If possible, the <tt class="computeroutput">init</tt> must be callable
+          with no parameters. In which case, it should try to autodetect all
+          the necessary information, for example, by looking for a tool in
+          <tt class="envar">PATH</tt> or in common installation locations. Often this
+          is possible and allows the user to simply write:
+</p>
+<pre class="programlisting">
+using yfc ;
+</pre>
+</li>
+<li><p>Consider using facilities in the
+          <tt class="computeroutput">tools/common</tt> module. You can take a look at how
+          <tt class="computeroutput">tools/gcc.jam</tt> uses that module in the <tt class="computeroutput">init</tt> rule.
+          </p></li>
+</ul></div>
+</div>
+<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
+<td align="left"></td>
+<td align="right"><small></small></td>
+</tr></table>
+<hr>
+<div class="spirit-nav">
+<a accesskey="p" href="rules.html"><img src="../../images/prev.png" alt="Prev"></a><a accesskey="u" href="../extender.html"><img src="../../images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../images/home.png" alt="Home"></a><a accesskey="n" href="../reference.html"><img src="../../images/next.png" alt="Next"></a>
+</div>
+</body>
+</html>

Added: boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/faq/dll-path.html
===================================================================
--- boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/faq/dll-path.html	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/faq/dll-path.html	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,97 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+<title>Why are the dll-path and
+    hardcode-dll-paths properties useful?
+    </title>
+<link rel="stylesheet" href="../../boostbook.css" type="text/css">
+<meta name="generator" content="DocBook XSL Stylesheets V1.61.3">
+<link rel="home" href="../../index.html" title="Part I. Boost.Build v2 User Manual">
+<link rel="up" href="../faq.html" title="Chapter 7. Frequently Asked Questions">
+<link rel="previous" href="s07.html" title="How to change compilation flags for one file?
+    ">
+<link rel="next" href="../recipies/site-config.html" title="Targets in site-config.jam">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<table cellpadding="2" width="100%"><td valign="top"><img alt="boost.png (6897 bytes)" width="277" height="86" src="../../../../boost.png"></td></table>
+<hr>
+<div class="spirit-nav">
+<a accesskey="p" href="s07.html"><img src="../../images/prev.png" alt="Prev"></a><a accesskey="u" href="../faq.html"><img src="../../images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../images/home.png" alt="Home"></a><a accesskey="n" href="../recipies/site-config.html"><img src="../../images/next.png" alt="Next"></a>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div><div><h2 class="title" style="clear: both">
+<a name="bbv2.faq.dll-path"></a>Why are the <tt class="computeroutput">dll-path</tt> and
+    <tt class="computeroutput">hardcode-dll-paths</tt> properties useful?
+    </h2></div></div>
+<div></div>
+</div>
+<p>(This entry is specific to Unix system.)Before answering the
+      questions, let's recall a few points about shared libraries. Shared
+      libraries can be used by several applications, or other libraries,
+      without phisycally including the library in the application. This can
+      greatly decrease the total size of applications. It's also possible to
+      upgrade a shared library when the application is already
+      installed. Finally, shared linking can be faster.
+    </p>
+<p>However, the shared library must be found when the application is
+      started. The dynamic linker will search in a system-defined list of
+      paths, load the library and resolve the symbols. Which means that you
+      should either change the system-defined list, given by the
+      <tt class="envar">LD_LIBRARY_PATH</tt> environment variable, or install the
+      libraries to a system location. This can be inconvenient when
+      developing, since the libraries are not yet ready to be installed, and
+      cluttering system paths is undesirable. Luckily, on Unix there's another
+      way.
+    </p>
+<p>An executable can include a list of additional library paths, which
+      will be searched before system paths. This is excellent for development,
+      because the build system knows the paths to all libraries and can include
+      them in executables. That's done when the <tt class="computeroutput">hardcode-dll-paths</tt>
+      feature has the <tt class="literal">true</tt> value, which is the
+      default. When the executables should be installed, the story is
+      different.
+    </p>
+<p>
+      Obviously, installed executable should not hardcode paths to your
+      development tree. (The <tt class="computeroutput">stage</tt> rule explicitly disables the
+      <tt class="computeroutput">hardcode-dll-paths</tt> feature for that reason.) However, you
+      can use the <tt class="computeroutput">dll-path</tt> feature to add explicit paths
+      manually. For example:
+</p>
+<pre class="programlisting">
+stage installed : application : &lt;dll-path&gt;/usr/lib/snake
+                                &lt;location&gt;/usr/bin ;          
+</pre>
+<p>
+      will allow the application to find libraries placed to
+      <tt class="filename">/usr/lib/snake</tt>.
+    </p>
+<p>If you install libraries to a nonstandard location and add an
+      explicit path, you get more control over libraries which will be used. A
+      library of the same name in a system location will not be inadvertently
+      used.  If you install libraries to a system location and do not add any
+      paths, the system administrator will have more control. Each library can
+      be individually upgraded, and all applications will use the new library.
+    </p>
+<p>Which approach is best depends on your situation. If the libraries
+      are relatively standalone and can be used by third party applications,
+      they should be installed in the system location. If you have lots of
+      libraries which can be used only by our application, it makes sense to
+      install it to a nonstandard directory and add an explicit path, like the
+      example above shows. Please also note that guidelines for different
+      systems differ in this respect. The Debian guidelines prohibit any
+      additional search paths, and Solaris guidelines suggest that they should
+      always be used.
+    </p>
+</div>
+<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
+<td align="left"></td>
+<td align="right"><small></small></td>
+</tr></table>
+<hr>
+<div class="spirit-nav">
+<a accesskey="p" href="s07.html"><img src="../../images/prev.png" alt="Prev"></a><a accesskey="u" href="../faq.html"><img src="../../images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../images/home.png" alt="Home"></a><a accesskey="n" href="../recipies/site-config.html"><img src="../../images/next.png" alt="Next"></a>
+</div>
+</body>
+</html>

Added: boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/faq/external.html
===================================================================
--- boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/faq/external.html	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/faq/external.html	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,64 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+<title>Can I get output of external program as a variable in a Jamfile?
+    </title>
+<link rel="stylesheet" href="../../boostbook.css" type="text/css">
+<meta name="generator" content="DocBook XSL Stylesheets V1.61.3">
+<link rel="home" href="../../index.html" title="Part I. Boost.Build v2 User Manual">
+<link rel="up" href="../faq.html" title="Chapter 7. Frequently Asked Questions">
+<link rel="previous" href="s04.html" title="
+      How to control the library order on Unix?
+    ">
+<link rel="next" href="s06.html" title="How to get the project-root location?
+    ">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<table cellpadding="2" width="100%"><td valign="top"><img alt="boost.png (6897 bytes)" width="277" height="86" src="../../../../boost.png"></td></table>
+<hr>
+<div class="spirit-nav">
+<a accesskey="p" href="s04.html"><img src="../../images/prev.png" alt="Prev"></a><a accesskey="u" href="../faq.html"><img src="../../images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../images/home.png" alt="Home"></a><a accesskey="n" href="s06.html"><img src="../../images/next.png" alt="Next"></a>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div><div><h2 class="title" style="clear: both">
+<a name="bbv2.faq.external"></a>Can I get output of external program as a variable in a Jamfile?
+    </h2></div></div>
+<div></div>
+</div>
+<p>From time to time users ask how to run an external program and save
+    the result in Jamfile variable, something like:
+</p>
+<pre class="programlisting">
+local gtk_includes = [ RUN_COMMAND gtk-config ] ;
+</pre>
+<p>
+      Unfortunately, this is not possible at the moment. However, if the
+      result of command invocation is to be used in a command to some tool,
+      and you're working on Unix, the following workaround is possible.
+</p>
+<pre class="programlisting">
+ alias gtk+-2.0 : : : :
+         &lt;cflags&gt;"`pkg-config --cflags gtk+-2.0`"
+         &lt;inkflags&gt;"`pkg-config --libs gtk+-2.0`"
+     ;
+</pre>
+<p>
+      If you use the "gtk+-2.0" target in sources, then the properties
+      specified above will be added to the build properties and eventually
+      will appear in the command line. Unix command line shell processes
+      the backticks quoting by running the tool and using its output --
+      which is what's desired in that case. Thanks to Daniel James for
+      sharing this approach.
+    </p>
+</div>
+<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
+<td align="left"></td>
+<td align="right"><small></small></td>
+</tr></table>
+<hr>
+<div class="spirit-nav">
+<a accesskey="p" href="s04.html"><img src="../../images/prev.png" alt="Prev"></a><a accesskey="u" href="../faq.html"><img src="../../images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../images/home.png" alt="Home"></a><a accesskey="n" href="s06.html"><img src="../../images/next.png" alt="Next"></a>
+</div>
+</body>
+</html>

Added: boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/faq/s02.html
===================================================================
--- boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/faq/s02.html	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/faq/s02.html	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,59 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+<title>
+      Accessing environment variables
+      </title>
+<link rel="stylesheet" href="../../boostbook.css" type="text/css">
+<meta name="generator" content="DocBook XSL Stylesheets V1.61.3">
+<link rel="home" href="../../index.html" title="Part I. Boost.Build v2 User Manual">
+<link rel="up" href="../faq.html" title="Chapter 7. Frequently Asked Questions">
+<link rel="previous" href="../faq.html" title="Chapter 7. Frequently Asked Questions">
+<link rel="next" href="s03.html" title="
+        How to control properties order?
+      ">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<table cellpadding="2" width="100%"><td valign="top"><img alt="boost.png (6897 bytes)" width="277" height="86" src="../../../../boost.png"></td></table>
+<hr>
+<div class="spirit-nav">
+<a accesskey="p" href="../faq.html"><img src="../../images/prev.png" alt="Prev"></a><a accesskey="u" href="../faq.html"><img src="../../images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../images/home.png" alt="Home"></a><a accesskey="n" href="s03.html"><img src="../../images/next.png" alt="Next"></a>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div><div><h2 class="title" style="clear: both">
+<a name="id2540896"></a>
+      Accessing environment variables
+      </h2></div></div>
+<div></div>
+</div>
+<p>    
+      Many users would like to use environment variables in Jamfiles, for
+      example, to control location of external libraries. In many cases you
+      better declare those external libraries in the site-config.jam file, as
+      documented in the <a href="../recipies/site-config.html" title="Targets in site-config.jam">recipes
+      section</a>. However, if the users already have the environment variables set
+      up, it's not convenient to ask them to set up site-config.jam files as
+      well, and using environment variables might be reasonable.
+    </p>
+<p>In Boost.Build V2, each Jamfile is a separate namespace, and the
+    variables defined in environment is imported into the global
+    namespace. Therefore, to access environment variable from Jamfile, you'd
+    need the following code:
+</p>
+<pre class="programlisting">
+import modules ;
+local SOME_LIBRARY_PATH = [ modules.peek : SOME_LIBRARY_PATH ] ;
+exe a : a.cpp : &lt;include&gt;$(SOME_LIBRARY_PATH) ;
+</pre>
+</div>
+<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
+<td align="left"></td>
+<td align="right"><small></small></td>
+</tr></table>
+<hr>
+<div class="spirit-nav">
+<a accesskey="p" href="../faq.html"><img src="../../images/prev.png" alt="Prev"></a><a accesskey="u" href="../faq.html"><img src="../../images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../images/home.png" alt="Home"></a><a accesskey="n" href="s03.html"><img src="../../images/next.png" alt="Next"></a>
+</div>
+</body>
+</html>

Added: boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/faq/s03.html
===================================================================
--- boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/faq/s03.html	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/faq/s03.html	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,67 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+<title>
+        How to control properties order?
+      </title>
+<link rel="stylesheet" href="../../boostbook.css" type="text/css">
+<meta name="generator" content="DocBook XSL Stylesheets V1.61.3">
+<link rel="home" href="../../index.html" title="Part I. Boost.Build v2 User Manual">
+<link rel="up" href="../faq.html" title="Chapter 7. Frequently Asked Questions">
+<link rel="previous" href="s02.html" title="
+      Accessing environment variables
+      ">
+<link rel="next" href="s04.html" title="
+      How to control the library order on Unix?
+    ">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<table cellpadding="2" width="100%"><td valign="top"><img alt="boost.png (6897 bytes)" width="277" height="86" src="../../../../boost.png"></td></table>
+<hr>
+<div class="spirit-nav">
+<a accesskey="p" href="s02.html"><img src="../../images/prev.png" alt="Prev"></a><a accesskey="u" href="../faq.html"><img src="../../images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../images/home.png" alt="Home"></a><a accesskey="n" href="s04.html"><img src="../../images/next.png" alt="Next"></a>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div><div><h2 class="title" style="clear: both">
+<a name="id2540933"></a>
+        How to control properties order?
+      </h2></div></div>
+<div></div>
+</div>
+<p>For internal reasons, Boost.Build sorts all the properties
+    alphabetically. This means that if you write:
+</p>
+<pre class="programlisting">
+exe a : a.cpp : &lt;include&gt;b &lt;include&gt;a ;
+</pre>
+<p>
+      then the command line with first mention the "a" include directory, and
+      then "b", even though they are specified in the opposite order. In most
+      cases, the user doesn't care. But sometimes the order of includes, or
+      other properties, is important. For example, if one uses both the C++
+      Boost library and the "boost-sandbox" (libraries in development), then
+      include path for boost-sandbox must come first, because some headers may
+      override ones in C++ Boost. For such cases, a special syntax is
+      provided:
+</p>
+<pre class="programlisting">
+exe a : a.cpp : &lt;include&gt;a&amp;&amp;b ;        
+</pre>
+<p>The <tt class="computeroutput">&amp;&amp;</tt> symbols separate values of an
+      property, and specify that the order of the values should be preserved. You
+      are advised to use this feature only when the order of properties really
+      matters, and not as a convenient shortcut. Using it everywhere might
+      negatively affect performance.
+    </p>
+</div>
+<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
+<td align="left"></td>
+<td align="right"><small></small></td>
+</tr></table>
+<hr>
+<div class="spirit-nav">
+<a accesskey="p" href="s02.html"><img src="../../images/prev.png" alt="Prev"></a><a accesskey="u" href="../faq.html"><img src="../../images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../images/home.png" alt="Home"></a><a accesskey="n" href="s04.html"><img src="../../images/next.png" alt="Next"></a>
+</div>
+</body>
+</html>

Added: boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/faq/s04.html
===================================================================
--- boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/faq/s04.html	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/faq/s04.html	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,69 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+<title>
+      How to control the library order on Unix?
+    </title>
+<link rel="stylesheet" href="../../boostbook.css" type="text/css">
+<meta name="generator" content="DocBook XSL Stylesheets V1.61.3">
+<link rel="home" href="../../index.html" title="Part I. Boost.Build v2 User Manual">
+<link rel="up" href="../faq.html" title="Chapter 7. Frequently Asked Questions">
+<link rel="previous" href="s03.html" title="
+        How to control properties order?
+      ">
+<link rel="next" href="external.html" title="Can I get output of external program as a variable in a Jamfile?
+    ">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<table cellpadding="2" width="100%"><td valign="top"><img alt="boost.png (6897 bytes)" width="277" height="86" src="../../../../boost.png"></td></table>
+<hr>
+<div class="spirit-nav">
+<a accesskey="p" href="s03.html"><img src="../../images/prev.png" alt="Prev"></a><a accesskey="u" href="../faq.html"><img src="../../images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../images/home.png" alt="Home"></a><a accesskey="n" href="external.html"><img src="../../images/next.png" alt="Next"></a>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div><div><h2 class="title" style="clear: both">
+<a name="id2540977"></a>
+      How to control the library order on Unix?
+    </h2></div></div>
+<div></div>
+</div>
+<p>On the Unix-like operating systems, the order in which static
+      libraries are specified when invoking the linker is important, because by
+      default, the linker uses one pass though the libraries list. Passing the
+      libraries in the incorrect order will lead to a link error. Further, this
+      behaviour is often used to make one library override symbols from
+      another. So, sometimes it's necessary to force specific order of
+      libraries.    
+    </p>
+<p>Boost.Build tries to automatically compute the right order.  The
+      primary rule is that if library a "uses" library b, then library a will
+      appear on the command line before library b. Library a is considered to
+      use b is b is present either in the sources of a or in its
+      requirements. To explicitly specify the use relationship one can use the
+      &lt;use&gt; feature. For example, both of the following lines will cause
+      a to appear before b on the command line:
+</p>
+<pre class="programlisting">
+lib a : a.cpp b ;
+lib a : a.cpp : &lt;use&gt;b ;
+</pre>
+<p>
+      The same approach works for searched libraries, too:
+</p>
+<pre class="programlisting">
+lib z ;
+lib png : : &lt;use&gt;z ;
+exe viewer : viewer png z ;
+</pre>
+</div>
+<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
+<td align="left"></td>
+<td align="right"><small></small></td>
+</tr></table>
+<hr>
+<div class="spirit-nav">
+<a accesskey="p" href="s03.html"><img src="../../images/prev.png" alt="Prev"></a><a accesskey="u" href="../faq.html"><img src="../../images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../images/home.png" alt="Home"></a><a accesskey="n" href="external.html"><img src="../../images/next.png" alt="Next"></a>
+</div>
+</body>
+</html>

Added: boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/faq/s06.html
===================================================================
--- boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/faq/s06.html	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/faq/s06.html	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,48 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+<title>How to get the project-root location?
+    </title>
+<link rel="stylesheet" href="../../boostbook.css" type="text/css">
+<meta name="generator" content="DocBook XSL Stylesheets V1.61.3">
+<link rel="home" href="../../index.html" title="Part I. Boost.Build v2 User Manual">
+<link rel="up" href="../faq.html" title="Chapter 7. Frequently Asked Questions">
+<link rel="previous" href="external.html" title="Can I get output of external program as a variable in a Jamfile?
+    ">
+<link rel="next" href="s07.html" title="How to change compilation flags for one file?
+    ">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<table cellpadding="2" width="100%"><td valign="top"><img alt="boost.png (6897 bytes)" width="277" height="86" src="../../../../boost.png"></td></table>
+<hr>
+<div class="spirit-nav">
+<a accesskey="p" href="external.html"><img src="../../images/prev.png" alt="Prev"></a><a accesskey="u" href="../faq.html"><img src="../../images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../images/home.png" alt="Home"></a><a accesskey="n" href="s07.html"><img src="../../images/next.png" alt="Next"></a>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div><div><h2 class="title" style="clear: both">
+<a name="id2541063"></a>How to get the project-root location?
+    </h2></div></div>
+<div></div>
+</div>
+<p>You might want to use the location of the project-root in your
+      Jamfiles. To do it, you'd need to declare path constant in your
+      project-root.jam:
+</p>
+<pre class="programlisting">
+path-constant TOP : . ;
+</pre>
+<p>
+      After that, the <tt class="computeroutput">TOP</tt> variable can be used in every Jamfile.
+    </p>
+</div>
+<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
+<td align="left"></td>
+<td align="right"><small></small></td>
+</tr></table>
+<hr>
+<div class="spirit-nav">
+<a accesskey="p" href="external.html"><img src="../../images/prev.png" alt="Prev"></a><a accesskey="u" href="../faq.html"><img src="../../images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../images/home.png" alt="Home"></a><a accesskey="n" href="s07.html"><img src="../../images/next.png" alt="Next"></a>
+</div>
+</body>
+</html>

Added: boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/faq/s07.html
===================================================================
--- boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/faq/s07.html	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/faq/s07.html	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,63 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+<title>How to change compilation flags for one file?
+    </title>
+<link rel="stylesheet" href="../../boostbook.css" type="text/css">
+<meta name="generator" content="DocBook XSL Stylesheets V1.61.3">
+<link rel="home" href="../../index.html" title="Part I. Boost.Build v2 User Manual">
+<link rel="up" href="../faq.html" title="Chapter 7. Frequently Asked Questions">
+<link rel="previous" href="s06.html" title="How to get the project-root location?
+    ">
+<link rel="next" href="dll-path.html" title="Why are the dll-path and
+    hardcode-dll-paths properties useful?
+    ">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<table cellpadding="2" width="100%"><td valign="top"><img alt="boost.png (6897 bytes)" width="277" height="86" src="../../../../boost.png"></td></table>
+<hr>
+<div class="spirit-nav">
+<a accesskey="p" href="s06.html"><img src="../../images/prev.png" alt="Prev"></a><a accesskey="u" href="../faq.html"><img src="../../images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../images/home.png" alt="Home"></a><a accesskey="n" href="dll-path.html"><img src="../../images/next.png" alt="Next"></a>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div><div><h2 class="title" style="clear: both">
+<a name="id2541085"></a>How to change compilation flags for one file?
+    </h2></div></div>
+<div></div>
+</div>
+<p>If one file must be compiled with special options, you need to
+      explicitly declare an <tt class="computeroutput">obj</tt> target for that file and then use
+      that target in your <tt class="computeroutput">exe</tt> or <tt class="computeroutput">lib</tt> target:
+</p>
+<pre class="programlisting">
+exe a : a.cpp b ;
+obj b : b.cpp : &lt;optimization&gt;off ;
+</pre>
+<p>
+      Of course you can use other properties, for example to specify specific
+      compiler options:
+</p>
+<pre class="programlisting">
+exe a : a.cpp b ;
+obj b : b.cpp : &lt;cflags&gt;-g ;
+</pre>
+<p>
+      You can also use <a href="../tutorial/conditions.html" title="Conditions and alternatives">conditional
+      properties</a> for finer control:
+</p>
+<pre class="programlisting">
+exe a : a.cpp b ;
+obj b : b.cpp : &lt;variant&gt;release:&lt;optimization&gt;off ;
+</pre>
+</div>
+<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
+<td align="left"></td>
+<td align="right"><small></small></td>
+</tr></table>
+<hr>
+<div class="spirit-nav">
+<a accesskey="p" href="s06.html"><img src="../../images/prev.png" alt="Prev"></a><a accesskey="u" href="../faq.html"><img src="../../images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../images/home.png" alt="Home"></a><a accesskey="n" href="dll-path.html"><img src="../../images/next.png" alt="Next"></a>
+</div>
+</body>
+</html>

Added: boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/faq.html
===================================================================
--- boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/faq.html	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/faq.html	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,139 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+<title>Chapter 7. Frequently Asked Questions</title>
+<link rel="stylesheet" href="../boostbook.css" type="text/css">
+<meta name="generator" content="DocBook XSL Stylesheets V1.61.3">
+<link rel="home" href="../index.html" title="Part I. Boost.Build v2 User Manual">
+<link rel="up" href="../index.html" title="Part I. Boost.Build v2 User Manual">
+<link rel="previous" href="reference/generators.html" title="Generators">
+<link rel="next" href="faq/s02.html" title="
+      Accessing environment variables
+      ">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<table cellpadding="2" width="100%"><td valign="top"><img alt="boost.png (6897 bytes)" width="277" height="86" src="../../../boost.png"></td></table>
+<hr>
+<div class="spirit-nav">
+<a accesskey="p" href="reference/generators.html"><img src="../images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../images/home.png" alt="Home"></a><a accesskey="n" href="faq/s02.html"><img src="../images/next.png" alt="Next"></a>
+</div>
+<div class="chapter" lang="en">
+<div class="titlepage">
+<div><div><h2 class="title">
+<a name="bbv2.faq"></a>Chapter 7. Frequently Asked Questions</h2></div></div>
+<div></div>
+</div>
+<div class="toc">
+<p><b>Table of Contents</b></p>
+<dl>
+<dt><a href="faq.html#id2540813">
+        I'm getting "Duplicate name of actual target" error. What
+        does it mean?
+      </a></dt>
+<dt><a href="faq/s02.html">
+      Accessing environment variables
+      </a></dt>
+<dt><a href="faq/s03.html">
+        How to control properties order?
+      </a></dt>
+<dt><a href="faq/s04.html">
+      How to control the library order on Unix?
+    </a></dt>
+<dt><a href="faq/external.html">Can I get output of external program as a variable in a Jamfile?
+    </a></dt>
+<dt><a href="faq/s06.html">How to get the project-root location?
+    </a></dt>
+<dt><a href="faq/s07.html">How to change compilation flags for one file?
+    </a></dt>
+<dt><a href="faq/dll-path.html">Why are the dll-path and
+    hardcode-dll-paths properties useful?
+    </a></dt>
+<dt><a href="recipies/site-config.html">Targets in site-config.jam</a></dt>
+</dl>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div><div><h2 class="title" style="clear: both">
+<a name="id2540813"></a>
+        I'm getting "Duplicate name of actual target" error. What
+        does it mean?
+      </h2></div></div>
+<div></div>
+</div>
+<p>    
+    The most likely case is that you're trying to
+    compile the same file twice, with almost the same,
+    but differing properties. For example:
+
+</p>
+<pre class="programlisting">
+exe a : a.cpp : &lt;include&gt;/usr/local/include ;
+exe b : a.cpp ;
+</pre>
+<p>
+    The above snippet requires two different compilations
+    of 'a.cpp', which differ only in 'include' property.
+    Since the 'include' property is free, Boost.Build
+    can't generate two objects files into different directories.
+    On the other hand, it's dangerous to compile the file only
+    once -- maybe you really want to compile with different
+    includes.
+    </p>
+<p>
+    To solve this issue, you need to decide if file should
+    be compiled once or twice.</p>
+<div class="orderedlist"><ol type="1">
+<li>
+<p>Two compile file only once, make sure that properties
+      are the same:
+
+</p>
+<pre class="programlisting">
+exe a : a.cpp : &lt;include&gt;/usr/local/include ;
+exe b : a.cpp : &lt;include&gt;/usr/local/include ;
+</pre>
+</li>
+<li>
+<p>
+      If changing the properties is not desirable, for example
+      if 'a' and 'b' target have other sources which need
+      specific properties, separate 'a.cpp' into it's own target:
+
+</p>
+<pre class="programlisting">
+obj a_obj : a.cpp : &lt;include&gt;/usr/local/include ;
+exe a : a_obj ;
+</pre>
+</li>
+<li>
+<p>
+      To compile file twice, you can make the object file local
+      to the main target:
+
+</p>
+<pre class="programlisting">
+      exe a : [ obj a_obj : a.cpp ] : &lt;include&gt;/usr/local/include ;
+      exe b : [ obj a_obj : a.cpp ] ;
+</pre>
+</li>
+</ol></div>
+<p>
+   A good question is why Boost.Build can't use some of the above
+   approaches automatically. The problem is that such magic would
+   require additional implementation complexities and would only
+   help in half of the cases, while in other half we'd be silently
+   doing the wrong thing. It's simpler and safe to ask user to
+   clarify his intention in such cases.
+   </p>
+</div>
+</div>
+<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
+<td align="left"></td>
+<td align="right"><small></small></td>
+</tr></table>
+<hr>
+<div class="spirit-nav">
+<a accesskey="p" href="reference/generators.html"><img src="../images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../images/home.png" alt="Home"></a><a accesskey="n" href="faq/s02.html"><img src="../images/next.png" alt="Next"></a>
+</div>
+</body>
+</html>

Added: boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/howto.html
===================================================================
--- boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/howto.html	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/howto.html	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,53 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+<title>Chapter 1. How to use this document</title>
+<link rel="stylesheet" href="../boostbook.css" type="text/css">
+<meta name="generator" content="DocBook XSL Stylesheets V1.61.3">
+<link rel="home" href="../index.html" title="Part I. Boost.Build v2 User Manual">
+<link rel="up" href="../index.html" title="Part I. Boost.Build v2 User Manual">
+<link rel="previous" href="../index.html" title="Part I. Boost.Build v2 User Manual">
+<link rel="next" href="installation.html" title="Chapter 2. Installation">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<table cellpadding="2" width="100%"><td valign="top"><img alt="boost.png (6897 bytes)" width="277" height="86" src="../../../boost.png"></td></table>
+<hr>
+<div class="spirit-nav">
+<a accesskey="p" href="../index.html"><img src="../images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../images/home.png" alt="Home"></a><a accesskey="n" href="installation.html"><img src="../images/next.png" alt="Next"></a>
+</div>
+<div class="chapter" lang="en">
+<div class="titlepage">
+<div><div><h2 class="title">
+<a name="bbv2.howto"></a>Chapter 1. How to use this document</h2></div></div>
+<div></div>
+</div>
+<p>
+      If you've just found out about Boost.Build V2 and want to know
+      if it will work for you, start with <a href="tutorial.html" title="Chapter 3. Tutorial">Chapter 3, <i>Tutorial</i></a>. You can continue with the <a href="advanced.html" title="Chapter 4. User documentation">Chapter 4, <i>User documentation</i></a>. When you're ready to try Boost.Build
+      in practice, go to <a href="installation.html" title="Chapter 2. Installation">Chapter 2, <i>Installation</i></a>.
+    </p>
+<p>
+      If you are about to use Boost.Build on your project, or already
+      using it and have a problem, look at <a href="advanced.html" title="Chapter 4. User documentation">Chapter 4, <i>User documentation</i></a>.
+    </p>
+<p>
+      If you're trying to build a project which uses Boost.Build,
+      look at <a href="installation.html" title="Chapter 2. Installation">Chapter 2, <i>Installation</i></a> and then read about
+      <a href="reference.html#bbv2.reference.commandline" title="Command line">the section called &#8220;Command line&#8221;</a>.
+    </p>
+<p>
+      If you have questions, please post them to our <a href="../../../../more/mailing_lists.htm#jamboost" target="_top">mailing
+      list</a>, and be sure to indicate in the subject line that
+      you're asking about Boost.Build <span class="bold"><b>V2</b></span>.
+    </p>
+</div>
+<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
+<td align="left"></td>
+<td align="right"><small></small></td>
+</tr></table>
+<hr>
+<div class="spirit-nav">
+<a accesskey="p" href="../index.html"><img src="../images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../images/home.png" alt="Home"></a><a accesskey="n" href="installation.html"><img src="../images/next.png" alt="Next"></a>
+</div>
+</body>
+</html>

Added: boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/installation.html
===================================================================
--- boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/installation.html	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/installation.html	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,131 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+<title>Chapter 2. Installation</title>
+<link rel="stylesheet" href="../boostbook.css" type="text/css">
+<meta name="generator" content="DocBook XSL Stylesheets V1.61.3">
+<link rel="home" href="../index.html" title="Part I. Boost.Build v2 User Manual">
+<link rel="up" href="../index.html" title="Part I. Boost.Build v2 User Manual">
+<link rel="previous" href="howto.html" title="Chapter 1. How to use this document">
+<link rel="next" href="tutorial.html" title="Chapter 3. Tutorial">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<table cellpadding="2" width="100%"><td valign="top"><img alt="boost.png (6897 bytes)" width="277" height="86" src="../../../boost.png"></td></table>
+<hr>
+<div class="spirit-nav">
+<a accesskey="p" href="howto.html"><img src="../images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../images/home.png" alt="Home"></a><a accesskey="n" href="tutorial.html"><img src="../images/next.png" alt="Next"></a>
+</div>
+<div class="chapter" lang="en">
+<div class="titlepage">
+<div><div><h2 class="title">
+<a name="bbv2.installation"></a>Chapter 2. Installation</h2></div></div>
+<div></div>
+</div>
+<p>
+      This section describes how to install Boost.Build from a
+      released source distribution. All paths are given relative to
+      the <i class="firstterm">Boost.Build v2 root directory</i>, which is 
+
+      
+
+      located in the <tt class="filename">tools/build/v2</tt> subdirectory
+      of a full <a href="http://www.boost.org" target="_top">Boost</a>
+      distribution.
+    </p>
+<div class="orderedlist"><ol type="1">
+<li>
+          Boost.Build uses <a href="../jam_src/index.html" target="_top">Boost.Jam</a>, an
+          extension of the <a href="http://www.perforce.com/jam/jam.html" target="_top">Perforce
+          Jam</a> portable <b class="command">make</b> replacement. The
+          recommended way to get Boost.Jam is to <span class="bold"><b><a href="http://sourceforge.net/project/showfiles.php?group_id=7586&amp;package_id=72941" target="_top">download
+          a prebuilt executable</a></b></span> from SourceForge.
+          If a prebuilt executable is not provided for your platform
+          or you are using Boost's sources in an unreleased state, it
+          may be neccessary to <a href="../../jam_src/index.html#building_bjam" target="_top">build <b class="command">bjam</b>
+          from sources</a> included in the Boost source tree.
+        </li>
+<li>
+<p>
+
+          To install Boost.Jam, copy the executable,
+          called <b class="command">bjam</b>
+          or <b class="command">bjam.exe</b> to a location accessible in
+          your <tt class="envar">PATH</tt>.  Go to the Boost.Build root
+          directory and
+          run <b class="command">bjam <tt class="option">--version</tt></b>. You
+          should see:
+
+          </p>
+<pre class="screen">
+            Boost.Build V2 (Milestone N)
+            Boost.Jam xx.xx.xx 
+          </pre>
+<p>
+
+          where N is the version of Boost.Build you're using.
+        </p>
+</li>
+<li>
+          Configure Boost.Build to recognize the build resources (such
+          as compilers and libraries) you have installed on your
+          system.  Open the
+          <tt class="filename">user-config.jam</tt> file in the Boost.Build
+          root directory and follow the instructions there to describe
+          your toolsets and libraries, and, if neccessary, where they
+          are located.
+        </li>
+<li>
+          You should now be able to go to the
+          <tt class="filename">example/hello/</tt> directory and run
+          <b class="command">bjam</b> there. A simple application will be
+          built. You can also play with other projects in the
+          <tt class="filename">example/</tt> directory. 
+    </li>
+</ol></div>
+<p>
+      If you are using Boost's CVS state, be sure to
+      rebuild <b class="command">bjam</b> even if you have a previous
+      version.  The CVS version of Boost.Build requires the CVS
+      version of Boost.Jam.
+    </p>
+<p>
+      When <b class="command">bjam</b> is invoked, it always needs to be
+      able to find the Boost.Build root directory, where the
+      interpreted source code of Boost.Build is located.  There are
+      two ways to tell <b class="command">bjam</b> about the root directory:
+    </p>
+<div class="itemizedlist"><ul type="disc">
+<li>
+          Set the environment variable <tt class="envar">BOOST_BUILD_PATH</tt>
+          to the absolute path of the Boost.Build root directory.
+        </li>
+<li>
+<p>
+          At the root directory of your project or in any of its
+          parent directories, create a file called
+          <tt class="filename">boost-build.jam</tt>, with a single line:
+
+</p>
+<pre class="programlisting">
+boost-build <i class="replaceable"><tt>/path/to/boost.build</tt></i> ;
+</pre>
+</li>
+</ul></div>
+<p><span class="bold"><b>N.B.</b></span>
+  When <b class="command">bjam</b> is invoked from anywhere in the Boost
+  directory tree <span class="emphasis"><em>other than</em></span> the Boost.Build root
+  and its subdirectories, <a href="../../tools/build" target="_top">Boost.Build
+  v1</a> is used by default. To override the default and use
+  Boost.Build v2, you have to add the <tt class="option">--v2</tt> command
+  line option to all <b class="command">bjam</b> invocations.</p>
+</div>
+<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
+<td align="left"></td>
+<td align="right"><small></small></td>
+</tr></table>
+<hr>
+<div class="spirit-nav">
+<a accesskey="p" href="howto.html"><img src="../images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../images/home.png" alt="Home"></a><a accesskey="n" href="tutorial.html"><img src="../images/next.png" alt="Next"></a>
+</div>
+</body>
+</html>

Added: boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/recipies/site-config.html
===================================================================
--- boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/recipies/site-config.html	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/recipies/site-config.html	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,56 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+<title>Targets in site-config.jam</title>
+<link rel="stylesheet" href="../../boostbook.css" type="text/css">
+<meta name="generator" content="DocBook XSL Stylesheets V1.61.3">
+<link rel="home" href="../../index.html" title="Part I. Boost.Build v2 User Manual">
+<link rel="up" href="../faq.html" title="Chapter 7. Frequently Asked Questions">
+<link rel="previous" href="../faq/dll-path.html" title="Why are the dll-path and
+    hardcode-dll-paths properties useful?
+    ">
+<link rel="next" href="../arch.html" title="Appendix A. Boost.Build v2 architecture">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<table cellpadding="2" width="100%"><td valign="top"><img alt="boost.png (6897 bytes)" width="277" height="86" src="../../../../boost.png"></td></table>
+<hr>
+<div class="spirit-nav">
+<a accesskey="p" href="../faq/dll-path.html"><img src="../../images/prev.png" alt="Prev"></a><a accesskey="u" href="../faq.html"><img src="../../images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../images/home.png" alt="Home"></a><a accesskey="n" href="../arch.html"><img src="../../images/next.png" alt="Next"></a>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div><div><h2 class="title" style="clear: both">
+<a name="bbv2.recipies.site-config"></a>Targets in site-config.jam</h2></div></div>
+<div></div>
+</div>
+<p>It is desirable to declare standard libraries available on a
+      given system. Putting target declaration in Jamfile is not really
+      good, since locations of the libraries can vary. The solution is
+      to put the following to site-config.jam.</p>
+<pre class="programlisting">
+import project ;
+project.initialize $(__name__) ;
+project site-config ;
+lib zlib : : &lt;name&gt;z ;
+</pre>
+<p>The second line allows this module to act as project. The
+      third line gives id to this project &#8212; it really has no location
+      and cannot be used otherwise. The fourth line just declares a
+      target. Now, one can write:
+</p>
+<pre class="programlisting">
+exe hello : hello.cpp /site-config//zlib ;
+</pre>
+<p>
+      in any Jamfile.</p>
+</div>
+<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
+<td align="left"></td>
+<td align="right"><small></small></td>
+</tr></table>
+<hr>
+<div class="spirit-nav">
+<a accesskey="p" href="../faq/dll-path.html"><img src="../../images/prev.png" alt="Prev"></a><a accesskey="u" href="../faq.html"><img src="../../images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../images/home.png" alt="Home"></a><a accesskey="n" href="../arch.html"><img src="../../images/next.png" alt="Next"></a>
+</div>
+</body>
+</html>

Added: boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/reference/buildprocess.html
===================================================================
--- boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/reference/buildprocess.html	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/reference/buildprocess.html	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,134 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+<title>Build process</title>
+<link rel="stylesheet" href="../../boostbook.css" type="text/css">
+<meta name="generator" content="DocBook XSL Stylesheets V1.61.3">
+<link rel="home" href="../../index.html" title="Part I. Boost.Build v2 User Manual">
+<link rel="up" href="../reference.html" title="Chapter 6. Detailed reference">
+<link rel="previous" href="jamfiles.html" title="Writing Jamfiles">
+<link rel="next" href="definitions.html" title="">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<table cellpadding="2" width="100%"><td valign="top"><img alt="boost.png (6897 bytes)" width="277" height="86" src="../../../../boost.png"></td></table>
+<hr>
+<div class="spirit-nav">
+<a accesskey="p" href="jamfiles.html"><img src="../../images/prev.png" alt="Prev"></a><a accesskey="u" href="../reference.html"><img src="../../images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../images/home.png" alt="Home"></a><a accesskey="n" href="definitions.html"><img src="../../images/next.png" alt="Next"></a>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div><div><h2 class="title" style="clear: both">
+<a name="bbv2.reference.buildprocess"></a>Build process</h2></div></div>
+<div></div>
+</div>
+<div class="toc"><dl>
+<dt><a href="buildprocess.html#bbv2.reference.buildprocess.alternatives">Alternative selection</a></dt>
+<dt><a href="buildprocess.html#bbv2.reference.buildprocess.common">Determining common properties</a></dt>
+</dl></div>
+<p>The general overview of the build process was given in the 
+      <a href="../advanced/build_process.html" title="Build process">user documentation</a>.
+      This section provides additional details, and some specific rules.
+    </p>
+<p>To recap, building a target with specific properties includes the
+      following steps:
+      </p>
+<div class="orderedlist"><ol type="1">
+<li><p>applying default build,</p></li>
+<li><p>selecting the main target alternative to use,
+          </p></li>
+<li><p>determining "common" properties</p></li>
+<li><p>building targets referred by the sources list and
+            dependency properties</p></li>
+<li><p>adding the usage requirements produces when building
+            dependencies to the "common" properties</p></li>
+<li><p>building the target using generators</p></li>
+<li><p>computing the usage requirements to be returned</p></li>
+</ol></div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div><div><h3 class="title">
+<a name="bbv2.reference.buildprocess.alternatives"></a>Alternative selection</h3></div></div>
+<div></div>
+</div>
+<p>When there are several alternatives, one of them must be
+        selected. The process is as follows:</p>
+<div class="orderedlist"><ol type="1">
+<li>
+            For each alternative <span class="emphasis"><em>condition</em></span> is defined
+            as the set of base properies in requirements. [Note: it might be
+            better to specify the condition explicitly, as in
+            conditional requirements].
+          </li>
+<li>
+            An alternative is viable only if all properties in condition
+            are present in build request.
+          </li>
+<li>
+            If there's one viable alternative, it's choosen. Otherwise,
+            an attempt is made to find one best alternative. An alternative
+            a is better than another alternative b, iff set of properties
+            in b's condition is strict subset of the set of properities of
+            'a's condition. If there's one viable alternative, which is
+            better than all other, it's selected. Otherwise, an error is
+            reported.
+          </li>
+</ol></div>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div><div><h3 class="title">
+<a name="bbv2.reference.buildprocess.common"></a>Determining common properties</h3></div></div>
+<div></div>
+</div>
+<p>The "common" properties is a somewhat artificial term. Those are
+        the intermediate property set from which both the build request for
+        dependencies and properties for building the target are derived.
+      </p>
+<p>Since default build and alternatives are already handled, we have
+        only two inputs: build requests and requirements. Here are the rules
+        about common properties.
+      </p>
+<div class="orderedlist"><ol type="1">
+<li><p>Non-free feature can have only one
+            value</p></li>
+<li><p>A non-conditional property in requirement in always
+            present in common properties.</p></li>
+<li><p>A property in build request is present in
+            common properties, unless (2) tells otherwise.</p></li>
+<li><p>If either build request, or requirements (non-conditional
+            or conditional) include an expandable property (either composite,
+            or property with specified subfeature value), the behaviour is
+            equivalent to explicitly adding all expanded properties to build
+            request or requirements.</p></li>
+<li><p>If requirements include a conditional property, and
+            condiiton of this property is true in context of common
+            properties, then the conditional property should be in common
+            properties as well.</p></li>
+<li><p>If no value for a feature is given by other rules
+            here, it has default value in common properties.</p></li>
+</ol></div>
+<p>Those rules are declarative, they don't specify how to compute the
+        common properties. However, they provide enough information for the
+        user. The important point is the handling of conditional
+        requirements. The condition can be satisfied either by property in
+        build request, by non-conditional requirements, or even by another
+        conditional property. For example, the following example works as
+        expected:
+</p>
+<pre class="programlisting">
+exe a : a.cpp 
+      : &lt;toolset&gt;gcc:&lt;variant&gt;release 
+        &lt;variant&gt;release:&lt;define&gt;FOO ;
+</pre>
+</div>
+</div>
+<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
+<td align="left"></td>
+<td align="right"><small></small></td>
+</tr></table>
+<hr>
+<div class="spirit-nav">
+<a accesskey="p" href="jamfiles.html"><img src="../../images/prev.png" alt="Prev"></a><a accesskey="u" href="../reference.html"><img src="../../images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../images/home.png" alt="Home"></a><a accesskey="n" href="definitions.html"><img src="../../images/next.png" alt="Next"></a>
+</div>
+</body>
+</html>

Added: boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/reference/definitions.html
===================================================================
--- boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/reference/definitions.html	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/reference/definitions.html	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,391 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+<title></title>
+<link rel="stylesheet" href="../../boostbook.css" type="text/css">
+<meta name="generator" content="DocBook XSL Stylesheets V1.61.3">
+<link rel="home" href="../../index.html" title="Part I. Boost.Build v2 User Manual">
+<link rel="up" href="../reference.html" title="Chapter 6. Detailed reference">
+<link rel="previous" href="buildprocess.html" title="Build process">
+<link rel="next" href="generators.html" title="Generators">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<table cellpadding="2" width="100%"><td valign="top"><img alt="boost.png (6897 bytes)" width="277" height="86" src="../../../../boost.png"></td></table>
+<hr>
+<div class="spirit-nav">
+<a accesskey="p" href="buildprocess.html"><img src="../../images/prev.png" alt="Prev"></a><a accesskey="u" href="../reference.html"><img src="../../images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../images/home.png" alt="Home"></a><a accesskey="n" href="generators.html"><img src="../../images/next.png" alt="Next"></a>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div></div>
+<div></div>
+</div>
+<div class="toc"><dl>
+<dt><a href="definitions.html#bbv2.reference.features">Features and properties</a></dt>
+<dt><a href="definitions.html#bbv2.reference.variants">Build Variants</a></dt>
+<dt><a href="definitions.html#bbv2.reference.variants.proprefine">Property refinement</a></dt>
+<dt><a href="definitions.html#bbv2.reference.variants.propcond">Conditional properties</a></dt>
+<dt><a href="definitions.html#bbv2.reference.ids">Target identifiers and references</a></dt>
+</dl></div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div><div><h3 class="title">
+<a name="bbv2.reference.features"></a>Features and properties</h3></div></div>
+<div></div>
+</div>
+<div class="toc"><dl>
+<dt><a href="definitions.html#bbv2.reference.features.validity">Property Validity</a></dt>
+<dt><a href="definitions.html#bbv2.reference.features.attributes">Feature Attributes</a></dt>
+<dt><a href="definitions.html#bbv2.reference.features.declaration">Feature Declaration</a></dt>
+</dl></div>
+<p>A <span class="emphasis"><em>feature</em></span> is a normalized (toolset-independent)
+        aspect of a build configuration, such as whether inlining is
+        enabled. Feature names may not contain the '<tt class="literal">&gt;</tt>'
+        character.</p>
+<p>Each feature in a build configuration has one or more
+        associated <span class="emphasis"><em>value</em></span>s. Feature values for non-free features
+        may not contain the '<tt class="literal">&lt;</tt>', '<tt class="literal">:</tt>', or
+        '<tt class="literal">=</tt>' characters. Feature values for free features may not
+        contain the '<tt class="literal">&lt;</tt>' character.</p>
+<p>A <span class="emphasis"><em>property</em></span> is a (feature,value) pair, expressed as
+        &lt;feature&gt;value.</p>
+<p>A <span class="emphasis"><em>subfeature</em></span> is a feature which only exists in the
+        presence of its parent feature, and whose identity can be derived
+        (in the context of its parent) from its value. A subfeature's
+        parent can never be another subfeature. Thus, features and their
+        subfeatures form a two-level hierarchy.</p>
+<p>A <span class="emphasis"><em>value-string</em></span> for a feature <span class="bold"><b>F</b></span> is a string of
+        the form
+        <tt class="literal">value-subvalue1-subvalue2</tt>...<tt class="literal">-subvalueN</tt>, where
+        <tt class="literal">value</tt> is a legal value for <span class="bold"><b>F</b></span> and
+        <tt class="literal">subvalue1</tt>...<tt class="literal">subvalueN</tt> are legal values of some
+        of <span class="bold"><b>F</b></span>'s subfeatures. For example, the properties
+        <tt class="literal">&lt;toolset&gt;gcc &lt;toolset-version&gt;3.0.1</tt> can be
+        expressed more conscisely using a value-string, as
+        <tt class="literal">&lt;toolset&gt;gcc-3.0.1</tt>.</p>
+<p>A <span class="emphasis"><em>property set</em></span> is a set of properties (i.e. a
+        collection without duplicates), for instance:
+        <tt class="literal">&lt;toolset&gt;gcc &lt;runtime-link&gt;static</tt>.</p>
+<p>A <span class="emphasis"><em>property path</em></span> is a property set whose elements have
+        been joined into a single string separated by slashes. A property
+        path representation of the previous example would be
+        <tt class="literal">&lt;toolset&gt;gcc/&lt;runtime-link&gt;static</tt>.</p>
+<p>A <span class="emphasis"><em>build specification</em></span> is a property set which fully
+        describes the set of features used to build a target.</p>
+<div class="section" lang="en">
+<div class="titlepage">
+<div><div><h4 class="title">
+<a name="bbv2.reference.features.validity"></a>Property Validity</h4></div></div>
+<div></div>
+</div>
+<p>
+          For <a href="definitions.html#bbv2.reference.features.attributes.free">free</a>
+            features, all values are valid. For all other features,
+          the valid values are explicitly specified, and the build
+          system will report an error for the use of an invalid
+          feature-value. Subproperty validity may be restricted so
+          that certain values are valid only in the presence of
+          certain other subproperties. For example, it is possible
+          to specify that the <tt class="computeroutput">&lt;gcc-target&gt;mingw</tt>
+          property is only valid in the presence of
+          <tt class="computeroutput">&lt;gcc-version&gt;2.95.2</tt>.
+        </p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div><div><h4 class="title">
+<a name="bbv2.reference.features.attributes"></a>Feature Attributes</h4></div></div>
+<div></div>
+</div>
+<p>Each feature has a collection of zero or more of the following
+          attributes. Feature attributes are low-level descriptions of how the
+          build system should interpret a feature's values when they appear in
+          a build request. We also refer to the attributes of properties, so
+          that an <span class="emphasis"><em>incidental</em></span> property, for example, is
+          one whose feature has the <span class="emphasis"><em>incidental</em></span>
+          attribute.</p>
+<div class="itemizedlist"><ul type="disc">
+<li>
+<p><span class="emphasis"><em>incidental</em></span></p>
+<p>Incidental features are assumed not to affect build
+              products at all. As a consequence, the build system may use
+              the same file for targets whose build specification differs
+              only in incidental features. A feature which controls a
+              compiler's warning level is one example of a likely
+              incidental feature.</p>
+<p>Non-incidental features are assumed to affect build
+              products, so the files for targets whose build specification
+              differs in non-incidental features are placed in different
+              directories as described in "target paths" below. [ where? ]
+            </p>
+</li>
+<li>
+<p><a name="bbv2.reference.features.attributes.propagated"></a><span class="emphasis"><em>propagated</em></span></p>
+<p>Features of this kind are
+              propagated to dependencies. That is, if a <a href="../advanced/jamfiles.html#bbv2.advanced.targets.main">main target</a> is built using a
+              propagated
+              property, the build systems attempts to use the same property
+              when building any of its dependencies as part of that main
+              target. For instance, when an optimized exectuable is
+              requested, one usually wants it to be linked with optimized
+              libraries. Thus, the <tt class="literal">&lt;optimization&gt;</tt> feature is
+              propagated.</p>
+</li>
+<li>
+<p><a name="bbv2.reference.features.attributes.free"></a><span class="emphasis"><em>free</em></span></p>
+<p>Most features have a finite set of allowed values, and can
+              only take on a single value from that set in a given build
+              specification. Free features, on the other hand, can have
+              several values at a time and each value can be an arbitrary
+              string. For example, it is possible to have several
+              preprocessor symbols defined simultaneously:</p>
+<pre class="programlisting">
+&lt;define&gt;NDEBUG=1 &lt;define&gt;HAS_CONFIG_H=1
+</pre>
+</li>
+<li>
+<p><span class="emphasis"><em>optional</em></span></p>
+<p>An optional feature is a feature which is not required to
+              appear in a build specification. Every non-optional non-free
+              feature has a default value which is used when a value for
+              the feature is not otherwise specified, either in a target's
+              requirements or in the user's build request. [A feature's
+              default value is given by the first value listed in the
+              feature's declaration. -- move this elsewhere - dwa]</p>
+</li>
+<li>
+<p><span class="emphasis"><em>symmetric</em></span></p>
+<p>A symmetric feature's default value is not automatically
+              included in <a href="definitions.html#bbv2.reference.variants" title="Build Variants">build variants</a>.  Normally
+              a feature only generates a subvariant directory when its
+              value differs from the value specified by the build variant,
+              leading to an assymmetric subvariant directory structure for
+              certain values of the feature. A symmetric feature, when
+              relevant to the toolset, always generates a corresponding
+              subvariant directory.</p>
+</li>
+<li>
+<p><span class="emphasis"><em>path</em></span></p>
+<p>The value of a path feature specifies a path. The path is
+              treated as relative to the directory of Jamfile where path
+              feature is used and is translated appropriately by the build
+              system when the build is invoked from a different
+              directory</p>
+</li>
+<li>
+<p><span class="emphasis"><em>implicit</em></span></p>
+<p>Values of implicit features alone identify the feature.
+              For example, a user is not required to write
+              "&lt;toolset&gt;gcc", but can simply write "gcc". Implicit
+              feature names also don't appear in variant paths, although
+              the values do. Thus: bin/gcc/... as opposed to
+              bin/toolset-gcc/.... There should typically be only a few
+              such features, to avoid possible name clashes.</p>
+</li>
+<li>
+<p><span class="emphasis"><em>composite</em></span></p>
+<p>Composite features actually correspond to groups of
+              properties. For example, a build variant is a composite
+              feature. When generating targets from a set of build
+              properties, composite features are recursively expanded and
+              <span class="emphasis"><em>added</em></span> to the build property set, so rules can find
+              them if neccessary. Non-composite non-free features override
+              components of composite features in a build property set.</p>
+</li>
+<li>
+<p><span class="emphasis"><em>link-incompatible</em></span></p>
+<p>See <a href="../../">below</a>.</p>
+</li>
+<li>
+<p><span class="emphasis"><em>dependency</em></span></p>
+<p>The value of dependency feature if a target reference.
+              When used for building of a main target, the value of
+              dependency feature is treated as additional dependency.</p>
+<p>For example, dependency features allow to state that
+              library A depends on library B. As the result, whenever an
+              application will link to A, it will also link to B.
+              Specifying B as dependency of A is different from adding B to
+              the sources of A. </p>
+</li>
+</ul></div>
+<p>Features which are neither free nor incidental are called
+          <span class="emphasis"><em>base</em></span> features.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div><div><h4 class="title">
+<a name="bbv2.reference.features.declaration"></a>Feature Declaration</h4></div></div>
+<div></div>
+</div>
+<p>The low-level feature declaration interface is the
+          <tt class="literal">feature</tt> rule from the
+          <tt class="literal">feature</tt> module:
+          
+</p>
+<pre class="programlisting">
+rule feature ( name : allowed-values * : attributes * )
+</pre>
+<p>
+          
+          A feature's allowed-values may be extended with the
+          <tt class="computeroutput">feature.extend</tt> rule.
+        </p>
+</div>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div><div><h3 class="title">
+<a name="bbv2.reference.variants"></a>Build Variants</h3></div></div>
+<div></div>
+</div>
+<p>
+        A build variant, or (simply variant) is a special kind of composite
+        feature which automatically incorporates the default values of
+        features that . Typically you'll want at least two separate
+        variants: one for debugging, and one for your release code. [
+        Volodya says: "Yea, we'd need to mention that it's a composite
+        feature and describe how they are declared, in pacticular that
+        default values of non-optional features are incorporated into
+        build variant automagically. Also, do we wan't some variant
+        inheritance/extension/templates. I don't remember how it works in
+        V1, so can't document this for V2.". Will clean up soon -DWA ]
+      </p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div><div><h3 class="title">
+<a name="bbv2.reference.variants.proprefine"></a>Property refinement</h3></div></div>
+<div></div>
+</div>
+<p>When a target with certain properties is requested, and that
+        target requires some set of properties, it is needed to find the
+        set of properties to use for building. This process is called
+        <span class="emphasis"><em>property refinement</em></span> and is performed by these rules</p>
+<div class="orderedlist"><ol type="1">
+<li>
+            If original properties and required properties are not
+            link-compatible, refinement fails.
+          </li>
+<li>
+            Each property in the required set is added to the original
+            property set
+          </li>
+<li>
+            If the original property set includes property with a different
+            value of non free feature, that property is removed.
+          </li>
+</ol></div>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div><div><h3 class="title">
+<a name="bbv2.reference.variants.propcond"></a>Conditional properties</h3></div></div>
+<div></div>
+</div>
+<p>Sometime it's desirable to apply certain requirements only for
+        a specific combination of other properties. For example, one of
+        compilers that you use issues a pointless warning that you want to
+        suppress by passing a command line option to it. You would not
+        want to pass that option to other compilers. Conditional
+        properties allow you to do just that. Their syntax is:</p>
+<pre class="programlisting">
+        property ( "," property ) * ":" property
+      </pre>
+<p>
+        For example, the problem above would be solved by:
+
+</p>
+<pre class="programlisting">
+exe hello : hello.cpp : &lt;toolset&gt;yfc:&lt;cxxflags&gt;-disable-pointless-warning ;
+</pre>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div><div><h3 class="title">
+<a name="bbv2.reference.ids"></a>Target identifiers and references</h3></div></div>
+<div></div>
+</div>
+<p><span class="emphasis"><em>Target identifier</em></span> is used to denote a
+        target. The syntax is:</p>
+<pre class="programlisting">
+target-id -&gt; (project-id | target-name | file-name )
+              | (project-id | directory-name) "//" target-name   
+project-id -&gt; path
+target-name -&gt; path
+file-name -&gt; path
+directory-name -&gt; path                  
+</pre>
+<p>
+        This grammar allows some elements to be recognized as either
+        
+        </p>
+<div class="itemizedlist"><ul type="disc">
+<li>
+              project id (at this point, all project ids start with slash).
+            </li>
+<li>
+              name of target declared in current Jamfile (note that target
+              names may include slash).
+            </li>
+<li>
+              a regular file, denoted by absolute name or name relative to
+              project's sources location.
+            </li>
+</ul></div>
+<p>
+
+        To determine the real meaning a check is made if project-id
+        by the specified name exists, and then if main target of that
+        name exists. For example, valid target ids might be:
+
+</p>
+<pre class="screen">
+a                                    -- target in current project
+lib/b.cpp                            -- regular file
+/boost/thread                        -- project "/boost/thread"
+/home/ghost/build/lr_library//parser -- target in specific project
+</pre>
+<p><span class="bold"><b>Rationale:</b></span>Target is separated from project by special
+        separator (not just slash), because:</p>
+<div class="itemizedlist"><ul type="disc">
+<li>
+            It emphasises that projects and targets are different things.
+          </li>
+<li>
+            It allows to have main target names with slashes. 
+
+            </li>
+</ul></div>
+<p><a name="bbv2.reference.targets.references"></a><span class="emphasis"><em>Target reference</em></span> is used to
+        specify a source target, and may additionally specify desired
+        properties for that target. It has this syntax:</p>
+<pre class="programlisting">
+target-reference -&gt; target-id [ "/" requested-properties ]
+requested-properties -&gt; property-path
+</pre>
+<p>
+        For example,
+
+        </p>
+<pre class="programlisting">
+          exe compiler : compiler.cpp libs/cmdline/&lt;optimization&gt;space ;
+        </pre>
+<p>
+        
+        would cause the version of <tt class="literal">cmdline</tt> library,
+        optimized for space, to be linked in even if the
+        <tt class="literal">compiler</tt> executable is build with optimization for
+        speed.
+      </p>
+</div>
+</div>
+<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
+<td align="left"></td>
+<td align="right"><small></small></td>
+</tr></table>
+<hr>
+<div class="spirit-nav">
+<a accesskey="p" href="buildprocess.html"><img src="../../images/prev.png" alt="Prev"></a><a accesskey="u" href="../reference.html"><img src="../../images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../images/home.png" alt="Home"></a><a accesskey="n" href="generators.html"><img src="../../images/next.png" alt="Next"></a>
+</div>
+</body>
+</html>

Added: boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/reference/generators.html
===================================================================
--- boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/reference/generators.html	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/reference/generators.html	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,198 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+<title>Generators</title>
+<link rel="stylesheet" href="../../boostbook.css" type="text/css">
+<meta name="generator" content="DocBook XSL Stylesheets V1.61.3">
+<link rel="home" href="../../index.html" title="Part I. Boost.Build v2 User Manual">
+<link rel="up" href="../reference.html" title="Chapter 6. Detailed reference">
+<link rel="previous" href="definitions.html" title="">
+<link rel="next" href="../faq.html" title="Chapter 7. Frequently Asked Questions">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<table cellpadding="2" width="100%"><td valign="top"><img alt="boost.png (6897 bytes)" width="277" height="86" src="../../../../boost.png"></td></table>
+<hr>
+<div class="spirit-nav">
+<a accesskey="p" href="definitions.html"><img src="../../images/prev.png" alt="Prev"></a><a accesskey="u" href="../reference.html"><img src="../../images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../images/home.png" alt="Home"></a><a accesskey="n" href="../faq.html"><img src="../../images/next.png" alt="Next"></a>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div><div><h2 class="title" style="clear: both">
+<a name="bbv2.reference.generators"></a>Generators</h2></div></div>
+<div></div>
+</div>
+<div class="toc"><dl>
+<dt><a href="generators.html#id2540607">Selecting and ranking viable generators</a></dt>
+<dt><a href="generators.html#id2540667">Running generators</a></dt>
+<dt><a href="generators.html#id2540706">Selecting dependency graph</a></dt>
+<dt><a href="generators.html#id2540717">Property adjustment</a></dt>
+<dt><a href="generators.html#id2540792">Transformations cache</a></dt>
+</dl></div>
+<div class="warning" style="margin-left: 0.5in; margin-right: 0.5in;">
+<h3 class="title">Warning</h3>
+<p>The information is this section is likely to be outdated
+        and misleading. 
+      </p>
+</div>
+<p>To construct a main target with given properties from sources,
+      it is required to create a dependency graph for that main target,
+      which will also include actions to be run. The algorithm for
+      creating the dependency graph is described here.</p>
+<p>The fundamental concept is <span class="emphasis"><em>generator</em></span>. If encapsulates
+      the notion of build tool and is capable to converting a set of
+      input targets into a set of output targets, with some properties.
+      Generator matches a build tool as closely as possible: it works
+      only when the tool can work with requested properties (for
+      example, msvc compiler can't work when requested toolset is gcc),
+      and should produce exactly the same targets as the tool (for
+      example, if Borland's linker produces additional files with debug
+      information, generator should also).</p>
+<p>Given a set of generators, the fundamental operation is to
+      construct a target of a given type, with given properties, from a
+      set of targets. That operation is performed by rule
+      <tt class="literal">generators.construct</tt> and the used algorithm is described
+      below.</p>
+<div class="section" lang="en">
+<div class="titlepage">
+<div><div><h3 class="title">
+<a name="id2540607"></a>Selecting and ranking viable generators</h3></div></div>
+<div></div>
+</div>
+<p>Each generator, in addition to target types that it can
+        produce, have attribute that affects its applicability in
+        particular sitiation. Those attributes are:</p>
+<div class="orderedlist"><ol type="1">
+<li>
+            Required properties, which are properties absolutely
+            necessary for the generator to work. For example, generator
+            encapsulating the gcc compiler would have &lt;toolset&gt;gcc as
+            required property.
+          </li>
+<li>
+            Optional properties, which increase the generators
+            suitability for a particual build.
+          </li>
+</ol></div>
+<p>
+        Generator's required and optional properties may not include
+        either free or incidental properties. (Allowing this would
+        greatly complicate caching targets).
+      </p>
+<p>When trying to construct a target, the first step is to select
+        all possible generators for the requested target type, which
+        required properties are a subset of requested properties.
+        Generators which were already selected up the call stack are
+        excluded. In addition, if any composing generators were selected
+        up the call stack, all other composing generators are ignored
+        (TODO: define composing generators). The found generators
+        are assigned a rank, which is the number of optional properties
+        present in requested properties. Finally, generators with highest
+        rank are selected for futher processing.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div><div><h3 class="title">
+<a name="id2540667"></a>Running generators</h3></div></div>
+<div></div>
+</div>
+<p>When generators are selected, each is run to produce a list of
+        created targets. This list might include targets which are not of
+        requested types, because generators create the same targets as
+        some tool, and tool's behaviour is fixed. (Note: should specify
+        that in some cases we actually want extra targets). If generator
+        fails, it returns an empty list. Generator is free to call
+        'construct' again, to convert sources to the types it can handle.
+        It also can pass modified properties to 'construct'. However, a
+        generator is not allowed to modify any propagated properties,
+        otherwise when actually consuming properties we might discover
+        that the set of propagated properties is different from what was
+        used for building sources.</p>
+<p>For all targets which are not of requested types, we try to
+        convert them to requested type, using a second call to
+        <tt class="literal">construct</tt>. This is done in order to support
+        transformation sequences where single source file expands to
+        several later. See <a href="http://groups.yahoo.com/group/jamboost/message/1667" target="_top">this
+          message</a> for details.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div><div><h3 class="title">
+<a name="id2540706"></a>Selecting dependency graph</h3></div></div>
+<div></div>
+</div>
+<p>
+        After all generators are run,
+        it is necessary to decide which of successfull invocation will be
+        taken as final result. At the moment, this is not done. Instead,
+        it is checked whether all successfull generator invocation
+        returned the same target list. Error is issued otherwise.
+      </p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div><div><h3 class="title">
+<a name="id2540717"></a>Property adjustment</h3></div></div>
+<div></div>
+</div>
+<p>Because target location is determined by the build system, it
+        is sometimes necessary to adjust properties, in order to not
+        break actions. For example, if there's an action which generates
+        a header, say "a_parser.h", and a source file "a.cpp" which
+        includes that file, we must make everything work as if a_parser.h
+        is generated in the same directory where it would be generated
+        without any subvariants.</p>
+<p>Correct property adjustment can be done only after all targets
+        are created, so the approach taken is:</p>
+<div class="orderedlist"><ol type="1">
+<li><p>
+            When dependency graph is constructed, each action can be
+            assigned a rule for property adjustment.
+          </p></li>
+<li><p>
+            When virtual target is actualized, that rule is run and
+            return the final set of properties. At this stage it can use
+            information of all created virtual targets.
+          </p></li>
+</ol></div>
+<p>In case of quoted includes, no adjustment can give 100% correct
+        results. If target dirs are not changed by build system, quoted
+        includes are searched in "." and then in include path, while angle
+        includes are searched only in include path. When target dirs are
+        changed, we'd want to make quoted includes to be search in "." then in
+        additional dirs and then in the include path and make angle includes
+        be searched in include path, probably with additional paths added at
+        some position. Unless, include path already has "." as the first
+        element, this is not possible. So, either generated headers should not
+        be included with quotes, or first element of include path should be
+        ".", which essentially erases the difference between quoted and angle
+        includes. <span class="bold"><b>Note:</b></span> the only way to get
+        "." as include path into compiler command line is via verbatim
+        compiler option. In all other case, Boost.Build will convert "." into
+        directory where it occurs.</p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div><div><h3 class="title">
+<a name="id2540792"></a>Transformations cache</h3></div></div>
+<div></div>
+</div>
+<p>
+        Under certain conditions, an
+        attempt is made to cache results of transformation search. First,
+        the sources are replaced with targets with special name and the
+        found target list is stored. Later, when properties, requested
+        type, and source type are the same, the store target list is
+        retrieved and cloned, with appropriate change in names.
+      </p>
+</div>
+</div>
+<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
+<td align="left"></td>
+<td align="right"><small></small></td>
+</tr></table>
+<hr>
+<div class="spirit-nav">
+<a accesskey="p" href="definitions.html"><img src="../../images/prev.png" alt="Prev"></a><a accesskey="u" href="../reference.html"><img src="../../images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../images/home.png" alt="Home"></a><a accesskey="n" href="../faq.html"><img src="../../images/next.png" alt="Next"></a>
+</div>
+</body>
+</html>

Added: boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/reference/jamfiles.html
===================================================================
--- boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/reference/jamfiles.html	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/reference/jamfiles.html	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,69 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+<title>Writing Jamfiles</title>
+<link rel="stylesheet" href="../../boostbook.css" type="text/css">
+<meta name="generator" content="DocBook XSL Stylesheets V1.61.3">
+<link rel="home" href="../../index.html" title="Part I. Boost.Build v2 User Manual">
+<link rel="up" href="../reference.html" title="Chapter 6. Detailed reference">
+<link rel="previous" href="../reference.html" title="Chapter 6. Detailed reference">
+<link rel="next" href="buildprocess.html" title="Build process">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<table cellpadding="2" width="100%"><td valign="top"><img alt="boost.png (6897 bytes)" width="277" height="86" src="../../../../boost.png"></td></table>
+<hr>
+<div class="spirit-nav">
+<a accesskey="p" href="../reference.html"><img src="../../images/prev.png" alt="Prev"></a><a accesskey="u" href="../reference.html"><img src="../../images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../images/home.png" alt="Home"></a><a accesskey="n" href="buildprocess.html"><img src="../../images/next.png" alt="Next"></a>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div><div><h2 class="title" style="clear: both">
+<a name="bbv2.reference.jamfiles"></a>Writing Jamfiles</h2></div></div>
+<div></div>
+</div>
+<div class="toc"><dl><dt><a href="jamfiles.html#bbv2.reference.headers">Generated headers</a></dt></dl></div>
+<p>This section describes specific information about writing Jamfiles.</p>
+<div class="section" lang="en">
+<div class="titlepage">
+<div><div><h3 class="title">
+<a name="bbv2.reference.headers"></a>Generated headers</h3></div></div>
+<div></div>
+</div>
+<p>Usually, Boost.Build handles implicit dependendies completely
+        automatically. For example, for C++ files, all <tt class="literal">#include</tt>
+        statements are found and handled. The only aspect where user help
+        might be needed is implicit dependency on generated files.</p>
+<p>By default, Boost.Build handles such dependencies within one
+        main target. For example, assume that main target "app" has two
+        sources, "app.cpp" and "parser.y". The latter source is converted
+        into "parser.c" and "parser.h". Then, if "app.cpp" includes
+        "parser.h", Boost.Build will detect this dependency. Moreover,
+        since "parser.h" will be generated into a build directory, the
+        path to that directory will automatically added to include
+        path.</p>
+<p>Making this mechanism work across main target boundaries is
+        possible, but imposes certain overhead. For that reason, if
+        there's implicit dependency on files from other main targets, the
+        <tt class="literal">&lt;implicit-dependency&gt;</tt> [ link ] feature must
+        be used, for example:</p>
+<pre class="programlisting">
+lib parser : parser.y ;
+exe app : app.cpp : &lt;implicit-dependency&gt;parser ;
+</pre>
+<p>
+        The above example tells the build system that when scanning
+        all sources of "app" for implicit-dependencies, it should consider
+        targets from "parser" as potential dependencies.
+      </p>
+</div>
+</div>
+<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
+<td align="left"></td>
+<td align="right"><small></small></td>
+</tr></table>
+<hr>
+<div class="spirit-nav">
+<a accesskey="p" href="../reference.html"><img src="../../images/prev.png" alt="Prev"></a><a accesskey="u" href="../reference.html"><img src="../../images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../images/home.png" alt="Home"></a><a accesskey="n" href="buildprocess.html"><img src="../../images/next.png" alt="Next"></a>
+</div>
+</body>
+</html>

Added: boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/reference.html
===================================================================
--- boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/reference.html	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/reference.html	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,310 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+<title>Chapter 6. Detailed reference</title>
+<link rel="stylesheet" href="../boostbook.css" type="text/css">
+<meta name="generator" content="DocBook XSL Stylesheets V1.61.3">
+<link rel="home" href="../index.html" title="Part I. Boost.Build v2 User Manual">
+<link rel="up" href="../index.html" title="Part I. Boost.Build v2 User Manual">
+<link rel="previous" href="extending/toolset_modules.html" title="Toolset modules">
+<link rel="next" href="reference/jamfiles.html" title="Writing Jamfiles">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<table cellpadding="2" width="100%"><td valign="top"><img alt="boost.png (6897 bytes)" width="277" height="86" src="../../../boost.png"></td></table>
+<hr>
+<div class="spirit-nav">
+<a accesskey="p" href="extending/toolset_modules.html"><img src="../images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../images/home.png" alt="Home"></a><a accesskey="n" href="reference/jamfiles.html"><img src="../images/next.png" alt="Next"></a>
+</div>
+<div class="chapter" lang="en">
+<div class="titlepage">
+<div><div><h2 class="title">
+<a name="bbv2.reference"></a>Chapter 6. Detailed reference</h2></div></div>
+<div></div>
+</div>
+<div class="toc">
+<p><b>Table of Contents</b></p>
+<dl>
+<dt><a href="reference.html#bbv2.reference.general">General information</a></dt>
+<dt><a href="reference/jamfiles.html">Writing Jamfiles</a></dt>
+<dt><a href="reference/buildprocess.html">Build process</a></dt>
+<dt><a href="reference/definitions.html"></a></dt>
+<dt><a href="reference/generators.html">Generators</a></dt>
+</dl>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div><div><h2 class="title" style="clear: both">
+<a name="bbv2.reference.general"></a>General information</h2></div></div>
+<div></div>
+</div>
+<div class="toc"><dl>
+<dt><a href="reference.html#bbv2.reference.init">Initialization</a></dt>
+<dt><a href="reference.html#bbv2.reference.commandline">Command line</a></dt>
+</dl></div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div><div><h3 class="title">
+<a name="bbv2.reference.init"></a>Initialization</h3></div></div>
+<div></div>
+</div>
+<p>bjam's first job upon startup is to load the Jam code which
+        implements the build system. To do this, it searches for a file
+        called "boost-build.jam", first in the invocation directory, then
+        in its parent and so forth up to the filesystem root, and finally
+        in the directories specified by the environment variable
+        BOOST_BUILD_PATH. When found, the file is interpreted, and should
+        specify the build system location by calling the boost-build
+        rule:</p>
+<pre class="programlisting">
+rule boost-build ( location ? )
+</pre>
+<p>
+        If location is a relative path, it is treated as relative to
+        the directory of boost-build.jam. The directory specified by
+        location and directories in BOOST_BUILD_PATH are then searched for
+        a file called bootstrap.jam which is interpreted and is expected to
+        bootstrap the build system. This arrangement allows the build
+        system to work without any command-line or environment variable
+        settings. For example, if the build system files were located in a
+        directory "build-system/" at your project root, you might place a
+        boost-build.jam at the project root containing:
+
+</p>
+<pre class="programlisting">
+boost-build build-system ;
+</pre>
+<p>
+
+        In this case, running bjam anywhere in the project tree will
+        automatically find the build system.</p>
+<p>The default "bootstrap.jam", after loading some standard
+        definitions, loads two files, which can be provided/customised by
+        user: "site-config.jam" and "user-config.jam".</p>
+<p>Locations where those files a search are summarized below:</p>
+<div class="table">
+<a name="bbv2.reference.init.config"></a><p class="title"><b>Table 6.1. Search paths for configuration files</b></p>
+<table class="table" summary="Search paths for configuration files">
+<colgroup>
+<col>
+<col>
+<col>
+</colgroup>
+<thead><tr>
+<th> </th>
+<th>site-config.jam</th>
+<th>user-config.jam</th>
+</tr></thead>
+<tbody>
+<tr>
+<td>Linux</td>
+<td>
+<p>/etc</p>
+<p>$HOME</p>
+<p>$BOOST_BUILD_PATH</p>
+</td>
+<td>
+<p>$HOME</p>
+<p>$BOOST_BUILD_PATH</p>
+</td>
+</tr>
+<tr>
+<td>Windows</td>
+<td>
+<p>$SystemRoot</p>
+<p>$HOME</p>
+<p>$BOOST_BUILD_PATH</p>
+</td>
+<td>
+<p>$HOME</p>
+<p>$BOOST_BUILD_PATH</p>
+</td>
+</tr>
+</tbody>
+</table>
+</div>
+<p>
+        Boost.Build comes with default versions of those files,
+        which can serve as templates for customized versions.
+      </p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div><div><h3 class="title">
+<a name="bbv2.reference.commandline"></a>Command line</h3></div></div>
+<div></div>
+</div>
+<div class="toc"><dl>
+<dt><a href="reference.html#bbv2.reference.init.args">Command line arguments</a></dt>
+<dt><a href="reference.html#bbv2.reference.init.options">Command line options</a></dt>
+</dl></div>
+<p>The command line may contain:</p>
+<div class="itemizedlist"><ul type="disc">
+<li>Jam options,</li>
+<li>Boost.Build <a href="reference.html#bbv2.reference.init.options" title="Command line options">options</a>,</li>
+<li>Command line arguments</li>
+</ul></div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div><div><h4 class="title">
+<a name="bbv2.reference.init.args"></a>Command line arguments</h4></div></div>
+<div></div>
+</div>
+<p>
+          Command line arguments specify targets and build
+          request using the following rules.
+        </p>
+<div class="itemizedlist"><ul type="disc">
+<li>
+              An argument which does not contain slashes or the "="
+              symbol is either a value of an implicit feature, or target to
+              be built. It is taken to be value of a feature if appropriate
+              feature exists. Otherwise, it is considered a <a href="reference/definitions.html#bbv2.reference.ids" title="Target identifiers and references">target id</a>. Special target name "clean"
+              has the same effect as "--clean" option.
+            </li>
+<li>
+<p>
+              An argument with either slashes or the "=" symbol specifies
+              a number of <a href="../">build
+                request</a>
+              elements. In the simplest form, it's just a set of properties,
+              separated by slashes, which become a single build request
+              element, for example:
+
+</p>
+<pre class="programlisting">
+borland/&lt;runtime-link&gt;static
+</pre>
+<p>
+
+              More complex form is used to save typing. For example,
+              instead of
+
+</p>
+<pre class="programlisting">
+borland/runtime-link=static borland/runtime-link=dynamic
+</pre>
+<p>
+
+              one can use
+
+</p>
+<pre class="programlisting">
+borland/runtime-link=static,dynamic
+</pre>
+<p>
+
+              Exactly, the conversion from argument to build request
+              elements is performed by (1) splitting the argument at each slash,
+              (2) converting each split part into a set of properties and (3)
+              taking all possible combination of the property sets. Each split
+              part should have the either the form
+
+</p>
+<pre class="programlisting"><span class="emphasis"><em>feature-name</em></span>=<span class="emphasis"><em>feature-value1</em></span>[","<span class="emphasis"><em>feature-valueN</em></span>]*   
+</pre>
+<p>
+
+              or, in case of implicit feature
+
+</p>
+<pre class="programlisting"><span class="emphasis"><em>feature-value1</em></span>[","<span class="emphasis"><em>feature-valueN</em></span>;]*   
+</pre>
+<p>
+
+              and will be converted into property set
+
+</p>
+<pre class="programlisting">
+&lt;feature-name&gt;feature-value1 .... &lt;feature-name&gt;feature-valueN
+</pre>
+</li>
+</ul></div>
+<p>
+          For example, the command line
+
+</p>
+<pre class="programlisting">
+target1 debug gcc/runtime-link=dynamic,static
+</pre>
+<p>
+
+          would cause target called <tt class="literal">target1</tt> to be rebuilt in
+          debug mode, except that for gcc, both dynamically and statically
+          linked binaries would be created.
+        </p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div><div><h4 class="title">
+<a name="bbv2.reference.init.options"></a>Command line options</h4></div></div>
+<div></div>
+</div>
+<p>All of the Boost.Build options start with the "--" prefix.
+          They are described in the following table.</p>
+<div class="table">
+<a name="id2539335"></a><p class="title"><b>Table 6.2. Command line options</b></p>
+<table class="table" summary="Command line options">
+<colgroup>
+<col>
+<col>
+</colgroup>
+<thead><tr>
+<th>Option</th>
+<th>Description</th>
+</tr></thead>
+<tbody>
+<tr>
+<td><tt class="literal">--version</tt></td>
+<td>Prints information on Boost.Build and Boost.Jam
+                  versions.</td>
+</tr>
+<tr>
+<td>
+<a name="bbv2.reference.init.options.help"></a><tt class="literal">--help</tt>
+</td>
+<td>Access to the online help system. This prints general
+                  information on how to use the help system with additional
+                  --help* options.</td>
+</tr>
+<tr>
+<td><tt class="literal">--clean</tt></td>
+<td>Removes everything instead of building. Unlike
+                  <tt class="literal">clean</tt> target in make, it is possible to clean only
+                  some targets.</td>
+</tr>
+<tr>
+<td><tt class="literal">--debug</tt></td>
+<td>Enables internal checks.</td>
+</tr>
+<tr>
+<td><tt class="literal">--dump-projects</tt></td>
+<td>Cause the project structure to be output.</td>
+</tr>
+<tr>
+<td><tt class="literal">--no-error-backtrace</tt></td>
+<td>Don't print backtrace on errors. Primary useful for
+                  testing.</td>
+</tr>
+<tr>
+<td><tt class="literal">--ignore-config</tt></td>
+<td>Do not load <tt class="literal">site-config.jam</tt> and
+                  <tt class="literal">user-config.jam</tt>
+</td>
+</tr>
+</tbody>
+</table>
+</div>
+</div>
+</div>
+</div>
+</div>
+<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
+<td align="left"></td>
+<td align="right"><small></small></td>
+</tr></table>
+<hr>
+<div class="spirit-nav">
+<a accesskey="p" href="extending/toolset_modules.html"><img src="../images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../images/home.png" alt="Home"></a><a accesskey="n" href="reference/jamfiles.html"><img src="../images/next.png" alt="Next"></a>
+</div>
+</body>
+</html>

Added: boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/tutorial/conditions.html
===================================================================
--- boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/tutorial/conditions.html	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/tutorial/conditions.html	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,80 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+<title>Conditions and alternatives</title>
+<link rel="stylesheet" href="../../boostbook.css" type="text/css">
+<meta name="generator" content="DocBook XSL Stylesheets V1.61.3">
+<style type="text/css">
+body { background-image: url('http://docbook.sourceforge.net/release/images/draft.png');
+       background-repeat: no-repeat;
+       background-position: top left;
+       /* The following properties make the watermark "fixed" on the page. */
+       /* I think that's just a bit too distracting for the reader... */
+       /* background-attachment: fixed; */
+       /* background-position: center center; */
+     }</style>
+<link rel="home" href="../../index.html" title="Part I. Boost.Build v2 User Manual">
+<link rel="up" href="../tutorial.html" title="Chapter 3. Tutorial">
+<link rel="previous" href="linkage.html" title="Static and shared libaries">
+<link rel="next" href="prebuilt.html" title="Prebuilt targets">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<table cellpadding="2" width="100%"><td valign="top"><img alt="boost.png (6897 bytes)" width="277" height="86" src="../../../../boost.png"></td></table>
+<hr>
+<div class="spirit-nav">
+<a accesskey="p" href="linkage.html"><img src="../../images/prev.png" alt="Prev"></a><a accesskey="u" href="../tutorial.html"><img src="../../images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../images/home.png" alt="Home"></a><a accesskey="n" href="prebuilt.html"><img src="../../images/next.png" alt="Next"></a>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div><div><h2 class="title" style="clear: both">
+<a name="bbv2.tutorial.conditions"></a>Conditions and alternatives</h2></div></div>
+<div></div>
+</div>
+<p>As we've just figured out, properties can significally affect the
+      way targets are built. The processing of the &lt;link&gt; feature is
+      built in the build system, and is quite complex. But there is a couple
+      of mechanisms which allow ordinary users to do different things 
+      depending on properties.
+    </p>
+<p>The first mechanism is called <i class="firstterm">conditinal
+        requirement</i>. For example, you might want to set specific
+      defines when the library is build as shared, or you have your own define
+      to be used in release mode. Here's a piece of Jamfile.
+</p>
+<pre class="programlisting">
+lib network : network.cpp 
+    : &lt;link&gt;shared:&lt;define&gt;NEWORK_LIB_SHARED 
+      &lt;variant&gt;release:&lt;define&gt;EXTRA_FAST
+    ;
+</pre>
+<p>
+      This will have exactly the effect we wanted: whenever &lt;link&gt;shared
+      is in properties, &lt;define&gt;NEWORK_LIB_SHARED will be in properties
+      as well.
+    </p>
+<p>
+      Sometimes different variant of a target are so different, that
+      describing them using conditional requirements would be hard. Imagine
+      that a library has different sources on two supported toolsets, and
+      dummy implementation for all the other toolset. We can express this
+      situation using <i class="firstterm">target alternatives</i>:
+</p>
+<pre class="programlisting">
+lib demangler : dummy_demangler.cpp ;
+lib demangler : demangler_gcc.cpp : &lt;toolset&gt;gcc ;
+lib demangler : demangler_msvc.cpp : &lt;toolset&gt;msvc ;
+</pre>
+<p>
+      The proper alternative will be automatically selected. 
+    </p>
+</div>
+<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
+<td align="left"></td>
+<td align="right"><small></small></td>
+</tr></table>
+<hr>
+<div class="spirit-nav">
+<a accesskey="p" href="linkage.html"><img src="../../images/prev.png" alt="Prev"></a><a accesskey="u" href="../tutorial.html"><img src="../../images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../images/home.png" alt="Home"></a><a accesskey="n" href="prebuilt.html"><img src="../../images/next.png" alt="Next"></a>
+</div>
+</body>
+</html>

Added: boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/tutorial/depends.html
===================================================================
--- boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/tutorial/depends.html	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/tutorial/depends.html	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,77 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+<title>Library dependencies</title>
+<link rel="stylesheet" href="../../boostbook.css" type="text/css">
+<meta name="generator" content="DocBook XSL Stylesheets V1.61.3">
+<style type="text/css">
+body { background-image: url('http://docbook.sourceforge.net/release/images/draft.png');
+       background-repeat: no-repeat;
+       background-position: top left;
+       /* The following properties make the watermark "fixed" on the page. */
+       /* I think that's just a bit too distracting for the reader... */
+       /* background-attachment: fixed; */
+       /* background-position: center center; */
+     }</style>
+<link rel="home" href="../../index.html" title="Part I. Boost.Build v2 User Manual">
+<link rel="up" href="../tutorial.html" title="Chapter 3. Tutorial">
+<link rel="previous" href="libs.html" title="Libraries and Dependent Targets">
+<link rel="next" href="linkage.html" title="Static and shared libaries">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<table cellpadding="2" width="100%"><td valign="top"><img alt="boost.png (6897 bytes)" width="277" height="86" src="../../../../boost.png"></td></table>
+<hr>
+<div class="spirit-nav">
+<a accesskey="p" href="libs.html"><img src="../../images/prev.png" alt="Prev"></a><a accesskey="u" href="../tutorial.html"><img src="../../images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../images/home.png" alt="Home"></a><a accesskey="n" href="linkage.html"><img src="../../images/next.png" alt="Next"></a>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div><div><h2 class="title" style="clear: both">
+<a name="bbv2.tutorial.depends"></a>Library dependencies</h2></div></div>
+<div></div>
+</div>
+<p>The previous example was simple. Often, there are long chains
+      of dependencies between libraries. The main application is a thin
+      wrapper on top of library with core logic, which uses library of
+      utility functions, which uses boost filesystem library.
+      Expressing these dependencies is straightforward:</p>
+<pre class="programlisting">
+lib utils : utils.cpp /boost/filesystem//fs ;   
+lib core : core.cpp utils ;
+exe app : app.cpp core ;
+</pre>
+<p>So, what's the reason to even mention this case? First,
+      because it's a bit more complex that it seems. When using shared
+      linking, libraries are build just as written, and everything will
+      work. However, what happens with static linking? It's not
+      possible to include another library in static library.
+      Boost.Build solves this problem by returning back library targets
+      which appear as sources for static libraries. In this case, if
+      everything is built statically, the "app" target will link not
+      only "core" library, but also "utils" and
+      "/boost/filesystem//fs".</p>
+<p>So, the net result is that the above code will work for both
+      static linking and for shared linking.</p>
+<p>Sometimes, you want all applications in some project to link
+      to a certain library. Putting the library in sources of all
+      targets is possible, but verbose. You can do better by using the
+      &lt;source&gt; property. For example, if "/boost/filesystem//fs"
+      should be linked to all applications in your project, you can add
+      &lt;source&gt;/boost/filesystem//fs to requirements of the
+      project, like this:</p>
+<pre class="programlisting">
+project 
+   : requirements &lt;source&gt;/boost/filesystem//fs
+   ;   
+</pre>
+</div>
+<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
+<td align="left"></td>
+<td align="right"><small></small></td>
+</tr></table>
+<hr>
+<div class="spirit-nav">
+<a accesskey="p" href="libs.html"><img src="../../images/prev.png" alt="Prev"></a><a accesskey="u" href="../tutorial.html"><img src="../../images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../images/home.png" alt="Home"></a><a accesskey="n" href="linkage.html"><img src="../../images/next.png" alt="Next"></a>
+</div>
+</body>
+</html>

Added: boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/tutorial/hierarchy.html
===================================================================
--- boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/tutorial/hierarchy.html	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/tutorial/hierarchy.html	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,124 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+<title>Project Hierarchies</title>
+<link rel="stylesheet" href="../../boostbook.css" type="text/css">
+<meta name="generator" content="DocBook XSL Stylesheets V1.61.3">
+<style type="text/css">
+body { background-image: url('http://docbook.sourceforge.net/release/images/draft.png');
+       background-repeat: no-repeat;
+       background-position: top left;
+       /* The following properties make the watermark "fixed" on the page. */
+       /* I think that's just a bit too distracting for the reader... */
+       /* background-attachment: fixed; */
+       /* background-position: center center; */
+     }</style>
+<link rel="home" href="../../index.html" title="Part I. Boost.Build v2 User Manual">
+<link rel="up" href="../tutorial.html" title="Chapter 3. Tutorial">
+<link rel="previous" href="properties.html" title="Properties">
+<link rel="next" href="libs.html" title="Libraries and Dependent Targets">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<table cellpadding="2" width="100%"><td valign="top"><img alt="boost.png (6897 bytes)" width="277" height="86" src="../../../../boost.png"></td></table>
+<hr>
+<div class="spirit-nav">
+<a accesskey="p" href="properties.html"><img src="../../images/prev.png" alt="Prev"></a><a accesskey="u" href="../tutorial.html"><img src="../../images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../images/home.png" alt="Home"></a><a accesskey="n" href="libs.html"><img src="../../images/next.png" alt="Next"></a>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div><div><h2 class="title" style="clear: both">
+<a name="bbv2.tutorial.hierarchy"></a>Project Hierarchies</h2></div></div>
+<div></div>
+</div>
+<p>So far we've only considered examples with one project
+      (i.e. with one <tt class="filename">Jamfile</tt>). A typical large
+      software project would be composed of sub-projects organized
+      into a tree. The top of the tree is called the
+      <i class="firstterm">project root</i>.  Besides a
+      <tt class="filename">Jamfile</tt>, the project root directory
+      contains a file called <tt class="filename">project-root.jam</tt>. Every other
+      <tt class="filename">Jamfile</tt> in the project has a single parent
+      project, rooted in the nearest parent directory containing a
+      <tt class="filename">Jamfile</tt>. For example, in the following
+      directory layout:
+
+</p>
+<pre class="screen">
+top/ 
+  |
+  +-- Jamfile
+  +-- project-root.jam
+  |
+  +-- src/
+  |    |
+  |    +-- Jamfile
+  |    `-- app.cpp
+  | 
+  `-- util/
+       |
+       +-- foo/
+       .    |
+       .    +-- Jamfile
+       .    `-- bar.cpp
+</pre>
+<p>
+
+      the project root is <tt class="filename">top/</tt>.  Because there is
+      no <tt class="filename">Jamfile</tt> in
+      <tt class="filename">top/util/</tt>, the projects in
+      <tt class="filename">top/src/</tt> and
+      <tt class="filename">top/util/foo/</tt> are immediate children of the
+      root project.
+    </p>
+<p>
+      Projects inherit all attributes (such as requirements)
+      from their parents.  Inherited requirements are combined with
+      any requirements specified by the sub-project.  
+      For example, if <tt class="filename">top/Jamfile</tt> has
+
+</p>
+<pre class="programlisting">
+&lt;include&gt;/home/ghost/local
+</pre>
+<p>
+
+      in its requirements, then all of its sub-projects will have it
+      in their requirements, too.  Of course, any project can add
+      additional includes. <sup>[<a name="id2534693" href="#ftn.id2534693">2</a>]</sup> More details can be found in the section
+      on <a href="../advanced/jamfiles.html#bbv2.advanced.projects" title="Projects">projects</a>.
+    </p>
+<p>
+      Invoking <b class="command">bjam</b> without explicitly specifying
+      any targets on the command-line builds the project rooted in the
+      current directory.  Building a project does not automatically
+      cause its sub-projects to be built unless the parent project's
+      <tt class="filename">Jamfile</tt> explicitly requests it. In our
+      example, <tt class="filename">top/Jamfile</tt> might contain:
+
+</p>
+<pre class="programlisting">
+build-project src ;
+</pre>
+<p>
+
+      which would cause the project in <tt class="filename">top/src/</tt>
+      to be built whenever the project in <tt class="filename">top/</tt> is
+      built. However, targets in <tt class="filename">top/util/foo/</tt>
+      will be built only if they are needed by targets in
+      <tt class="filename">top/</tt> or <tt class="filename">top/src/</tt>.
+    </p>
+<div class="footnotes">
+<br><hr width="100" align="left">
+<div class="footnote"><a href="../reference/definitions.html#bbv2.reference.features.attributes" title="Feature Attributes"><sup>[<a name="ftn.id2534693" href="#id2534693">2</a>] </sup>the section called &#8220;Feature Attributes&#8221;</a></div>
+</div>
+</div>
+<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
+<td align="left"></td>
+<td align="right"><small></small></td>
+</tr></table>
+<hr>
+<div class="spirit-nav">
+<a accesskey="p" href="properties.html"><img src="../../images/prev.png" alt="Prev"></a><a accesskey="u" href="../tutorial.html"><img src="../../images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../images/home.png" alt="Home"></a><a accesskey="n" href="libs.html"><img src="../../images/next.png" alt="Next"></a>
+</div>
+</body>
+</html>

Added: boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/tutorial/libs.html
===================================================================
--- boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/tutorial/libs.html	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/tutorial/libs.html	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,157 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+<title>Libraries and Dependent Targets</title>
+<link rel="stylesheet" href="../../boostbook.css" type="text/css">
+<meta name="generator" content="DocBook XSL Stylesheets V1.61.3">
+<style type="text/css">
+body { background-image: url('http://docbook.sourceforge.net/release/images/draft.png');
+       background-repeat: no-repeat;
+       background-position: top left;
+       /* The following properties make the watermark "fixed" on the page. */
+       /* I think that's just a bit too distracting for the reader... */
+       /* background-attachment: fixed; */
+       /* background-position: center center; */
+     }</style>
+<link rel="home" href="../../index.html" title="Part I. Boost.Build v2 User Manual">
+<link rel="up" href="../tutorial.html" title="Chapter 3. Tutorial">
+<link rel="previous" href="hierarchy.html" title="Project Hierarchies">
+<link rel="next" href="depends.html" title="Library dependencies">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<table cellpadding="2" width="100%"><td valign="top"><img alt="boost.png (6897 bytes)" width="277" height="86" src="../../../../boost.png"></td></table>
+<hr>
+<div class="spirit-nav">
+<a accesskey="p" href="hierarchy.html"><img src="../../images/prev.png" alt="Prev"></a><a accesskey="u" href="../tutorial.html"><img src="../../images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../images/home.png" alt="Home"></a><a accesskey="n" href="depends.html"><img src="../../images/next.png" alt="Next"></a>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div><div><h2 class="title" style="clear: both">
+<a name="bbv2.tutorial.libs"></a>Libraries and Dependent Targets</h2></div></div>
+<div></div>
+</div>
+<i><span class="comment">TODO: need to make this
+      section consistent with "examples-v2/libraries".</span></i><p>
+      Targets that are "needed" by other targets are called
+      <i class="firstterm">dependencies</i> of those other targets.  The
+      targets that need the other targets are called
+      <i class="firstterm">dependent</i> targets.
+    </p>
+<p>To get a feeling of target dependencies, let's continue the
+      above example and see how <tt class="filename">src/Jamfile</tt> can
+      use libraries from <tt class="filename">util/foo</tt>.  Assume
+      util/foo/Jamfile contains:
+
+</p>
+<pre class="programlisting">
+lib bar : bar.cpp ;
+</pre>
+<p>
+
+      Then, to use this library in <tt class="filename">src/Jamfile</tt>, we can write:
+
+</p>
+<pre class="programlisting">
+exe app : app.cpp ../util/foo//bar ;
+</pre>
+<p>
+
+      While <tt class="computeroutput">app.cpp</tt> refers to a regular source file,
+      <tt class="computeroutput">../util/foo//bar</tt> is a reference to another target:
+      a library "bar" declared in the <tt class="filename">Jamfile</tt> at
+      <tt class="filename">../util/foo</tt>.  When linking the
+      <b class="command">app</b> executable, the appropriate version of
+      <tt class="computeroutput">bar</tt> will be built and linked in. What do we mean by
+      "appropriate"? For example, suppose we build "app" with:
+
+</p>
+<pre class="screen">
+bjam app optimization=full cxxflags=-w-8080
+</pre>
+<p>
+
+      Which properties must be used to build <tt class="computeroutput">foo</tt>? The
+      answer is that some properties are
+      <i class="firstterm">propagated</i> &#8212; Boost.Build attempts to
+      use dependencies with the same value of propagated features. The
+      &lt;optimization&gt; feature is propagated, so both "app" and
+      "foo" will be compiled with full optimization. But
+      &lt;cxxflags&gt; feature is not propagated: its value will be
+      added as-is to compiler flags for "a.cpp", but won't affect
+      "foo". There is still a couple of problems. First, the library
+      probably has some headers which must be used when compiling
+      "app.cpp". We could use requirements on "app" to add those
+      includes, but then this work will be repeated for all programs
+      which use "foo". A better solution is to modify
+      util/foo/Jamfilie in this way:
+
+</p>
+<pre class="programlisting">
+project 
+    : usage-requirements &lt;include&gt;.
+    ;
+
+lib foo : foo.cpp ;
+</pre>
+<p>
+
+      Usage requirements are requirements which are applied to
+      dependents. In this case, &lt;include&gt; will be applied to all
+      targets which use "foo" &#8212; i.e. targets which have "foo"
+      either in sources or in dependency properties. You'd need to
+      specify usage requirements only once, and programs which use "foo"
+      don't have to care about include paths any longer. Or course, the
+      path will be interpreted relatively to "util/foo" and will be
+      adjusted according to the <b class="command">bjam</b>s invocation
+      directory. For
+      example, if building from project root, the final compiler's
+      command line will contain <tt class="option">-Ilib/foo</tt>.
+    </p>
+<p>The second problem is that we hardcode the path to library's
+      Jamfile. Imagine it's hardcoded in 20 different places and we
+      change the directory layout. The solution is to use project ids
+      &#8212; symbolic names, not tied to directory layout. First, we
+      assign a project id to Jamfile in util/foo:</p>
+<pre class="programlisting">
+project foo
+    : usage-requirements &lt;include&gt;.
+    ;
+</pre>
+<p>
+      Second, we use the project id to refer to the library in
+      src/Jamfile:
+
+</p>
+<pre class="programlisting">
+exe app : app.cpp /foo//bar ;
+</pre>
+<p>
+
+      The "/foo//bar" syntax is used to refer to target "foo" in
+      project with global id "/foo" (the slash is used to specify global
+      id). This way, users of "foo" do not depend on its location, only
+      on id, which is supposedly stable. The only thing left, it to make
+      sure that src/Jamfile knows the project id that it uses. We add to
+      top/Jamfile the following line:
+
+</p>
+<pre class="programlisting">
+use-project /foo : util/foo ;
+</pre>
+<p>
+
+      Now, all projects can refer to "foo" using the symbolic
+      name. If the library is moved somewhere, only a single line in the
+      top-level Jamfile should be changed.
+    </p>
+</div>
+<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
+<td align="left"></td>
+<td align="right"><small></small></td>
+</tr></table>
+<hr>
+<div class="spirit-nav">
+<a accesskey="p" href="hierarchy.html"><img src="../../images/prev.png" alt="Prev"></a><a accesskey="u" href="../tutorial.html"><img src="../../images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../images/home.png" alt="Home"></a><a accesskey="n" href="depends.html"><img src="../../images/next.png" alt="Next"></a>
+</div>
+</body>
+</html>

Added: boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/tutorial/linkage.html
===================================================================
--- boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/tutorial/linkage.html	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/tutorial/linkage.html	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,134 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+<title>Static and shared libaries</title>
+<link rel="stylesheet" href="../../boostbook.css" type="text/css">
+<meta name="generator" content="DocBook XSL Stylesheets V1.61.3">
+<style type="text/css">
+body { background-image: url('http://docbook.sourceforge.net/release/images/draft.png');
+       background-repeat: no-repeat;
+       background-position: top left;
+       /* The following properties make the watermark "fixed" on the page. */
+       /* I think that's just a bit too distracting for the reader... */
+       /* background-attachment: fixed; */
+       /* background-position: center center; */
+     }</style>
+<link rel="home" href="../../index.html" title="Part I. Boost.Build v2 User Manual">
+<link rel="up" href="../tutorial.html" title="Chapter 3. Tutorial">
+<link rel="previous" href="depends.html" title="Library dependencies">
+<link rel="next" href="conditions.html" title="Conditions and alternatives">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<table cellpadding="2" width="100%"><td valign="top"><img alt="boost.png (6897 bytes)" width="277" height="86" src="../../../../boost.png"></td></table>
+<hr>
+<div class="spirit-nav">
+<a accesskey="p" href="depends.html"><img src="../../images/prev.png" alt="Prev"></a><a accesskey="u" href="../tutorial.html"><img src="../../images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../images/home.png" alt="Home"></a><a accesskey="n" href="conditions.html"><img src="../../images/next.png" alt="Next"></a>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div><div><h2 class="title" style="clear: both">
+<a name="bbv2.tutorial.linkage"></a>Static and shared libaries</h2></div></div>
+<div></div>
+</div>
+<p>While the
+      previous section explained how to create and use libraries, it
+      omitted one important detail. Libraries can be either
+      <span class="emphasis"><em>static</em></span>, which means they are included in executable
+      files which use them, or <span class="emphasis"><em>shared</em></span> (a.k.a.
+      <span class="emphasis"><em>dynamic</em></span>), which are only referred to from executables,
+      and must be available at run time. Boost.Build can work with both
+      types. By default, all libraries are shared. This is much more
+      efficient in build time and space. But the need to install all
+      libraries to some location is not always convenient, especially
+      for debug builds. Also, if the installed shared library changes,
+      all application which use it might start to behave differently.
+    </p>
+<p>Static libraries do not suffer from these problems, but
+      considerably increase the size of application. Before describing
+      static libraries, it's reasonable to give another, quite simple
+      approach. If your project is built with
+      &lt;hardcode-dll-paths&gt;true property, then the application
+      will include the full paths for all shared libraries, eliminating
+      the above problems. Unfortunately, you no longer can move shared
+      library to a different location, which makes this option suitable
+      only for debug builds. Further, only gcc compiler supports this
+      option.</p>
+<p>Building a library statically is easy. You'd need to change
+      the value of &lt;link&gt; feature from it's deafault value
+      <tt class="literal">shared</tt>, to <tt class="literal">static</tt>. So, to build everything as
+      static libraries, you'd say</p>
+<pre class="screen">
+bjam link=static
+</pre>
+<p>
+      on the command line. The linking mode can be fine-tuned on
+      per-target basis.
+
+      </p>
+<div class="orderedlist"><ol type="1">
+<li>
+<p>
+            Suppose your library can be only build statically. This is
+            easily achieved using requirements:
+
+</p>
+<pre class="programlisting">
+lib l : l.cpp : &lt;link&gt;static ;
+</pre>
+</li>
+<li>
+<p>
+            What if library can be both static and shared, but when
+            using it in specific executable, you want it static?
+            <a href="../../">Target
+              references</a> are here to help:
+
+</p>
+<pre class="programlisting">
+exe important : main.cpp helpers/&lt;link&gt;static ;
+</pre>
+</li>
+<li>
+<p>
+            What if the library is defined in some other project, which
+            you cannot change. But still, you want static linking to that
+            library in all cases. You can use target references everywhere:
+
+</p>
+<pre class="programlisting">
+exe e1 : e1.cpp /other_project//bar/&lt;link&gt;static ;
+exe e10 : e10.cpp /other_project//bar/&lt;link&gt;static ;
+</pre>
+<p>
+
+            but that's far from being convenient. Another way is to
+            introduce a level of indirection: create a local target, which will
+            refer to static version of <tt class="filename">foo</tt>. Here's the
+            solution:
+
+</p>
+<pre class="programlisting">
+alias foo : /other_project//bar/&lt;link&gt;static ;
+exe e1 : e1.cpp foo ;
+exe e10 : e10.cpp foo ;
+</pre>
+<p>
+
+            Note that the <a href="../advanced/builtins/targets.html#bbv2.builtins.alias" title="Alias">alias</a> 
+            rule is specifically used for rename a reference to a target and possibly
+            change the properties.
+
+          </p>
+</li>
+</ol></div>
+</div>
+<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
+<td align="left"></td>
+<td align="right"><small></small></td>
+</tr></table>
+<hr>
+<div class="spirit-nav">
+<a accesskey="p" href="depends.html"><img src="../../images/prev.png" alt="Prev"></a><a accesskey="u" href="../tutorial.html"><img src="../../images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../images/home.png" alt="Home"></a><a accesskey="n" href="conditions.html"><img src="../../images/next.png" alt="Next"></a>
+</div>
+</body>
+</html>

Added: boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/tutorial/prebuilt.html
===================================================================
--- boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/tutorial/prebuilt.html	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/tutorial/prebuilt.html	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,114 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+<title>Prebuilt targets</title>
+<link rel="stylesheet" href="../../boostbook.css" type="text/css">
+<meta name="generator" content="DocBook XSL Stylesheets V1.61.3">
+<style type="text/css">
+body { background-image: url('http://docbook.sourceforge.net/release/images/draft.png');
+       background-repeat: no-repeat;
+       background-position: top left;
+       /* The following properties make the watermark "fixed" on the page. */
+       /* I think that's just a bit too distracting for the reader... */
+       /* background-attachment: fixed; */
+       /* background-position: center center; */
+     }</style>
+<link rel="home" href="../../index.html" title="Part I. Boost.Build v2 User Manual">
+<link rel="up" href="../tutorial.html" title="Chapter 3. Tutorial">
+<link rel="previous" href="conditions.html" title="Conditions and alternatives">
+<link rel="next" href="../advanced.html" title="Chapter 4. User documentation">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<table cellpadding="2" width="100%"><td valign="top"><img alt="boost.png (6897 bytes)" width="277" height="86" src="../../../../boost.png"></td></table>
+<hr>
+<div class="spirit-nav">
+<a accesskey="p" href="conditions.html"><img src="../../images/prev.png" alt="Prev"></a><a accesskey="u" href="../tutorial.html"><img src="../../images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../images/home.png" alt="Home"></a><a accesskey="n" href="../advanced.html"><img src="../../images/next.png" alt="Next"></a>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div><div><h2 class="title" style="clear: both">
+<a name="bbv2.tutorial.prebuilt"></a>Prebuilt targets</h2></div></div>
+<div></div>
+</div>
+<p>
+      We've just learned how to use libraries which are created by
+      Boost.Build. But some libraries are not. At the same time, those
+      libraries can have different versions (release and debug, for
+      example), that we
+      should select depending on build properties. Prebuilt targets
+      provide a mechanism for that. Jamfile in util/lib2 can contain:
+
+</p>
+<pre class="programlisting">
+lib lib2
+    : 
+    : &lt;file&gt;lib2_release.a &lt;variant&gt;release
+    ;
+
+lib lib2
+    : 
+    : &lt;file&gt;lib2_debug.a &lt;variant&gt;debug
+    ;
+</pre>
+<p>
+
+      This defines two alternatives for target "lib2", and for each
+      one names a prebuilt file. Naturally, there are no sources.
+      Instead, the &lt;file&gt; feature is used to specify the file name.
+      Which alternative is selected depends on properties of dependents.
+      If "app" binary should use "lib2", we can write:
+
+</p>
+<pre class="programlisting">
+exe app : app.cpp ../util/lib2//lib2 ;
+</pre>
+<p>
+
+      If we build release version of "app", then it will be linked
+      with "lib2_release.a", and debug version will use "lib2_debug.a".
+      Another important kind of prebuilt targets are system libraries
+      &#8212; more specifically, libraries which are automatically found
+      by the compiler. E.g. gcc uses "-l" switch for that. Such libraries
+      should be declared almost like regular ones:
+
+</p>
+<pre class="programlisting">
+lib zlib : : &lt;name&gt;z ;
+</pre>
+<p>
+
+      We again don't specify any sources, but give a name which
+      should be passed to the compiler. In this example, and for gcc
+      compiler, the "-lz" option will be added. Paths where library
+      should be searched can also be specified:
+
+</p>
+<pre class="programlisting">
+lib zlib : : &lt;name&gt;z &lt;search&gt;/opt/lib ;
+</pre>
+<p>
+
+      And, of course, two variants can be used:
+
+</p>
+<pre class="programlisting">
+lib zlib : : &lt;name&gt;z &lt;variant&gt;release ;
+lib zlib : : &lt;name&gt;z_d &lt;variant&gt;debug ;
+</pre>
+<p>
+
+      Of course, you'll probably never in your life need debug
+      version of zlib, but for other libraries this is quite reasonable.
+    </p>
+<p>More advanced use of prebuilt target is described in <a href="doc/recipes.html#site_config_targets" target="_top">recipes</a>.</p>
+</div>
+<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
+<td align="left"></td>
+<td align="right"><small></small></td>
+</tr></table>
+<hr>
+<div class="spirit-nav">
+<a accesskey="p" href="conditions.html"><img src="../../images/prev.png" alt="Prev"></a><a accesskey="u" href="../tutorial.html"><img src="../../images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../images/home.png" alt="Home"></a><a accesskey="n" href="../advanced.html"><img src="../../images/next.png" alt="Next"></a>
+</div>
+</body>
+</html>

Added: boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/tutorial/properties.html
===================================================================
--- boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/tutorial/properties.html	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/tutorial/properties.html	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,167 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+<title>Properties</title>
+<link rel="stylesheet" href="../../boostbook.css" type="text/css">
+<meta name="generator" content="DocBook XSL Stylesheets V1.61.3">
+<style type="text/css">
+body { background-image: url('http://docbook.sourceforge.net/release/images/draft.png');
+       background-repeat: no-repeat;
+       background-position: top left;
+       /* The following properties make the watermark "fixed" on the page. */
+       /* I think that's just a bit too distracting for the reader... */
+       /* background-attachment: fixed; */
+       /* background-position: center center; */
+     }</style>
+<link rel="home" href="../../index.html" title="Part I. Boost.Build v2 User Manual">
+<link rel="up" href="../tutorial.html" title="Chapter 3. Tutorial">
+<link rel="previous" href="../tutorial.html" title="Chapter 3. Tutorial">
+<link rel="next" href="hierarchy.html" title="Project Hierarchies">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<table cellpadding="2" width="100%"><td valign="top"><img alt="boost.png (6897 bytes)" width="277" height="86" src="../../../../boost.png"></td></table>
+<hr>
+<div class="spirit-nav">
+<a accesskey="p" href="../tutorial.html"><img src="../../images/prev.png" alt="Prev"></a><a accesskey="u" href="../tutorial.html"><img src="../../images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../images/home.png" alt="Home"></a><a accesskey="n" href="hierarchy.html"><img src="../../images/next.png" alt="Next"></a>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div><div><h2 class="title" style="clear: both">
+<a name="bbv2.tutorial.properties"></a>Properties</h2></div></div>
+<div></div>
+</div>
+<div class="toc"><dl>
+<dt><a href="properties.html#bbv2.tutorial.properties.requirements">Build Requests and Target Requirements</a></dt>
+<dt><a href="properties.html#bbv2.tutorial.properties.project_attributes">Project Attributes</a></dt>
+</dl></div>
+<p>
+      To portably represent aspects of target configuration such as
+      debug and release variants, or single- and multi-threaded
+      builds, Boost.Build uses <i class="firstterm">features</i> with
+      associated <i class="firstterm">values</i>.  For
+      example, the "debug-symbols" feature can have a value of "on" or
+      "off".  A <i class="firstterm">property</i> is just a (feature,
+      value) pair.  When a user initiates a build, Boost.Build
+      automatically translates the requested properties into appropriate
+      command-line flags for invoking toolset components like compilers
+      and linkers.</p>
+<p>There are many built-in features that can be combined to
+      produce arbitrary build configurations.  The following command
+      builds the project's "release" variant with inlining
+      disabled and debug symbols enabled:
+
+</p>
+<pre class="screen">
+bjam release inlining=off debug-symbols=on
+</pre>
+<p>Properties on the command-line are specified with the syntax:
+
+</p>
+<pre class="screen"><i class="replaceable"><tt>feature-name</tt></i>=<i class="replaceable"><tt>feature-value</tt></i></pre>
+<p>The "release" and "debug" that we've seen
+      in <b class="command">bjam</b> invocations are just a shorthand way to
+      specify values of the "variant" feature.  For example, the command
+      above could also have been written this way:
+
+      </p>
+<pre class="screen">
+bjam variant=release inlining=off debug-symbols=on
+      </pre>
+<p>  "variant" is so commonly-used that it has been given
+      special status as an <i class="firstterm">implicit</i> feature
+      &#8212; Boost.Build will deduce the its identity just from the name
+      of one of its values.  
+    </p>
+<p>
+      A complete description of features can be found
+      <a href="../reference/definitions.html#bbv2.reference.features" title="Features and properties">here</a>. 
+    </p>
+<div class="section" lang="en">
+<div class="titlepage">
+<div><div><h3 class="title">
+<a name="bbv2.tutorial.properties.requirements"></a>Build Requests and Target Requirements</h3></div></div>
+<div></div>
+</div>
+<p>      
+        The set of properties specified in the command line constitute a
+        <i class="firstterm">build request</i> &#8212; a description of
+        the desired properties for building the requested targets (or,
+        if no targets were explicitly requested, the project in the
+        current directory).  The <span class="emphasis"><em>actual</em></span> properties
+        used for building targets is typically a combination of the
+        build request and properties derived from the
+        project's <tt class="filename">Jamfile</tt>s.  For example, the
+        locations of <tt class="computeroutput">#include</tt>d header files are normally
+        not specified on the command-line, but described
+        in <tt class="filename">Jamfile</tt>s as <i class="firstterm">target
+          requirements</i> and automatically combined with the
+        build request for those targets.  Multithread-enabled
+        compilation is another example of a typical target requirement.
+        The <tt class="filename">Jamfile</tt> fragment below illustrates how
+        these requirements might be specified.
+      </p>
+<pre class="programlisting">
+exe hello 
+    : hello.cpp
+    : &lt;include&gt;/home/ghost/Work/boost &lt;threading&gt;multi
+    ;
+</pre>
+<p> 
+        When <tt class="filename">hello</tt> is built, the two
+        requirements specified above will normally always be present.
+        If the build request given on the <b class="command">bjam</b>
+        command-line explictly contradicts a target's requirements,
+        the command-line usually overrides (or, in the case of
+        "free" feautures like <tt class="computeroutput">&lt;include&gt;</tt><sup>[<a name="id2473668" href="#ftn.id2473668">1</a>]</sup>,
+        augments) the target requirements.  However, when a
+        contradiction of a target's requrements involves certain
+        <i class="firstterm">link-incompatible</i> features, the target
+        will be skipped.  See ??? for more information.
+      </p>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div><div><h3 class="title">
+<a name="bbv2.tutorial.properties.project_attributes"></a>Project Attributes</h3></div></div>
+<div></div>
+</div>
+<p>
+        If we want the same requirements for our other
+        target, <tt class="filename">hello2</tt>, we could simply duplicate
+        them.  However, as projects grow, that approach leads to a great
+        deal of repeated boilerplate in Jamfiles.
+        
+        Fortunately, there's a better way. Each project (i.e. each
+        <tt class="filename">Jamfile</tt>), can specify a set of <i class="firstterm">attributes</i>,
+        including requirements:
+
+</p>
+<pre class="programlisting">
+project 
+    : requirements &lt;include&gt;/home/ghost/Work/boost &lt;threading&gt;multi 
+    ;
+
+exe hello : hello.cpp ;
+exe hello2 : hello.cpp ;
+</pre>
+<p>
+
+        The effect would be as if we specified the same requirement for
+        both <b class="command">hello</b> and <b class="command">hello2</b>.
+      </p>
+</div>
+<div class="footnotes">
+<br><hr width="100" align="left">
+<div class="footnote"><a href="../reference/definitions.html#bbv2.reference.features.attributes" title="Feature Attributes"><sup>[<a name="ftn.id2473668" href="#id2473668">1</a>] </sup>the section called &#8220;Feature Attributes&#8221;</a></div>
+</div>
+</div>
+<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
+<td align="left"></td>
+<td align="right"><small></small></td>
+</tr></table>
+<hr>
+<div class="spirit-nav">
+<a accesskey="p" href="../tutorial.html"><img src="../../images/prev.png" alt="Prev"></a><a accesskey="u" href="../tutorial.html"><img src="../../images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../images/home.png" alt="Home"></a><a accesskey="n" href="hierarchy.html"><img src="../../images/next.png" alt="Next"></a>
+</div>
+</body>
+</html>

Added: boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/tutorial.html
===================================================================
--- boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/tutorial.html	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/doc/html/bbv2/tutorial.html	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,130 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+<title>Chapter 3. Tutorial</title>
+<link rel="stylesheet" href="../boostbook.css" type="text/css">
+<meta name="generator" content="DocBook XSL Stylesheets V1.61.3">
+<style type="text/css">
+body { background-image: url('http://docbook.sourceforge.net/release/images/draft.png');
+       background-repeat: no-repeat;
+       background-position: top left;
+       /* The following properties make the watermark "fixed" on the page. */
+       /* I think that's just a bit too distracting for the reader... */
+       /* background-attachment: fixed; */
+       /* background-position: center center; */
+     }</style>
+<link rel="home" href="../index.html" title="Part I. Boost.Build v2 User Manual">
+<link rel="up" href="../index.html" title="Part I. Boost.Build v2 User Manual">
+<link rel="previous" href="installation.html" title="Chapter 2. Installation">
+<link rel="next" href="tutorial/properties.html" title="Properties">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<table cellpadding="2" width="100%"><td valign="top"><img alt="boost.png (6897 bytes)" width="277" height="86" src="../../../boost.png"></td></table>
+<hr>
+<div class="spirit-nav">
+<a accesskey="p" href="installation.html"><img src="../images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../images/home.png" alt="Home"></a><a accesskey="n" href="tutorial/properties.html"><img src="../images/next.png" alt="Next"></a>
+</div>
+<div class="chapter" lang="en">
+<div class="titlepage">
+<div><div><h2 class="title">
+<a name="bbv2.tutorial"></a>Chapter 3. Tutorial</h2></div></div>
+<div></div>
+</div>
+<div class="toc">
+<p><b>Table of Contents</b></p>
+<dl>
+<dt><a href="tutorial.html#bbv2.tutorial.hello">Hello, world</a></dt>
+<dt><a href="tutorial/properties.html">Properties</a></dt>
+<dt><a href="tutorial/hierarchy.html">Project Hierarchies</a></dt>
+<dt><a href="tutorial/libs.html">Libraries and Dependent Targets</a></dt>
+<dt><a href="tutorial/depends.html">Library dependencies</a></dt>
+<dt><a href="tutorial/linkage.html">Static and shared libaries</a></dt>
+<dt><a href="tutorial/conditions.html">Conditions and alternatives</a></dt>
+<dt><a href="tutorial/prebuilt.html">Prebuilt targets</a></dt>
+</dl>
+</div>
+<div class="section" lang="en">
+<div class="titlepage">
+<div><div><h2 class="title" style="clear: both">
+<a name="bbv2.tutorial.hello"></a>Hello, world</h2></div></div>
+<div></div>
+</div>
+<p>The simplest project that Boost.Build can construct is
+      stored in <tt class="filename">example/hello/</tt> directory. The
+      project is described by a file
+      called <tt class="filename">Jamfile</tt> that contains:
+
+</p>
+<pre class="programlisting">
+exe hello : hello.cpp ;
+</pre>
+<p>
+
+      Even with this simple setup, you can do some interesting
+      things. First of all, just invoking <b class="command">bjam</b> will
+      build the debug variant of the <b class="command">hello</b>
+      executable by compiling and
+      linking <tt class="filename">hello.cpp</tt>.  Now, to build the
+      release variant of <b class="command">hello</b>, invoke
+
+</p>
+<pre class="screen">
+bjam release
+</pre>
+<p>
+
+      Note that debug and release variants are created in different
+      directories, so you can switch between variants or even build
+      multiple variants at once, without any unneccessary
+      recompilation. Let's extend the example by adding another line
+      to our project's <tt class="filename">Jamfile</tt>:
+
+</p>
+<pre class="programlisting">
+exe hello2 : hello.cpp ;
+</pre>
+<p>
+
+      Now we can build both the debug and release variants of our
+      project:
+
+</p>
+<pre class="screen">
+bjam debug release
+</pre>
+<p>
+
+      Note that two variants of <b class="command">hello2</b> are linked.
+      Since we have already built both variants
+      of <b class="command">hello</b>, hello.cpp won't be recompiled;
+      instead the existing object files will just be linked into the
+      corresponding variants of <b class="command">hello2</b>. Now 
+      let's remove all the built products:
+
+</p>
+<pre class="screen">
+bjam --clean debug release
+</pre>
+<p>
+
+      It's also possible to build or clean specific targets.  The
+      following two commands, respectively, build or clean only the
+      debug version of <b class="command">hello2</b>.
+
+</p>
+<pre class="screen">
+bjam hello2
+bjam --clean hello2
+</pre>
+</div>
+</div>
+<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
+<td align="left"></td>
+<td align="right"><small></small></td>
+</tr></table>
+<hr>
+<div class="spirit-nav">
+<a accesskey="p" href="installation.html"><img src="../images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../images/home.png" alt="Home"></a><a accesskey="n" href="tutorial/properties.html"><img src="../images/next.png" alt="Next"></a>
+</div>
+</body>
+</html>

Added: boost-jam/boost-build/branches/upstream/current/doc/html/boostbook.css
===================================================================
--- boost-jam/boost-build/branches/upstream/current/doc/html/boostbook.css	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/doc/html/boostbook.css	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,331 @@
+/*=============================================================================
+    Copyright (c) 2002 2004 Joel de Guzman
+    http://spirit.sourceforge.net/
+
+    Use, modification and distribution is subject to the Boost Software
+    License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+    http://www.boost.org/LICENSE_1_0.txt)
+=============================================================================*/
+
+/* CSS based on w3c documentation which I like a lot, and the classic Spirit
+documentation. */
+
+/* Body defaults */
+body 
+{
+    padding: 2em 1em 2em 1em;
+    margin: 1em 1em 1em 1em;
+    font-family: sans-serif;
+}
+
+/* Paragraphs */
+p 
+{
+    text-align: justify;
+}
+
+pre.synopsis
+{
+    margin: 1pc 4% 0pc 4%;
+    padding: 0.5pc 0.5pc 0.5pc 0.5pc;
+}
+
+/* Headings */
+h1, h2, h3, h4, h5, h6 { text-align: left; margin-top: 2pc; }
+h1 { font: 170% sans-serif }
+h2 { font: bold 140% sans-serif }
+h3 { font: 120% sans-serif }
+h4 { font: bold 100% sans-serif }
+h5 { font: italic 100% sans-serif }
+h6 { font: italic 100% sans-serif }
+
+/* Unordered lists */
+ul 
+{
+    text-align: justify;
+}
+
+/* Links */
+a
+{
+    text-decoration: none; /* no underline */
+}
+
+a:hover
+{
+    text-decoration: underline;
+}
+
+/* Top page title */
+title, h1.title, h2.title, h3.title,
+       h4.title, h5.title, h6.title,
+       .refentrytitle
+{
+    font-weight:   bold;
+    font-size:     2pc;
+    margin-bottom: 1pc;
+}
+
+/* Spirit style navigation */
+.spirit-nav
+{
+    text-align: right;
+}
+
+.spirit-nav a
+{
+    color: white;
+    padding-left: 0.5em;
+}
+
+.spirit-nav img
+{
+    border-width: 0px;
+}
+
+/* Program listing box */
+.programlisting, .screen
+{
+    display: block;
+    margin-left:  4%;
+    margin-right: 4%;
+    padding: 0.5pc 0.5pc 0.5pc 0.5pc;
+}
+
+/* Table of contents */
+.toc
+{
+   margin: 1pc 4% 0pc 4%;
+   padding: 0.5pc 0.5pc 0.5pc 0.5pc;
+}
+
+.boost-toc
+{
+   float:   right;
+   padding: 0.5pc;
+}
+
+/* Tables */
+.table-title, div.table p.title
+{
+    margin-left: 4%;
+    padding-right: 0.5em; 
+    padding-left: 0.5em;
+    font-size: 120%;
+}
+
+.informaltable table, .table table
+{
+    width: 92%;
+    margin-left: 4%;
+    margin-right: 4%;
+}
+
+div.informaltable table, div.table table
+{
+    padding: 4px 4px 4px 4px;
+}
+
+div.informaltable table tr td, div.table table tr td
+{
+    padding: 0.5em 0.5em 0.5em 0.5em;
+    text-align: justify;
+}
+
+div.informaltable table tr th, div.table table tr th
+{
+    padding: 0.5em 0.5em 0.5em 0.5em;
+    border: 1pt solid white;
+}
+
+/* inlined images */
+.inlinemediaobject
+{
+    padding: 0.5em 0.5em 0.5em 0.5em;
+}
+
+/* tone down the title of Parameter lists */
+div.variablelist p.title
+{
+    font-weight: bold;
+    font-size: 100%;
+    text-align: left;
+}
+
+/* tabularize parameter lists */
+div.variablelist dl dt
+{
+    float: left;
+    clear: left;
+    display: block;
+    font-style: italic;
+}
+
+div.variablelist dl dd
+{
+    display: block;
+    clear:   right;
+    padding-left: 8pc;
+}
+
+/* title of books and articles in bibliographies */
+span.title
+{
+    font-style: italic;
+}
+
+div.tip, div.note, div.warning
+{
+    padding: 0.5em 0.5em 0.5em 0.5em;
+    border: 1pt solid white;
+}
+
+div.tip .title, div.note .title, div.warning .title
+{
+    font: bold 100% sans-serif;
+    margin-top: 0pc;
+}
+
+div.tip .title:before
+{
+    content: url(images/tip.png) " ";
+}
+
+div.note .title:before
+{
+    content: url(images/note.png) " ";
+}
+
+div.warning .title:before
+{
+    content: url(images/caution.png) " ";
+}
+
+ at media screen
+{
+    a
+    {
+        color: #005a9c;
+    }
+
+    a:visited
+    {
+        color: #9c5a9c;
+    }
+
+    /* Syntax Highlighting */
+    .keyword        { color: #0000AA; font-weight: bold; }
+    .identifier     {}
+    .special        { color: #707070; }
+    .preprocessor   { color: #402080; font-weight: bold; }
+    .char           { color: teal; }
+    .comment        { color: #800000; }
+    .string         { color: teal; }
+    .number         { color: teal; }
+    .copyright      { color: #666666; font-size: small; }
+    .white_bkd      { background-color: #FFFFFF; }
+    .dk_grey_bkd    { background-color: #999999; }
+
+    pre.synopsis
+    {
+        background-color: #f3f3f3;
+    }
+
+    .programlisting, .screen
+    {
+        background-color: #f3f3f3;
+    }
+
+    /* Table of contents */
+    .toc
+    {
+        background-color: #f3f3f3;
+    }
+
+    div.informaltable table tr td, div.table table tr td
+    {
+        background-color: #F3F3F3;
+        border: 1pt solid white;
+    }
+
+    div.informaltable table tr th, div.table table tr th
+    {
+        background-color: #e4e4e4;
+    }
+
+    div.tip, div.note, div.warning
+    {
+        background-color: #F3F3F3;
+    }
+
+    span.highlight
+    {
+        color: #00A000;
+    }
+}
+
+ at media print
+{
+    a
+    {
+        color: black;
+    }
+
+    a:visited
+    {
+        color: black;
+    }
+
+    .spirit-nav
+    {
+        display: none;
+    }
+
+    /* Syntax Highlighting */
+    .keyword
+    {
+        font-weight: bold;
+    }
+
+    pre.synopsis
+    {
+        border: 1px solid gray;
+    }
+
+    .programlisting, .screen
+    {
+        border: 1px solid gray;
+    }
+
+    /* Table of contents */
+    .toc
+    {
+        border: 1px solid gray;
+    }
+
+    .informaltable table, .table table
+    {
+        border: 1px solid gray;
+        border-collapse: collapse;
+    }
+
+    div.informaltable table tr td, div.table table tr td
+    {
+        border: 1px solid gray;
+    }
+
+    div.informaltable table tr th, div.table table tr th
+    {
+        border: 1px solid gray;
+    }
+
+    div.tip, div.note, div.warning
+    {
+        border: 1px solid gray;
+    }
+
+    span.highlight
+    {
+        font-weight: bold;
+    }
+}

Added: boost-jam/boost-build/branches/upstream/current/doc/html/images/blank.png
===================================================================
(Binary files differ)


Property changes on: boost-jam/boost-build/branches/upstream/current/doc/html/images/blank.png
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: boost-jam/boost-build/branches/upstream/current/doc/html/images/caution.png
===================================================================
(Binary files differ)


Property changes on: boost-jam/boost-build/branches/upstream/current/doc/html/images/caution.png
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: boost-jam/boost-build/branches/upstream/current/doc/html/images/draft.png
===================================================================
(Binary files differ)


Property changes on: boost-jam/boost-build/branches/upstream/current/doc/html/images/draft.png
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: boost-jam/boost-build/branches/upstream/current/doc/html/images/home.png
===================================================================
(Binary files differ)


Property changes on: boost-jam/boost-build/branches/upstream/current/doc/html/images/home.png
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: boost-jam/boost-build/branches/upstream/current/doc/html/images/important.png
===================================================================
(Binary files differ)


Property changes on: boost-jam/boost-build/branches/upstream/current/doc/html/images/important.png
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: boost-jam/boost-build/branches/upstream/current/doc/html/images/next.png
===================================================================
(Binary files differ)


Property changes on: boost-jam/boost-build/branches/upstream/current/doc/html/images/next.png
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: boost-jam/boost-build/branches/upstream/current/doc/html/images/note.png
===================================================================
(Binary files differ)


Property changes on: boost-jam/boost-build/branches/upstream/current/doc/html/images/note.png
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: boost-jam/boost-build/branches/upstream/current/doc/html/images/prev.png
===================================================================
(Binary files differ)


Property changes on: boost-jam/boost-build/branches/upstream/current/doc/html/images/prev.png
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: boost-jam/boost-build/branches/upstream/current/doc/html/images/tip.png
===================================================================
(Binary files differ)


Property changes on: boost-jam/boost-build/branches/upstream/current/doc/html/images/tip.png
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: boost-jam/boost-build/branches/upstream/current/doc/html/images/toc-blank.png
===================================================================
(Binary files differ)


Property changes on: boost-jam/boost-build/branches/upstream/current/doc/html/images/toc-blank.png
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: boost-jam/boost-build/branches/upstream/current/doc/html/images/toc-minus.png
===================================================================
(Binary files differ)


Property changes on: boost-jam/boost-build/branches/upstream/current/doc/html/images/toc-minus.png
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: boost-jam/boost-build/branches/upstream/current/doc/html/images/toc-plus.png
===================================================================
(Binary files differ)


Property changes on: boost-jam/boost-build/branches/upstream/current/doc/html/images/toc-plus.png
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: boost-jam/boost-build/branches/upstream/current/doc/html/images/up.png
===================================================================
(Binary files differ)


Property changes on: boost-jam/boost-build/branches/upstream/current/doc/html/images/up.png
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: boost-jam/boost-build/branches/upstream/current/doc/html/images/warning.png
===================================================================
(Binary files differ)


Property changes on: boost-jam/boost-build/branches/upstream/current/doc/html/images/warning.png
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: boost-jam/boost-build/branches/upstream/current/doc/html/index.html
===================================================================
--- boost-jam/boost-build/branches/upstream/current/doc/html/index.html	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/doc/html/index.html	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,113 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+<title>Part I. Boost.Build v2 User Manual</title>
+<link rel="stylesheet" href="boostbook.css" type="text/css">
+<meta name="generator" content="DocBook XSL Stylesheets V1.61.3">
+<link rel="home" href="index.html" title="Part I. Boost.Build v2 User Manual">
+<link rel="next" href="bbv2/howto.html" title="Chapter 1. How to use this document">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<table cellpadding="2" width="100%"><td valign="top"><img alt="boost.png (6897 bytes)" width="277" height="86" src="../../boost.png"></td></table>
+<hr>
+<div class="spirit-nav"><a accesskey="n" href="bbv2/howto.html"><img src="images/next.png" alt="Next"></a></div>
+<div class="part" lang="en">
+<div class="titlepage">
+<div><div><h1 class="title">
+<a name="bbv2"></a>Boost.Build v2 User Manual</h1></div></div>
+<div></div>
+</div>
+<div class="toc">
+<p><b>Table of Contents</b></p>
+<dl>
+<dt>1. <a href="bbv2/howto.html">How to use this document</a>
+</dt>
+<dt>2. <a href="bbv2/installation.html">Installation</a>
+</dt>
+<dt>3. <a href="bbv2/tutorial.html">Tutorial</a>
+</dt>
+<dd><dl>
+<dt><a href="bbv2/tutorial.html#bbv2.tutorial.hello">Hello, world</a></dt>
+<dt><a href="bbv2/tutorial/properties.html">Properties</a></dt>
+<dt><a href="bbv2/tutorial/hierarchy.html">Project Hierarchies</a></dt>
+<dt><a href="bbv2/tutorial/libs.html">Libraries and Dependent Targets</a></dt>
+<dt><a href="bbv2/tutorial/depends.html">Library dependencies</a></dt>
+<dt><a href="bbv2/tutorial/linkage.html">Static and shared libaries</a></dt>
+<dt><a href="bbv2/tutorial/conditions.html">Conditions and alternatives</a></dt>
+<dt><a href="bbv2/tutorial/prebuilt.html">Prebuilt targets</a></dt>
+</dl></dd>
+<dt>4. <a href="bbv2/advanced.html">User documentation</a>
+</dt>
+<dd><dl>
+<dt><a href="bbv2/advanced.html#bbv2.advanced.configuration">Configuration</a></dt>
+<dt><a href="bbv2/advanced/jamfiles.html">Writing Jamfiles</a></dt>
+<dt><a href="bbv2/advanced/build_process.html">Build process</a></dt>
+<dt><a href="bbv2/advanced/builtins/targets.html">Builtin target types</a></dt>
+<dt><a href="bbv2/advanced/builtins/features.html">Builtin features</a></dt>
+<dt><a href="bbv2/advanced/differences_to_v1.html">Differences to Boost.Build V1</a></dt>
+</dl></dd>
+<dt>5. <a href="bbv2/extender.html">Extender Manual</a>
+</dt>
+<dd><dl>
+<dt><a href="bbv2/extender.html#bbv2.extender.intro">Introduction</a></dt>
+<dt><a href="bbv2/extending/targets.html">Target types</a></dt>
+<dt><a href="bbv2/extending/tools.html">Tools and generators</a></dt>
+<dt><a href="bbv2/extending/features.html">Features</a></dt>
+<dt><a href="bbv2/extending/rules.html">Main target rules</a></dt>
+<dt><a href="bbv2/extending/toolset_modules.html">Toolset modules</a></dt>
+</dl></dd>
+<dt>6. <a href="bbv2/reference.html">Detailed reference</a>
+</dt>
+<dd><dl>
+<dt><a href="bbv2/reference.html#bbv2.reference.general">General information</a></dt>
+<dt><a href="bbv2/reference/jamfiles.html">Writing Jamfiles</a></dt>
+<dt><a href="bbv2/reference/buildprocess.html">Build process</a></dt>
+<dt><a href="bbv2/reference/definitions.html"></a></dt>
+<dt><a href="bbv2/reference/generators.html">Generators</a></dt>
+</dl></dd>
+<dt>7. <a href="bbv2/faq.html">Frequently Asked Questions</a>
+</dt>
+<dd><dl>
+<dt><a href="bbv2/faq.html#id2540813">
+        I'm getting "Duplicate name of actual target" error. What
+        does it mean?
+      </a></dt>
+<dt><a href="bbv2/faq/s02.html">
+      Accessing environment variables
+      </a></dt>
+<dt><a href="bbv2/faq/s03.html">
+        How to control properties order?
+      </a></dt>
+<dt><a href="bbv2/faq/s04.html">
+      How to control the library order on Unix?
+    </a></dt>
+<dt><a href="bbv2/faq/external.html">Can I get output of external program as a variable in a Jamfile?
+    </a></dt>
+<dt><a href="bbv2/faq/s06.html">How to get the project-root location?
+    </a></dt>
+<dt><a href="bbv2/faq/s07.html">How to change compilation flags for one file?
+    </a></dt>
+<dt><a href="bbv2/faq/dll-path.html">Why are the dll-path and
+    hardcode-dll-paths properties useful?
+    </a></dt>
+<dt><a href="bbv2/recipies/site-config.html">Targets in site-config.jam</a></dt>
+</dl></dd>
+<dt>A. <a href="bbv2/arch.html">Boost.Build v2 architecture</a>
+</dt>
+<dd><dl>
+<dt><a href="bbv2/arch.html#bbv2.arch.overview">Overview</a></dt>
+<dt><a href="bbv2/arch/build.html">The build layer</a></dt>
+<dt><a href="bbv2/arch/tools.html">The tools layer</a></dt>
+<dt><a href="bbv2/arch/targets.html">Targets</a></dt>
+</dl></dd>
+</dl>
+</div>
+</div>
+<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
+<td align="left"><small><p>Last revised: October 21, 2004 at 10:05:15 GMT</p></small></td>
+<td align="right"><small></small></td>
+</tr></table>
+<hr>
+<div class="spirit-nav"><a accesskey="n" href="bbv2/howto.html"><img src="images/next.png" alt="Next"></a></div>
+</body>
+</html>

Added: boost-jam/boost-build/branches/upstream/current/doc/project-root.jam
===================================================================

Added: boost-jam/boost-build/branches/upstream/current/doc/src/advanced.xml
===================================================================
--- boost-jam/boost-build/branches/upstream/current/doc/src/advanced.xml	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/doc/src/advanced.xml	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,1408 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE chapter PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN"
+  "http://www.boost.org/tools/boostbook/dtd/boostbook.dtd">
+
+  <chapter id="bbv2.advanced">
+    <title>User documentation</title>
+
+  <para>This section will provide the information necessary to create your own
+  projects using Boost.Build. The information provided here is relatively
+  high-level, and <link linkend="bbv2.reference">detailed reference</link> as
+  well as the on-line help system must be used to obtain
+  low-level documentation (see the <link linkend=
+  "bbv2.reference.init.options.help">help option</link>).</para>
+
+  <para>The Boost.Build actually consists of two parts - Boost.Jam, which is a
+  build engine with its own interpreted language, and Boost.Build itself,
+  implemented in Boost.Jam's language. The chain of event which happen when
+  you type "bjam" on the command is:
+      <orderedlist>
+        <listitem>
+          <para>Boost.Jam tries to find Boost.Build and loads the top-level
+          module. The exact process is described in the <link
+          linkend="bbv2.reference.init">section on
+          initialization</link></para>
+        </listitem>
+        <listitem>
+          <para>Boost.Build top-level module loads user-defined configuration
+          files, "user-config.jam" and "site-config.jam", which define
+          available toolsets.</para>
+        </listitem>
+        <listitem>
+          <para>The Jamfile in the current directory is read. That in turn
+          might cause reading of further Jamfiles. As a result, a tree of
+          projects is created, with targets inside projects.</para>
+        </listitem>
+        <listitem>
+          <para>Finally, using build request specified on the command line,
+          Boost.Build decides which targets should be built, and how. That
+          information is passed back to Boost.Jam, which takes care of
+          actually running commands.</para>
+        </listitem>        
+      </orderedlist>
+    </para>
+
+    <para>So, to be able to successfully use Boost.Build, you'd need to know only
+      three things:
+      <itemizedlist>
+        <listitem>
+          <para><link linkend="bbv2.advanced.configuration">
+              How to configure Boost.Build</link></para>
+        </listitem>
+        <listitem>
+          <para><link linkend="bbv2.advanced.jamfiles">
+              How to write Jamfiles</link></para>
+        </listitem>
+        <listitem>
+          <para><link linkend="bbv2.advanced.build_process">
+              How the build process works</link></para>
+        </listitem>
+      </itemizedlist>
+    </para>
+    
+
+  <section id="bbv2.advanced.configuration">
+    <title>Configuration</title>
+
+    <para>The Boost.Build configuration is specified in the file
+    "user-config.jam". You can edit the one which comes with Boost.Build, or
+    create a copy in your home directory and edit that. (See the <link
+    linkend="bbv2.reference.init.config">reference</link> for the exact search
+    paths.) The primary function of that file is to declarate which compilers
+    and other tools are available. The simplest syntax to configure a tool is:
+<programlisting>
+using &lt;tool-name&gt; ;        
+</programlisting>
+      The "using" rule is given a name of tool, and will make that tool
+      available to Boost.Build. For example, "using gcc ;" will make available
+      the gcc compiler.      
+    </para>
+
+    <para>
+      Since nothing but tool name is specified, Boost.Build will pick some
+      default settings -- for example will use gcc found in path, or look in
+      some known installation locations. For ordinary users, this is quite
+      fine. In case you have several version of a compiler, or it's located in
+      some unusual location, or you need to tweak the configuration, you'd
+      need to pass additional parameters to the "using" rule. Generally, 
+      for every tool module, the parameters differ, and you can obtain the documentaiton
+      by running
+<programlisting>
+bjam --help &lt;tool-name&gt;.init         
+</programlisting>
+      on the command line. However, for all compilers the meaning of the first
+      three parameters is the same: version, invocation command and options.
+    </para>
+
+    <para>The "version" parameter identifies the compiler, in case you have
+    several. It can have any form you like, but it's recommended that you use
+    a numeric identifier, like &quot;7.1&quot;. The "invocation command"
+    parameter is the command which must be executed to run the compiler. This
+    might be just compiler name, or a name with a path in it. Here are some
+    examples. 
+    </para>
+      
+    <para>To configure a compiler installed in non-standard location and not
+    present in path, you can do the following:
+<programlisting>
+using msvc : : Z:/Programs/Microsoft Visual Studio/vc98/bin/cl.exe ;
+</programlisting>
+    </para>
+
+    <para>To configure several versions of a compiler, the following can be used.
+<programlisting>
+using gcc : 3.3 ;
+using gcc : 3.4 : g++-3.4 ;
+using gcc : 3.2 : g++-3.2 ;
+</programlisting>
+        Note that in the first call to "using", the compiler found in path
+      will be used, and there's no need to explicitly specify the command.
+    </para>
+
+    <para>As shown above, both "version" and "invocation command" parameters
+      are optional, but there's an important restriction: if you configure the
+      same compiler more then once, you must pass the "version" parameter
+      every time. For example, the following is not allowed:
+<programlisting>
+using gcc ;
+using gcc : 3.4 : g++-3.4 ;
+</programlisting>
+      because the first "using" does not specify the version. 
+    </para>
+
+    <para>The <code>options</code> parameter is used to fine-tune the
+      configuration. All compilers allow to pass four option, intentionally
+      similiar in spelling to builtin features: <code>cflags</code>,
+      <code>cxxflags</code>, <code>compileflags</code> and
+      <code>linkflags</code>. They specify additional options which will be
+      always passed to the corresponding tools. The <code>cflags</code> option
+      applies only to the C compiler, the <code>cxxflags</code> option applies
+      only to the C++ compiler and the <code>compileflags</code> options
+      applies to both. For example, to use 64 bit mode with gcc you can use:
+<programlisting>
+using gcc : 3.4 : : &lt;compileflags&gt;-m64 &lt;linkflags&gt;-m64 ;
+</programlisting>
+    </para>
+                
+    </section>
+
+  <section id="bbv2.advanced.jamfiles">
+    <title>Writing Jamfiles</title>
+
+    <section id="bbv2.advanced.overview">
+      <title>Overview</title>
+
+      <para>Jamfiles are the thing which is most important to the user,
+      bacause they declare the targets which should be build. Jamfiles are
+      also used for organizing targets -- each Jamfile is a separate project,
+      which can be build independently from the other projects.</para>
+
+      <para>Jamfile mostly contain calls to Boost.Build functions, which do
+        all the work, specifically:
+        <itemizedlist>
+          <listitem>
+            <para><link linkend="bbv2.advanced.targets">declare main
+                targets</link></para>
+          </listitem>
+          <listitem>
+            <para><link
+            linkend="bbv2.advanced.projects">define
+            project properties</link></para>
+          </listitem>
+          <listitem>
+            <para><link linkend="bbv2.advanced.other-rules">do various other
+            things</link></para>            
+          </listitem>
+        </itemizedlist>
+      </para>
+
+      <para>In addition to Jamfiles, Boost.Build has another user-editable
+        file, project-root.jam, which is mostly useful to declare constants
+        global to all the projects. It is described in more detail <link
+        linkend="bbv2.advanced.project-root">below</link>.
+      </para>
+
+<!--
+      <para>The most fundemental entity in Boost.Build is <emphasis>main
+          target</emphasis>. This is object that user want to construct from
+        sources and keep up to date with regard to those sources. Typical
+        examples of main targets are executable files and libraries.</para>
+      
+      <para>Main targets are grouped in <emphasis>projects</emphasis>. Their main
+        purpose is organization: related targets placed in one project,
+        can then be built together, or share some definitions.</para>
+      
+      <para>Main targets and projects are created as the result of reading
+        one or several Jamfiles. Each Jamfile is a file written in
+        Boost.Jam interpreted language, and typically contains calls to
+        functions provided by Boost.Build, which create main targets of
+        needed type, declare project attributes and access other
+        projects. The full list of functions provided by Boost.Build is
+        described <link linkend="bbv2.advanced.builtins">below</link>.
+        Of course, user can create his own functions, or it can directly
+        access Boost.Build internals from Jamfile, if builtin facilities are
+        not sufficient.</para>
+
+  <para>Each main target, or project can be built in a number of ways,
+  say with optimization or without. We'll call such entities
+  "metatargets". To make Boost.Build produce any real targets, user
+  issues <link linkend="bbv2.reference.buildreq">build request</link>,
+  which specifies metatargets to be built, and properties to be
+  used.</para>
+
+  <para>The <emphasis>properties</emphasis> are just (name,value) pairs that
+  describe various aspects of constructed objects, for example:</para>
+  <programlisting>
+&lt;optimization&gt;full &lt;inlining&gt;off
+</programlisting>
+
+  <para>Given the built request, Boost.Build figures out the targets
+  needed for requested metatargets with requested properties, how
+  they can be created, and whether exising files can be reused. It
+  finally issues command to create needed files, automatically
+  converting properties into appropricate command line options.</para>
+-->
+    </section>
+
+<!--
+    <section id="bbv2.advanced.roadmap">
+      <title>Your first project and roadmap</title>
+
+
+  <para>Creating your first project requires three steps:</para>
+
+  <orderedlist>
+    <listitem><simpara>Create an empty file called "Jamfile"</simpara></listitem>
+
+    <listitem>
+      <simpara>
+        Create an empty file called "project-root.jam"
+      </simpara>
+    </listitem>
+
+    <listitem>
+      <para>Either set your <envar>BOOST_BUILD_PATH</envar> environment
+    variant to Boost.Build root, or create a "boost-build.jam" file
+    with the following content:
+
+<programlisting>
+boost-build /path/to/boost.build ;
+</programlisting>
+
+      </para>
+    </listitem>
+  </orderedlist>
+
+  <para>After that, you can run the "bjam" command in the directory
+  where you've created the files. Surely, it won't do anything, but
+  it will run without error, at least. Your next steps might
+  be:</para>
+
+  <orderedlist>
+    <listitem>
+      <simpara>
+        Adding new main targets to the "Jamfile" file. The basic
+    syntax for declaring a main target is described <link linkend=
+    "bbv2.advanced.targets">below</link>, and all builtin functions for
+    declaring main targets are <link linkend=
+    "bbv2.advanced.builtins.targets">listed</link>.
+      </simpara>
+    </listitem>
+
+    <listitem>
+      <simpara>
+        Creating subprojects. Create a directory, put new Jamfile
+    there, and move some main targets to that Jamfile, or declare
+    new ones. The <link linkend="bbv2.advanced.projects">projects
+    reference</link> will help with this part.
+      </simpara>
+    </listitem>
+
+    <listitem>
+      <simpara>
+        Customizing Boost.Build for your needs. You might have
+    additional tools you want to run, or just want different
+    extension for some file. The <link linkend="bbv2.extending">extender manual</ulink> is waiting for
+    you.
+      </simpara>
+    </listitem>
+  </orderedlist>
+
+    </section>
+-->
+    <section id="bbv2.advanced.targets">
+      <title>Main targets</title>
+
+      <para id="bbv2.advanced.targets.main">
+        <emphasis>Main target</emphasis> is a user-defined named
+        entity which can be build, for example a named executable file.
+        Declaring a main target is usually done using one of <link linkend=
+          "bbv2.advanced.builtins.targets">main target functions</link>.
+        The user can also declare <ulink url=
+          "doc/extending.html#main_target_rules">custom main target
+          function</ulink>.</para>
+      
+      <para>Most main targets rules in Boost.Build use similiar
+        syntax:</para>
+
+<anchor id="bbv2.main-target-rule-syntax"/>
+<programlisting>
+function-name main-target-name 
+    : sources 
+    : requirements 
+    : default-build 
+    : usage-requirements 
+    ;
+</programlisting>
+
+      <itemizedlist>
+        <listitem>
+          <simpara>
+            "main-target-name" is the name used to request the target
+            on command line and to use it from other main targets. Main
+            target name may contain alphanumeric characters and symbols '-'
+            and '_';
+          </simpara>
+        </listitem>
+        
+        <listitem>
+          <simpara>
+            "sources" is the list of source files and other main
+            targets that must be combined. 
+          </simpara>
+        </listitem>
+        
+        <listitem>
+          <simpara>
+            "requirements" is the list of properties that must always
+            be present when this main target is built.
+          </simpara>
+        </listitem>
+        
+        <listitem>
+          <simpara>
+            "default-build" is the list of properties that will be used
+            unless some other value of the same feature is already
+            specified.
+          </simpara>
+        </listitem>
+        
+        <listitem>
+          <simpara>
+            "usage-requirements" is the list of properties that will be
+            propagated to all main targets that use this one, i.e. to all
+            dependents.
+          </simpara>
+        </listitem>
+      </itemizedlist>
+
+      <para>Note that the actual requirements, default-build and
+        usage-requirements attributes for a target are obtained by combining
+        the explicitly specified one with those specified for the project
+        where a target is declared.
+      </para>
+      <para>          
+        Some main target rules have shorter list of parameters, and
+        you should consult their documentation for details.
+      </para>
+      
+      <para>The list of sources specifies what should be processed to get
+        the resulting targets. Most of the time, it's just a list of
+        files. Sometimes, you'd want to use all files with the same
+        extension as sources, in which case you can use the "glob"
+        rule. Here are two examples:
+<programlisting>
+exe a : a.cpp ;
+exe b : [ glob *.cpp ] ;
+</programlisting>
+        Unless you specify a files with absolute path, the name is
+        considered relative to the source directory -- which is typically
+        the same as directory when Jamfile is located, but can be changed as
+        described <link linkend=
+          "bbv2.advanced.projects.attributes.projectrule">here</link>
+      </para>
+      
+      <para>
+        The list of sources can also reference other main targets. The
+        targets in the same project can be referred by using the name, and
+        targets in other project need to specify directory or a symbolic
+        name of the other project. For example:
+<programlisting>
+lib helper : helper.cpp ;
+exe a : a.cpp helper ;
+exe b : b.cpp ..//utils ;
+exe c : c.cpp /boost/program_options//program_opions ;
+</programlisting>
+        The first exe uses the library defined in the same project. The
+        second one uses some target (most likely library) defined by Jamfile
+        one level higher. Finally, the third target uses some <ulink
+          url="http://boost.org">C++ Boost</ulink> library, using the
+        symbolic name to refer to it. More information about it can be found
+        in <link linkend="bbv2.tutorial.libs">tutorial</link> and in 
+        <link linkend="bbv2.reference.ids">target id reference</link>.          
+      </para>
+
+<!--
+      <section id="bbv2.advanced.targets.requirements">        
+        <title>Requirements and usage-requirements</title>
+        
+        <para>The requirements argument specify what properties are absolutely
+        necessary for this main target. 
+      </section>
+-->
+      <para>Requirements are the properties that should always be present when
+        building a target. Typically, they are includes and defines:
+<programlisting>
+exe hello : hello.cpp : &lt;include&gt;/opt/boost &lt;define&gt;MY_DEBUG ;
+</programlisting>
+        In special circumstances, other properties can be used, for example if
+        a library does not work if it's shared, or a file can't be compiled
+        with optimization due to a compiler bug, one can use
+<programlisting>
+lib util : util.cpp : &lt;link&gt;static ;
+obj main : main.cpp : &lt;optimization&gt;off ;
+</programlisting>                
+      </para>
+
+      <para>Sometimes, requirements are necessary only for a specific
+        compiler, or build variant. The 
+        <link linkend="v2.reference.variants.propcond">conditional
+        properties</link> can be used in that case:
+<programlisting>
+lib util : util.cpp : &lt;toolset&gt;msvc:&lt;link&gt;static ;
+</programlisting>
+        In means when whenever <code>&lt;toolset&gt;msvc</code> property is
+        in build properties, the <code>&lt;link&gt;static</code> property will
+        be included as well. The conditional requirements can be "chained":
+<programlisting>
+lib util : util.cpp : &lt;toolset&gt;msvc:&lt;link&gt;static 
+                      &lt;link&gt;static:&lt;define&gt;STATIC_LINK ;
+</programlisting>
+        will set of static link and the <code>STATIC_LINK</code> define on the
+        <code>msvc</code> toolset.
+      </para>
+
+      <para>The default-build attribute is
+        a set of properties which should be used if build request does not
+        specify a value. For example:
+<programlisting>
+exe hello : hello.cpp : : &lt;threading&gt;multi ;
+</programlisting>
+        would build the target in multi-threaded mode, unless the user
+        explicitly requests single-threaded version. The difference between
+        requirements and default-build is that requirements cannot be
+        overriden in any way.
+      </para>
+
+      <para>A target of the same name can be declared several times. In that
+        case is declaration is called an
+        <firstterm>alternative</firstterm>. When the target is build, one of
+        the alternatives will be selected and use. Alternatives need not be
+        defined by the same main target rule. The following is OK:
+<programlisting>
+lib helpers : helpers.hpp ;
+alias helpers : helpers.lib : &lt;toolset&gt;msvc ;
+</programlisting>
+      </para>
+
+      <para>Building of the same main target can differ greatly from
+        platform to platform. For example, you might have different list
+        of sources for different compilers, or different options for those
+        compilers. Two approaches to this are explained in the 
+        <link linkend="bbv2.tutorial.conditions">tutorial</link>.
+      </para>
+
+      <para>Sometimes a main target is really needed only by some other main
+        target. For example, a rule that declares a test-suite uses a main
+        target that represent test, but those main targets are rarely needed
+        by themself.</para>
+
+      <para>It is possible to declare target inline, i.e. the "sources"
+        parameter may include call to other main rules. For example:</para>
+
+<programlisting>
+exe hello : hello.cpp 
+    [ obj helpers : helpers.cpp : &lt;optimization&gt;off ] ;
+</programlisting>
+
+      <para>
+        Will cause "helpers.cpp" to be always compiled without
+        optimization. It's possible to request main targets declared
+        inline, but since they are considered local, they are renamed to
+        "parent-main-target_name..main-target-name". In the example above,
+        to build only helpers, one should run "bjam hello..helpers".
+      </para>
+
+    </section>
+
+    <section id="bbv2.advanced.projects">
+      <title>Projects</title>
+
+      <para>As mentioned before, targets are grouped into project, and each
+        Jamfile is a separate project. Projects are useful because it allows
+        to group related targets together, define properties common to all
+        those targets, and assign a symbolic name to the project, allowing to
+        easily refer to the targets in the project. Two last goals are
+        accompished with the "project" rule.
+      </para>
+
+      <para>The rule has this syntax
+<programlisting>
+project id : &lt;attributes&gt; ;
+</programlisting>
+        Here, attributes is a sequence of (attribute-name,
+        attribute-value) pairs. The list of attribute names along with its
+        handling is also shown in the table below. For example, it is
+        possible to write:
+<programlisting>
+project tennis 
+    : requirements &lt;threading&gt;multi 
+    : default-build release
+    ;
+</programlisting>   
+      </para>
+
+      <para>The possible attributes are listed below.</para>
+
+      <para><emphasis>Project id</emphasis> is a short way to denote a project, as
+        opposed to the Jamfile's pathname. It is a hierarchical path,
+        unrelated to filesystem, such as "boost/thread". <link linkend=
+          "bbv2.reference.ids">Target references</link> make use of project ids to
+        specify a target.</para>
+
+      <para><emphasis>Source location</emphasis> specifies the directory where sources
+        for the project are located.</para>
+
+      <para><emphasis>Project requirements</emphasis> are requirements that apply to
+        all the targets in the projects as well as all subprojects.</para>
+
+      <para><emphasis>Default build</emphasis> is the build request that should be
+        used when no build request is specified explicitly.</para>
+
+      <para id="bbv2.advanced.projects.attributes.projectrule">
+        The default values for those attributes are
+        given in the table below.
+
+        <table>
+          <title/>
+          <tgroup cols="4">
+            <thead>
+              <row>
+                <entry>Attribute</entry>
+                
+                <entry>Name for the 'project' rule</entry>
+                
+                <entry>Default value</entry>
+                
+                <entry>Handling by the 'project' rule</entry>
+              </row>
+            </thead>
+            
+            <tbody>
+              
+              <row>
+                <entry>Project id</entry>
+                
+                <entry>none</entry>
+                
+                <entry>none</entry>
+                
+                <entry>Assigned from the first parameter of the 'project' rule.
+                  It is assumed to denote absolute project id.</entry>
+              </row>
+              
+              <row>
+                <entry>Source location</entry>
+                
+                <entry><literal>source-location</literal></entry>
+                
+                <entry>The location of jamfile for the project</entry>
+                
+                <entry>Sets to the passed value</entry>
+              </row>
+              
+              <row>
+                <entry>Requirements</entry>
+                
+                <entry><literal>requirements</literal></entry>
+                
+                <entry>The parent's requirements</entry>
+                
+                <entry>The parent's requirements are refined with the passed
+                  requirement and the result is used as the project
+                  requirements.</entry>
+              </row>
+              
+              <row>
+                <entry>Default build</entry>
+                
+                <entry><literal>default-build</literal></entry>
+                
+                <entry>none</entry>
+                
+                <entry>Sets to the passed value</entry>
+              </row>
+              
+              <row>
+                <entry>Build directory</entry>
+                
+                <entry><literal>build-dir</literal></entry>
+                
+                <entry>If parent has a build dir set, the value of it, joined
+                  with the relative path from parent to the current project.
+                  Otherwise, empty</entry>
+                
+                <entry>Sets to the passed value, interpreted as relative to the
+                  project's location.</entry>
+              </row>
+            </tbody>
+          </tgroup>
+        </table>
+        </para>
+      </section>
+
+    <section id="bbv2.advanced.other-rules">
+      <title>Additional Jamfile rules</title>
+
+      <para>There's a number of other helper rules which can be used in
+      Jamfile, described in the following table.</para>
+
+      <table>
+        <title/>
+        <tgroup cols="2">
+          <thead>
+            <row>
+              <entry>Rule</entry>
+              
+              <entry>Semantic</entry>
+            </row>
+          </thead>
+          
+          <tbody>
+            <row>
+              <entry><link linkend=
+                  "bbv2.advanced.projects.attributes.projectrule">project</link>
+              </entry>
+              
+              <entry>Define project attributes.</entry>
+            </row>
+            
+            <row>
+              <entry><link linkend=
+                  "bbv2.advanced.projects.relationships.useprojectrule">use-project</link></entry>
+              
+              <entry>Make another project known.</entry>
+            </row>
+            
+            <row>
+              <entry><link linkend=
+                  "bbv2.advanced.projects.relationships.buildprojectrule">build-project</link></entry>
+              
+              <entry>Build another project when this one is built.</entry>
+            </row>
+            
+            <row>
+              <entry><link linkend=
+                  "bbv2.reference.buildprocess.explict">explicit</link></entry>
+              
+              <entry>States that the target should be built only by explicit
+                request.</entry>
+            </row>
+            
+            <row>
+              <entry>glob</entry>
+              
+              <entry>Takes a list of wildcards, and returns the list of files
+                which match any of the wildcards.</entry>
+            </row>
+          </tbody>
+        </tgroup>
+      </table>
+    </section>
+      
+    <section id="bbv2.advanced.project-root">
+      <para>Each project is also associated with <emphasis>project root</emphasis>.
+        That's a root for a tree of projects, which specifies some global
+        properties.</para>
+      
+        <title>Project root</title>
+
+        <para>
+          Project root for a projects is the nearest parent directory
+          which contains a file called
+          <filename>project-root.jam</filename>. That file defines
+          certain properties which apply to all projects under project
+          root. It can:
+
+        <itemizedlist>
+          <listitem>
+            <simpara>
+              configure toolsets, via call to <literal>toolset.using</literal>
+            </simpara>
+          </listitem>
+          
+          <listitem>
+            <simpara>
+              refer to other projects, via the <literal>use-project</literal>
+              rule
+            </simpara>
+          </listitem>
+          
+          <listitem>
+            <simpara>
+              declare constants, via the <literal>constant</literal> and
+              <literal>path-constant</literal> rules.
+            </simpara>
+          </listitem>
+        </itemizedlist>
+
+      </para>
+
+      <para>To facilitate declaration of simple projects, Jamfile and
+        project-root can be merged together. To achieve this effect, the
+        project root file should call the <literal>project</literal> rule. The
+        semantic is precisely the same as if the call was made in
+        Jamfile, except that project-root.jam will start to serve as
+        Jamfile. The Jamfile in the directory of project-root.jam will be
+        ignored, and project-root.jam will be able to declare main
+        targets as usual.</para>
+      
+    </section>
+
+<!--
+      <section id="bbv2.advanced.projects.relationships">
+        <title>Project relationship</title>
+
+  <para>There are three kinds of project relationships.</para>
+
+  <para>First is parent-child. This relationship is established
+  implicitly: parent directories of a project are searched, and the
+  first found Jamfile is assumed to define the parent project. The
+  parent-child relationship affects only attribute values for the
+  child project.</para>
+
+  <para id="bbv2.advanced.projects.relationships.buildprojectrule">
+  Second is build relationship. Some
+  project may request to recursively build other projects. Those
+  project need not be child projects. The <literal>build-project</literal>
+  rule is used for that:</para>
+  <programlisting>
+    build-project src ;   
+</programlisting>
+
+  <para id="bbv2.advanced.projects.relationships.useprojectrule">
+  The third kind is the 'use'
+  relationship. In means that one project uses targets from
+  another. It is possible to just refer to target in other projects
+  using target id. However, if target id uses project id, it is
+  required that the project id is known. The
+  <literal>use-project</literal>
+  rule is employed to guarantee that.
+  </para>
+
+<programlisting>
+use-project ( id : location )
+</programlisting>
+
+        <para>
+It loads the project at the specified location, which makes
+its project id available in the project which invokes the rule. It
+is required that the <literal>id</literal> parameter passed to the
+<literal>use-project</literal> rule be equal to the id that the loaded
+project declared. At this moment, the <literal>id</literal> paremeter
+should be absolute project id.
+        </para>
+      </section>
+    </section>
+
+-->
+       
+  </section>
+  
+  <section id="bbv2.advanced.build_process">
+    <title>Build process</title>
+
+    <para>When you've described your targets, you want Boost.Build to run the
+      right tools and create the needed targets. This section will describe
+      two things: how you specify what to build, and how the main targets are
+      actually constructed.
+    </para>
+
+    <para>The most important thing to note is that in Boost.Build, unlike
+      other build tools, the targets you declare do not correspond to specific
+      files. What you declare in Jamfiles is more like "metatarget". Depending
+      on the properties that you specify on the command line, each
+      "metatarget" will produce a set of real targets corresponding to the
+      requested properties. It is quite possible that the same metatarget is
+      build several times with different properties, and will, of course,
+      produce different files.
+    </para>
+    <tip>
+      <para>
+        This means that for Boost.Build, you cannot directly obtain build
+        variant from Jamfile. There could be several variants requested by the
+        user, and each target can be build with different properties. 
+      </para>
+    </tip>
+
+    <section>
+      <title>Build request</title>
+
+      <para>
+        The command line specifies which targets to build and with what
+        properties. For example:
+<programlisting>
+bjam app1 lib1//lib1 toolset=gcc variant=debug optimization=full
+</programlisting>
+        would build two targets, "app1" and "lib1//lib1" with the specified
+        properties. You can refer to any targets, using 
+        <link linkend="bbv2.reference.ids">target id</link> and specify arbitrary
+        properties. Some of the properties are very common, and for them the name
+        of the property can be omitted. For example, the above can be written as:
+<programlisting>
+bjam app1 lib1//lib1 gcc debug optimization=full
+</programlisting>
+        The complete syntax which has some additional shortcuts if described <link
+          linkend="bbv2.reference.commandline">here</link>.
+      </para>
+    </section>
+
+    <section><title>Building a main target</title>
+
+      <para>When you request, directly or indirectly, a build of a main target
+        with specific requirements, the following steps are made. Some brief
+        explanation is provided, and more detailes are given in the <link
+        linkend="bbv2.reference.buildprocess">reference</link>.
+        <orderedlist>
+          
+          <listitem><para>Applying default build. If the default-build
+          property of a target specifies a value of a feature which is not
+          present in the build request, that value is added.</para></listitem>
+          
+          <listitem><para>Selecting the main target alternative to use. For
+              each alternative we look how many properties are present both in
+              alternative's requirements, and in build request. The
+              alternative with large number of matching properties is selected.
+            </para></listitem>
+          
+          <listitem><para>Determining "common" properties. The build request
+              is <link linkend="bbv2.reference.variants.proprefine">refined</link>
+              with target's requirements. The conditional properties in
+              requirements are handled as well. Finally, default values of
+              features are added.
+            </para></listitem>
+          
+          <listitem><para>Building targets referred by the sources list and
+              dependency properties. The list of sources and the properties
+              can refer to other target using <link
+              linkend="bbv2.reference.ids">target references</link>. For each
+              reference, we take all <link
+              linkend="bbv2.reference.features.attributes.propagated">propagated</link>
+              properties, refine them by explicit properties specified in the
+              target reference, and pass the resulting properties as build
+              request to the other target.              
+            </para></listitem>
+          
+          <listitem><para>Adding the usage requirements produces when building
+              dependencies to the "common" properties. When dependencies are
+              built in the previous step, they return both the set of created
+              "real" targets, and usage requirements. The usage requirements
+              are added to the common properties and the resulting property
+              set will be used for building the current target.              
+            </para></listitem>
+          
+          <listitem><para>Building the target using generators. To convert the
+              sources to the desired type, Boost.Build uses "generators" ---
+              objects which correspond to tools like compilers and
+              linkers. Each generator declares what type of targets in can
+              produce and what type of sources it requires. Using this
+              information, Boost.Build determines which generators must be run
+              to produce a specific target from specific sources. When
+              generators are run, they return the "real" targets.
+            </para></listitem>
+          
+          <listitem><para>Computing the usage requirements to be returned. The
+          conditional properties in usage requirements are expanded and the
+          result is returned.</para></listitem>
+        </orderedlist>        
+      </para>
+    </section>
+
+    <section><title>Building a project</title>
+
+      <para>Often, user request a build of a complete project, not just one
+        main target. In fact, invoking <command>bjam</command> without
+        parameters builds the project defined in the current directory.</para>
+
+      <para>When a project is build, the build request is passed without
+        modification to all main targets in that project. It's is possible to
+        prevent implicit building of a target in a project with the
+        <code>explicit</code> rule:
+<programlisting>
+explicit hello_test ;
+</programlisting>
+        would cause the <code>hello_test</code> target to be built only if
+        explicitly requested by the user or by some other target.
+      </para>
+
+      <para>The Jamfile for a project can include a number of
+      <code>build-project</code> rule calls, that specify additional projects
+      to be built.
+      </para>
+
+    </section>
+
+  </section>
+
+  <section id="bbv2.advanced.builtins.targets">
+    <title>Builtin target types</title>
+
+    <section>
+      <title>Programs</title>
+
+      <para>Programs are created using the <code>exe</code> rule, which
+        follows the <link linkend="bbv2.main-target-rule-syntax">common
+          syntax</link>. For example:
+<programlisting>
+exe hello : hello.cpp some_library.lib /some_project//library 
+          : &lt;threading&gt;multi 
+          ;
+</programlisting>
+        This will create an executable file from the sources -- in this case,
+        one C++ file, one library file present in the same directory, and
+        another library which is created by Boost.Build. Generally, sources
+        can include C and C++ files, object files and libraries. Boost.Build
+        will automatically try to convert targets of other types.
+      </para>
+
+      <tip>
+        <para>         
+          On Windows, if an application uses dynamic libraries, and both
+          the application and the libraries are built by Boost.Build, its not
+          possible to immediately run the application, because the
+          <literal>PATH</literal> environment variable should include the path
+          to the libraries. It means you have to either add the paths
+          manually, or place the application and the libraries to the same
+          directory, for example using the <link linkend="bbv2.builtins.stage">
+            stage</link> rule.
+      </para>
+      </tip>
+    </section>
+
+    <section>
+      <title>Libraries</title>
+
+      <para>Libraries are created using the <code>lib</code> rule, which
+        follows the <link linkend="bbv2.main-target-rule-syntax">common
+          syntax</link>. For example:
+<programlisting>
+lib helpers : helpers.cpp : &lt;include&gt;boost : : &lt;include&gt;. ;
+</programlisting>
+      </para>
+
+      <para>In the most common case, the <code>lib</code> creates a library
+        from the specified sources. Depending on the value of
+        &lt;link&gt; feature the library will be either static or
+        shared. There are two other cases. First is when the library is
+        installed somewhere in compiler's search paths, and should be
+        searched by the compiler (typically, using the <option>-l</option>
+        option). The second case is where the library is available as a 
+        prebuilt file and the full path is known.          
+        </para>
+      
+      <para>
+        The syntax for these case is given below:
+<programlisting>
+lib z : : &lt;name&gt;z &lt;search&gt;/home/ghost ;            
+lib compress : : &lt;file&gt;/opt/libs/compress.a ;
+</programlisting>
+        The <code>name</code> property specifies the name which should be
+        passed to the <option>-l</option> option, and the <code>file</code>
+        property specifies the file location. The <code>search</code> feature
+        specifies paths where the library should be searched. That feature can
+        be specified several time, or can be omitted -- in which case only
+        default compiler paths will be searched.
+      </para>
+
+      <para>The difference between using the <code>file</code> feature as
+        opposed to the <code>name</code> name feature together with the
+        <code>search</code> feature is that <code>file</code> is more
+        precise. A specific file will be used. On the other hand, the
+        <code>search</code> feature only adds a library path, and the
+        <code>name</code> feature gives the basic name of the library. The
+        search rules are specific to the linker. For example, given these
+        definition:
+<programlisting>
+lib a : : &lt;variant&gt;release &lt;file&gt;/pool/release/a.so ;
+lib a : : &lt;variant&gt;debug &lt;file&gt;/pool/debug/a.so ;
+lib b : : &lt;variant&gt;release &lt;file&gt;/pool/release/b.so ;
+lib b : : &lt;variant&gt;debug &lt;file&gt;/pool/debug/b.so ;
+</programlisting>
+        It's possible to use release version of <code>a</code> and debug
+        version of <code>b</code>. Had we used the <code>name</code> and
+        <code>search</code> features, the linker would always pick either
+        release or debug versions.
+      </para>
+      
+      <para>
+        For convenience, the following syntax is allowed:
+<programlisting>
+lib z ;
+lib gui db aux ;
+</programlisting>
+          and is does exactly the same as:
+<programlisting>
+lib z : : &lt;name&gt;z ;            
+lib giu : : &lt;name&gt;gui ;            
+lib db : : &lt;name&gt;db ;            
+lib aux : : &lt;name&gt;aux ;            
+</programlisting>
+      </para>
+          
+      <para>When a library uses another library you should put that another
+        library in the list of sources. This will do the right thing in all
+        cases. For portability, you should specify library dependencies even
+        for searched and prebuilt libraries, othewise, static linking on
+        Unix won't work. For example:
+<programlisting>
+lib z ;
+lib png : z : &lt;name&gt;png ;
+</programlisting>
+        </para>
+
+      <note>
+        <para>When a library (say, <code>a</code>), which has another
+          library, (say, <code>b</code>) is linked dynamically, the <code>b</code>
+          library will be incorporated in <code>a</code>. (If <code>b</code>
+          is dynamic library as well, then <code>a</code> will only refer to
+          it, and not include any extra code.) When the <code>a</code>
+          library is linked statically, Boost.Build will assure that all
+          executables which link to <code>a</code> will also link to
+          <code>b</code>.
+        </para>
+      </note>
+         
+      <para>One feature of Boost.Build which is very important for libraries
+        is usage requirements. For example, if you write:
+<programlisting>
+lib helpers : helpers.cpp : : : &lt;include&gt;. ;
+</programlisting>
+        then compiler include path for all targets which use
+        <code>helpers</code> will contain the directory where the target is
+        defined.path to "helpers.cpp". So, the user need only to add
+        <code>helpers</code> to the list of sources, and don't bother about
+        other requirements. This allows to greatly simplify Jamfiles.
+      </para>
+
+      <note>
+        <para>If you don't want shared libraries to include all libraries
+          which are specified in sources (especially statically linked ones),
+          you'd need to use the following:
+<programlisting>
+lib b : a.cpp ;
+lib a : a.cpp : &lt;use&gt;b : : &lt;library&gt;b ;
+</programlisting>
+          This specifies that <code>a</code> uses <code>b</code>, and causes
+          all executables which link to <code>a</code> also link to
+          <code>b</code>. In this case, even for shared linking, the
+          <code>a</code> library won't even refer to <code>b</code>.
+        </para>
+      </note>
+          
+    </section>
+
+    <section id="bbv2.builtins.alias">
+      <title>Alias</title>
+
+      <para>The <code>alias</code> rule follows the <link
+          linkend="bbv2.main-target-rule-syntax">common syntax</link>. For
+        example:
+<programlisting>
+alias core : im reader writer ;
+</programlisting>
+        will build the sources and return the generated source targets
+        without modification. 
+      </para>
+
+      <para>
+        The <code>alias</code> rule is a convenience tool. If you often build
+        the same group of targets at the same time, you can define the alias
+        to save typing.        
+      </para>
+
+      <para>
+        Another use of the <code>alias</code> rule is to change build
+        properties. For example, if you always want static linking for a
+        specific C++ Boost library, you can write the following:
+<programlisting>
+alias boost_thread : /boost/thread//boost_thread : &lt;link&gt;static ;
+</programlisting>
+        and use only the <code>boost_thread</code> alias in your Jamfiles.
+      </para>              
+
+      <para>
+        It is also allowed to specify usage requirements for the
+        <code>alias</code> target. If you write the following:
+<programlisting>
+alias header_only_library : : : :  &lt;include&gt;/usr/include/header_only_library ; 
+</programlisting>
+        then using <code>header_only_library</code> in sources will only add an
+        include path. Also note that when there are some sources, their usage
+        requirements are propagated, too. For example:
+<programlisting>
+lib lib : lib.cpp : : : &lt;include&gt;. ;
+alias lib_alias ;
+exe main : main.cpp lib_alias ;
+</programlisting>
+        will compile <filename>main.cpp</filename> with the additional include.
+      </para>
+ 
+    </section>
+
+    <section id="bbv2.builtins.stage">
+      <title>Installing</title>
+
+      <para>For installing the built target you should use the
+        <code>stage</code> rule follows the <link
+          linkend="bbv2.main-target-rule-syntax">common syntax</link>. For
+        example:
+<programlisting>
+stage dist : hello helpers ;
+</programlisting>
+        will cause the targets <code>hello</code> and <code>helpers</code> to
+        be moved to the <filename>dist</filename> directory. The directory can
+        be changed with the <code>location</code> property:
+<programlisting>
+stage dist : hello helpers : &lt;location&gt;/usr/bin ;
+</programlisting>
+      </para>
+
+      <para>
+        Specifying the names of all libraries to install can be boring. The
+        <code>stage</code> allows to specify only the top-level executable
+        targets to install, and automatically install all dependencies:
+<programlisting>
+stage dist : hello 
+           : &lt;traverse-dependencies&gt;on &lt;include-type&gt;EXE
+             &lt;include-type&gt;LIB
+           ;
+</programlisting>
+        will find all targets that <code>hello</code> depends on, and install
+        all of the which are either executables or libraries.
+      </para>
+        
+    </section>
+
+    <section id="bbv2.builtins.testing">
+
+      <title>Testing</title>
+
+      <para>Boost.Build has convenient support for running unit tests. The
+        simplest way is the <code>unit-test</code> rule, which follows the
+        <link linkend="bbv2.main-target-rule-syntax">common syntax</link>. For
+        example:
+<programlisting>
+unit-test helpers_test : helpers_test.cpp helpers ;
+</programlisting>
+      </para>
+
+      <para>The <code>unit-test</code> rule behaves like the
+        <code>exe</code> rule, but after the executable is created it is
+        run. If the executable returns error, the build system will also
+        return error and will try running the executable on the next
+        invocation until it runs successfully. This behaviour ensures that you
+        can't miss a unit test failure.
+      </para>
+
+      <para>There are rules for more elaborate testing: <code>compile</code>,
+        <code>compile-fail</code>, <code>run</code> and
+        <code>run-fail</code>. They are more suitable for automated testing, and
+        are not covered here yet.
+      </para>        
+    </section>
+    
+  </section>
+  
+  <section id="bbv2.advanced.builtins.features">
+    <title>Builtin features</title> 
+        
+    <variablelist>
+      <varlistentry><term><literal>variant</literal></term>
+        
+        <listitem>
+          <simpara>
+            The feature which combines several low-level features in
+            order to make building most common variants simple.
+          </simpara>
+          
+          <para><emphasis role="bold">Allowed values:</emphasis> <literal>debug</literal>, <literal>release</literal>,
+            <literal>profile</literal></para>
+          
+          <para>The value <literal>debug</literal> expands to</para>
+          
+          <programlisting>
+            &lt;optimization&gt;off &lt;debug-symbols&gt;on &lt;inlining&gt;off &lt;runtime-debugging&gt;on
+          </programlisting>
+          
+          <para>The value <literal>release</literal> expands to</para>
+          
+          <programlisting>
+            &lt;optimization&gt;speed &lt;debug-symbols&gt;off &lt;inlining&gt;full &lt;runtime-debugging&gt;off
+          </programlisting>
+          
+          <para>The value <literal>profile</literal> expands to the same as
+            <literal>release</literal>, plus:</para>
+          
+          <programlisting>
+            &lt;profiling&gt;on &lt;debug-symbols&gt;on
+          </programlisting>
+          
+          <para><emphasis role="bold">Rationale:</emphasis> Runtime debugging is on in debug build
+            to suit expectations of people used various IDEs. It's
+            assumed other folks don't have any specific expectation in
+            this point.</para>
+        </listitem></varlistentry>
+      
+      <varlistentry id="bbv2.advanced.builtins.features.link">
+        <term><literal>link</literal></term>
+        
+        <listitem>
+          <simpara>
+            Feature which controls how libraries are built.
+          </simpara>
+          
+          <para><emphasis role="bold">Allowed values:</emphasis> <literal>shared</literal>,
+            <literal>static</literal></para>
+        </listitem></varlistentry>
+      
+      <varlistentry><term><literal>source</literal></term>
+        
+        <listitem>
+          <simpara>
+            Tthe &lt;source&gt;X feature has the same effect on building a target
+            as putting X in the list of sources. The feature
+            is sometimes more convenient: you can put &lt;source&gt;X in
+            the requirements for a project and it will be linked to all
+            executables.
+          </simpara>
+        </listitem>
+      </varlistentry>
+      
+      <varlistentry><term><literal>library</literal></term>
+        
+        <listitem>
+          <simpara>
+            This feature is equivalent to the &lt;source&gt; feature, and exists
+            for backward compatibility reasons.
+          </simpara>
+        </listitem>
+      </varlistentry>
+      
+      
+      <varlistentry><term><literal>use</literal></term>
+        
+        <listitem>
+          <simpara>
+            Causes the target referenced by the value of this feature
+            to be constructed and adds it's usage requirements to build
+            properties. The constructed targets are not used in any other
+            way. The primary use case is when you use some library and want
+            it's usage requirements (such as include paths) to be applied,
+            but don't want to link to the library.
+          </simpara>
+        </listitem>
+      </varlistentry>
+      
+      <varlistentry><term><literal>dll-path</literal></term>
+        
+        <listitem>
+          <simpara>
+            Specify an additional path where shared libraries should be
+            searched where the executable or shared library is run. This
+            feature only affect Unix compilers. Plase see the <link
+            linkend="bbv2.faq.dll-path">FAQ entry</link> for details.
+          </simpara>
+        </listitem></varlistentry>
+      
+      <varlistentry><term><literal>hardcode-dll-paths</literal></term>
+        
+        <listitem>
+          <simpara>
+            Controls automatic generation of dll-path properties.
+          </simpara>
+          
+          <para><emphasis role="bold">Allowed values:</emphasis>
+            <literal>true</literal>, <literal>false</literal>.  This property
+            is specific to Unix systems. If an executable is build with
+            <code>&lt;hardcode-dll-paths&gt;true</code>, the generated binary
+            will contain the list of all the paths to the used shared
+            libraries. As the result, the executable can be run without
+            changing system paths to shared libraries, or installing the
+            libraries to system paths. This is very convenient during
+            development. Plase see the <link
+            linkend="bbv2.faq.dll-path">FAQ entry</link> for details.
+          </para>
+        </listitem></varlistentry>
+    </variablelist>
+  </section>
+
+  <section id="bbv2.advanced.differences_to_v1">
+    <title>Differences to Boost.Build V1</title>
+
+    <para>While Boost.Build V2 is based on the same ideas as Boost.Build V1,
+    some of the syntax was changed, and some new important features were
+    added. This chapter describes most of the changes.</para>
+
+    <section id="bbv2.advanced.differences_to_v1.configuration">
+      <title>Configuration</title>
+      
+      <para>In V1, there were two methods to configure a toolset. One is to
+      set some environment variable, or use "-s" command line option to set
+      variable inside BJam. Another method was creating new toolset module,
+      which would set the variables and then invoke basic toolset. Neither
+      method is necessary now, the "using" rule provides a consistent way to
+      initialize toolset, including several versions. See <link
+      linkend="bbv2.advanced.configuration">section on configuraton</link> for
+      details.
+      </para>
+      
+    </section>
+
+    <section id="bbv2.advanced.differences_to_v1.jamfiles">
+      <title>Writing Jamfiles</title>
+
+      <para>Probably one of the most important differences in V2 Jamfiles is
+      the project requirements. In V1, if several targets have the same
+      requirements (for example, common include path), it was necessary to
+      manually write that requirements, or use a helper rule. In V2, the
+      common properties can be specified with the "requirements" project
+      attribute, as documented <link linkend="bbv2.advanced.projects">here</link>.
+      </para>
+
+      <para>The <link linkend="bbv2.tutorial.libs">usage requirements</link>
+      is also important mechanism to simplify Jamfile. If a library requires
+      all clients to use specific includes, or macros when compiling the
+      code which depends on the library, this information can be cleanly
+      represented.</para>
+
+      <para>The difference between "lib" and "dll" targets in V1 is completely
+      eliminated in V2. There's only one target -- "lib", which can create
+      either static or shared library depending on the value of the 
+        <link linkend="bbv2.advanced.builtins.features.link">&lt;link&gt;
+      feature</link>. If your target should be only build in one variant, you
+      can add &lt;link&gt;shared or &lt;link&gt;static to requirements.
+      </para>
+
+      <para>The syntax for referring to other targets was changed a bit. While
+      in V1 one would use:
+<programlisting>
+exe a : a.cpp &lt;lib&gt;../foo/bar ;
+</programlisting> 
+        the V2 syntax is:
+<programlisting>
+exe a : a.cpp ../foo//bar ;
+</programlisting>
+        Note that you don't need to specify the type of other target, but the
+        last element should be separated to double slash, to indicate that
+        you're referring to target "bar" in project "../foo", and not to
+        project "../foo/bar".
+        </para>
+      
+                  
+    </section>
+
+    <section id="bbv2.advanced.differences_to_v1.build_process">
+      <title>Build process</title>
+
+      <para>The command line syntax in V2 is completely different. For example
+<programlisting>
+bjam -sTOOLS=msvc -sBUILD=release some_target
+</programlisting>
+        now becomes:
+<programlisting>
+bjam toolset=msvc variant=release some_target
+</programlisting>
+        or, using shortcuts, just:
+<programlisting>
+bjam msvc release some_target
+</programlisting>
+      See <link linkend="bbv2.reference.commandline">the reference</link> for
+      complete description of the syntax.
+      </para>
+
+            
+    </section>
+
+  </section>
+    
+
+  </chapter>
+
+<!--
+     Local Variables:
+     mode: xml
+     sgml-indent-data: t     
+     sgml-parent-document: ("userman.xml" "chapter")
+     sgml-set-face: t
+     End:
+-->

Added: boost-jam/boost-build/branches/upstream/current/doc/src/architecture.xml
===================================================================
--- boost-jam/boost-build/branches/upstream/current/doc/src/architecture.xml	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/doc/src/architecture.xml	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,564 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE appendix PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN"
+  "http://www.boost.org/tools/boostbook/dtd/boostbook.dtd">
+
+  <appendix id="bbv2.arch">
+    <title>Boost.Build v2 architecture</title>
+
+  <sidebar>
+    <para>This document is work-in progress. Don't expect much from it
+      yet.</para>
+  </sidebar>
+  
+  <section id="bbv2.arch.overview">
+    <title>Overview</title>
+
+    <para>The Boost.Build code is structured in four different components:
+    "kernel", "util", "build" and "tools". The first two are relatively
+    uninteresting, so we'll focus on the remaining pair. The "build" component
+    provides classes necessary to declare targets, determine which properties
+    should be used for their building, and for creating the dependency
+    graph. The "tools" component provides user-visible functionality. It
+    mostly allows to declare specific kind of main targets, and declare
+    avaiable tools, which are then used when creating the dependency graph.
+    </para>
+    
+  </section>
+
+  <section id="bbv2.arch.build">
+    <title>The build layer</title>
+
+    <para>The build layer has just four main parts -- abstract targets,
+      virtual targets, generators and properties. The abstract targets,
+      represented by the "abstract-target" class, correspond to main targets
+      -- which, as you recall, can produce different files depending on
+      properties. Virtual targets, represented by the 'virtual-target' class
+      correspond to real files. The abstract-target class has a method
+      'generate', which is given a set of properties and produces virtual
+      targets for those properties.       
+    </para>
+
+    <para>There are several classes derived from "abstract-target". The
+      "main-target" class represents top-level main target, the "project-target"
+      acts like container for all main targets, and "basic-target" class is a
+      base class for all further target types.
+    </para>
+
+    <para>Since each main target can have several alternatives, all top-level
+      target objects are just containers, referring to "real" main target
+      classes. The type is that container is "main-target". For example, given:
+<programlisting>
+alias a ;
+lib a : a.cpp : &lt;toolset&gt;gcc ;
+</programlisting>
+      we would have one-top level instance of "main-target-class", which will
+      contain one instance of "alias-target-class" and one instance of
+      "lib-target-class". The "generate" method of "main-target" decides
+      which of the alternative should be used, and call "generate" on the
+      corresponding instance.
+</para>
+
+    <para>Each alternative is a instance of a class derived from
+    "basic-target". The "basic-target.generate" does several things that are
+    always should be done:
+      <itemizedlist>
+        <listitem>
+          <para>Determines what properties should be used for building the
+          target. This includes looking at requested properties, requirements,
+          and usage requirements of all sources.</para>
+        </listitem>
+        <listitem>
+          <para>Builds all sources</para>
+        </listitem>
+        <listitem>
+          <para>Computes the usage requirements which should be passes back.</para>
+        </listitem>
+      </itemizedlist>
+      For the real work of constructing virtual target, a new method
+      "construct" is called.
+    </para>
+
+    <para>The "construct" method can be implemented in any way by classes
+      derived from "basic-target", but one specific derived class plays the
+      central role -- "typed-target". That class holds the desired type of file
+      to be produces, and calls the generators modules to do the job.
+    </para>
+
+    <para>Generators are Boost.Build abstractions for a tool. For example, one
+      can register a generator which converts target of type CPP into target of
+      type OBJ. When run with on a virtual target with CPP type, the generator
+      will construct the virtual target of type OBJ. The "generators" module
+      implements an algorithm, which given a list of sources, the desired type
+      and a list of properties, find all the generators which can perform the conversion.
+    </para>
+
+    <para>The virtual targets which are produces by the main targets form a
+      graph. Targets which are produces from other ones refer to an instance of
+      "action" class, which in turn refers to action's sources, which can
+      further refer to actions. The sources, which are not produces from
+      anything, don't refer to any actions.
+    </para>
+
+    <para>When all virtual targets are produced, they are "actualized". This
+    means that the real file names are computed, and the commands that should
+    be run are generated. This is done by "virtual-target.actualize" and
+    "action.actualize" methods. The first is conceptually simple, while the
+    second need additional explanation. The commands in bjam are generated in
+    two-stage process. First, a rule with the appropriate name (for example
+    "gcc.compile") is called and is given the names of targets. The rule sets
+    some variables, like "OPTIONS". After that, the command string is taken,
+    and variable are substitutes, so use of OPTIONS inside the command string
+    become the real compile options. 
+    </para>
+
+    <para>Boost.Build added a third stage to simplify things. It's now
+    possible to automatically convert properties to appropriate assignments to
+    variables. For example, &lt;debug-symbols&gt;on would add "-g" to the
+    OPTIONS variable, without requiring to manually add this logic to
+    gcc.compile. This functionality is part of the "toolset" module.
+    </para>
+    
+    <para>When target paths are computed and the commands are set, Boost.Build
+    just gives control to bjam, which controls the execution of
+    commands.</para>
+        
+  </section>
+
+  <section id="bbv2.arch.tools">
+    <title>The tools layer</title>
+
+    <para>Write me!</para>
+
+  </section>
+  
+    <section id="bbv2.arch.targets">
+      <title>Targets</title>
+
+  <para>NOTE: THIS SECTION IS NOT EXPECTED TO BE READ!
+        There are two user-visible kinds of targets in Boost.Build.
+  First are "abstract" &#x2014; they correspond to things declared
+  by user, for example, projects and executable files. The primary
+  thing about abstract target is that it's possible to request them
+  to be build with a particular values of some properties. Each
+  combination of properties may possible yield different set of
+  real file, so abstract target do not have a direct correspondence
+  with files.</para>
+
+  <para>File targets, on the contary, are associated with concrete
+  files. Dependency graphs for abstract targets with specific
+  properties are constructed from file targets. User has no was to
+  create file targets, however it can specify rules that detect
+  file type for sources, and also rules for transforming between
+  file targets of different types. That information is used in
+  constructing dependency graph, as desribed in the "next section".
+  [ link? ] <emphasis role="bold">Note:</emphasis>File targets are not
+  the same as targets in Jam sense; the latter are created from
+  file targets at the latest possible moment. <emphasis role="bold">Note:</emphasis>"File
+  target" is a proposed name for what we call virtual targets. It
+  it more understandable by users, but has one problem: virtual
+  targets can potentially be "phony", and not correspond to any
+  file.</para>
+
+    <section id="bbv2.arch.depends">
+      <title>Dependency scanning</title>
+
+  <para>Dependency scanning is the process of finding implicit
+  dependencies, like "#include" statements in C++. The requirements
+  for right dependency scanning mechanism are:</para>
+
+  <itemizedlist>
+    <listitem>
+      <simpara>
+        Support for different scanning algorithms. C++ and XML have
+    quite different syntax for includes and rules for looking up
+    included files.
+      </simpara>
+    </listitem>
+
+    <listitem>
+      <simpara>
+        Ability to scan the same file several times. For example,
+    single C++ file can be compiled with different include
+    paths.
+      </simpara>
+    </listitem>
+
+    <listitem>
+      <simpara>
+        Proper detection of dependencies on generated files.
+      </simpara>
+    </listitem>
+
+    <listitem>
+      <simpara>
+        Proper detection of dependencies from generated file.
+      </simpara>
+    </listitem>
+  </itemizedlist>
+
+      <section>
+        <title>Support for different scanning algorithms</title>
+
+  <para>Different scanning algorithm are encapsulated by objects
+  called "scanners". Please see the documentation for "scanner"
+  module for more details.</para>
+
+      </section>
+
+      <section>
+        <title>Ability to scan the same file several times</title>
+
+  <para>As said above, it's possible to compile a C++ file twice, with
+  different include paths. Therefore, include dependencies for
+  those compilations can be different. The problem is that bjam
+  does not allow several scans of the same target.</para>
+
+  <para>The solution in Boost.Build is straigtforward. When a virtual
+  target is converted to bjam target (via
+  <literal>virtual-target.actualize</literal> method), we specify the scanner
+  object to be used. The actualize method will create different
+  bjam targets for different scanners.</para>
+
+  <para>All targets with specific scanner are made dependent on target
+  without scanner, which target is always created. This is done in
+  case the target is updated. The updating action will be
+  associated with target without scanner, but if sources for that
+  action are touched, all targets &#x2014; with scanner and without
+  should be considered outdated.</para>
+
+  <para>For example, assume that "a.cpp" is compiled by two compilers
+  with different include path. It's also copied into some install
+  location. In turn, it's produced from "a.verbatim". The
+  dependency graph will look like:</para>
+
+<programlisting>
+a.o (&lt;toolset&gt;gcc)  &lt;--(compile)-- a.cpp (scanner1) ----+
+a.o (&lt;toolset&gt;msvc) &lt;--(compile)-- a.cpp (scanner2) ----|
+a.cpp (installed copy)    &lt;--(copy) ----------------------- a.cpp (no scanner)
+                                                                 ^
+                                                                 |
+                       a.verbose --------------------------------+
+</programlisting>
+
+      </section>
+      <section>
+        <title>Proper detection of dependencies on generated files.</title>
+
+  <para>This requirement breaks down to the following ones.</para>
+
+  <orderedlist>
+    <listitem>
+      <simpara>
+        If when compiling "a.cpp" there's include of "a.h", the
+    "dir" directory is in include path, and a target called "a.h"
+    will be generated to "dir", then bjam should discover the
+    include, and create "a.h" before compiling "a.cpp".
+      </simpara>
+    </listitem>
+
+    <listitem>
+      <simpara>
+      Since almost always Boost.Build generates targets to a
+    "bin" directory, it should be supported as well. I.e. in the
+    scanario above, Jamfile in "dir" might create a main target,
+    which generates "a.h". The file will be generated to "dir/bin"
+    directory, but we still have to recornize the dependency.
+      </simpara>
+    </listitem>
+  </orderedlist>
+
+  <para>The first requirement means that when determining what "a.h"
+  means, when found in "a.cpp", we have to iterate over all
+  directories in include paths, checking for each one:</para>
+
+  <orderedlist>
+    <listitem>
+      <simpara>
+        If there's file "a.h" in that directory, or
+      </simpara>
+    </listitem>
+
+    <listitem>
+      <simpara>
+        If there's a target called "a.h", which will be generated
+    to that directory.
+      </simpara>
+    </listitem>
+  </orderedlist>
+
+  <para>Classic Jam has built-in facilities for point (1) above, but
+  that's not enough. It's hard to implement the right semantic
+  without builtin support. For example, we could try to check if
+  there's targer called "a.h" somewhere in dependency graph, and
+  add a dependency to it. The problem is that without search in
+  include path, the semantic may be incorrect. For example, one can
+  have an action which generated some "dummy" header, for system
+  which don't have the native one. Naturally, we don't want to
+  depend on that generated header on platforms where native one is
+  included.</para>
+
+  <para>There are two design choices for builtin support. Suppose we
+  have files a.cpp and b.cpp, and each one includes header.h,
+  generated by some action. Dependency graph created by classic jam
+  would look like:</para>
+
+<programlisting>
+a.cpp -----&gt; &lt;scanner1&gt;header.h  [search path: d1, d2, d3]
+
+
+                  &lt;d2&gt;header.h  --------&gt; header.y
+                  [generated in d2]
+           
+b.cpp -----&gt; &lt;scanner2&gt;header.h [ search path: d1, d2, d4]
+</programlisting>
+
+    <para>
+In this case, Jam thinks all header.h target are not
+realated. The right dependency graph might be:
+
+<programlisting>
+a.cpp ---- 
+          \
+           \     
+            &gt;----&gt;  &lt;d2&gt;header.h  --------&gt; header.y
+           /       [generated in d2]
+          / 
+b.cpp ----
+</programlisting>
+
+or
+
+<programlisting>
+a.cpp -----&gt; &lt;scanner1&gt;header.h  [search path: d1, d2, d3]
+                          |
+                       (includes)
+                          V
+                  &lt;d2&gt;header.h  --------&gt; header.y
+                  [generated in d2]
+                          ^
+                      (includes)  
+                          |
+b.cpp -----&gt; &lt;scanner2&gt;header.h [ search path: d1, d2, d4]
+</programlisting>
+        </para>
+
+        <para>
+The first alternative was used for some time. The problem
+however is: what include paths should be used when scanning
+header.h? The second alternative was suggested by Matt Armstrong.
+It has similiar effect: add targets which depend on
+&lt;scanner1&gt;header.h will also depend on &lt;d2&gt;header.h.
+But now we have two different target with two different scanners,
+and those targets can be scanned independently. The problem of
+first alternative is avoided, so the second alternative is
+implemented now.
+        </para>
+
+  <para>The second sub-requirements is that targets generated to "bin"
+  directory are handled as well. Boost.Build implements
+  semi-automatic approach. When compiling C++ files the process
+  is:</para>
+
+  <orderedlist>
+    <listitem>
+      <simpara>
+        The main target to which compiled file belongs is found.
+      </simpara>
+    </listitem>
+
+    <listitem>
+      <simpara>
+        All other main targets that the found one depends on are
+    found. Those include main target which are used as sources, or
+    present as values of "dependency" features.
+      </simpara>
+    </listitem>
+
+    <listitem>
+      <simpara>
+        All directories where files belonging to those main target
+    will be generated are added to the include path.
+      </simpara>
+    </listitem>
+  </orderedlist>
+
+  <para>After this is done, dependencies are found by the approach
+  explained previously.</para>
+
+  <para>Note that if a target uses generated headers from other main
+  target, that main target should be explicitly specified as
+  dependency property. It would be better to lift this requirement,
+  but it seems not very problematic in practice.</para>
+
+  <para>For target types other than C++, adding of include paths must
+  be implemented anew.</para>
+
+      </section>
+      <section>
+        <title>Proper detection of dependencies from generated files</title>
+
+  <para>Suppose file "a.cpp" includes "a.h" and both are generated by
+  some action. Note that classic jam has two stages. In first stage
+  dependency graph graph is build and actions which should be run
+  are determined. In second stage the actions are executed.
+  Initially, neither file exists, so the include is not found. As
+  the result, jam might attempt to compile a.cpp before creating
+  a.h, and compilation will fail.</para>
+
+  <para>The solution in Boost.Jam is to perform additional dependency
+  scans after targets are updated. This break separation between
+  build stages in jam &#x2014; which some people consider a good
+  thing &#x2014; but I'm not aware of any better solution.</para>
+
+  <para>In order to understand the rest of this section, you better
+  read some details about jam dependency scanning, available
+  <ulink url=
+  "http://public.perforce.com:8080/@md=d&amp;cd=//public/jam/src/&amp;ra=s&amp;c=kVu@//2614?ac=10">
+  at this link</ulink>.</para>
+
+  <para>Whenever a target is updated, Boost.Jam rescans it for
+  includes. Consider this graph, created before any actions are
+  run.</para>
+
+<programlisting>
+A -------&gt; C ----&gt; C.pro
+     /
+B --/         C-includes   ---&gt; D
+</programlisting>
+
+        <para>
+Both A and B have dependency on C and C-includes (the latter
+dependency is not shown). Say during building we've tried to create
+A, then tried to create C and successfully created C.
+        </para>
+
+  <para>In that case, the set of includes in C might well have
+  changed. We do not bother to detect precisely which includes were
+  added or removed. Instead we create another internal node
+  C-includes-2. Then we determine what actions should be run to
+  update the target. In fact this mean that we perform logic of
+  first stage while already executing stage.</para>
+
+  <para>After actions for C-includes-2 are determined, we add
+  C-includes-2 to the list of A's dependents, and stage 2 proceeds
+  as usual. Unfortunately, we can't do the same with target B,
+  since when it's not visited, C target does not know B depends on
+  it. So, we add a flag to C which tells and it was rescanned. When
+  visiting B target, the flag is notices and C-includes-2 will be
+  added to the list of B's dependencies.</para>
+
+  <para>Note also that internal nodes are sometimes updated too.
+  Consider this dependency graph:</para>
+
+<programlisting>
+a.o ---&gt; a.cpp
+            a.cpp-includes --&gt;  a.h (scanned)
+                                   a.h-includes ------&gt; a.h (generated)
+                                                                 |
+                                                                 |
+            a.pro &lt;-------------------------------------------+
+</programlisting>
+
+  <para>Here, out handling of generated headers come into play. Say
+  that a.h exists but is out of date with respect to "a.pro", then
+  "a.h (generated)" and "a.h-includes" will be marking for
+  updating, but "a.h (scanned)" won't be marked. We have to rescan
+  "a.h" file after it's created, but since "a.h (generated)" has no
+  scanner associated with it, it's only possible to rescan "a.h"
+  after "a.h-includes" target was updated.</para>
+
+  <para>Tbe above consideration lead to decision that we'll rescan a
+  target whenever it's updated, no matter if this target is
+  internal or not.</para>
+
+  <warning>
+    <para>
+    The remainder of this document is not indended to be read at
+    all. This will be rearranged in future.
+    </para>
+  </warning>
+
+        <section>
+          <title>File targets</title>
+  
+          <para>
+  As described above, file targets corresponds
+  to files that Boost.Build manages. User's may be concerned about
+  file targets in three ways: when declaring file target types,
+  when declaring transformations between types, and when
+  determining where file target will be placed. File targets can
+  also be connected with actions, that determine how the target is
+  created. Both file targets and actions are implemented in the
+  <literal>virtual-target</literal> module.
+          </para>
+
+            <section> 
+              <title>Types</title>
+              
+              <para>A file target can be given a file, which determines
+  what transformations can be applied to the file. The
+  <literal>type.register</literal> rule declares new types. File type can
+  also be assigned a scanner, which is used to find implicit
+  dependencies. See "dependency scanning" [ link? ] below.</para>
+            </section>
+          </section>
+
+          <section>
+            <title>Target paths</title>
+
+  <para>To distinguish targets build with different properties, they
+  are put in different directories. Rules for determining target
+  paths are given below:</para>
+
+  <orderedlist>
+    <listitem>
+      <simpara>
+        All targets are placed under directory corresponding to the
+    project where they are defined.
+      </simpara>
+        </listitem>
+
+    <listitem>
+      <simpara>
+        Each non free, non incidental property cause an additional
+    element to be added to the target path. That element has the
+    form <literal>&lt;feature-name&gt;-&lt;feature-value&gt;</literal> for
+    ordinary features and <literal>&lt;feature-value&gt;</literal> for
+    implicit ones. [Note about composite features].
+      </simpara>
+        </listitem>
+
+    <listitem>
+      <simpara>
+        If the set of free, non incidental properties is different
+    from the set of free, non incidental properties for the project
+    in which the main target that uses the target is defined, a
+    part of the form <literal>main_target-&lt;name&gt;</literal> is added to
+    the target path. <emphasis role="bold">Note:</emphasis>It would be nice to completely
+    track free features also, but this appears to be complex and
+    not extremely needed.
+      </simpara>
+        </listitem>
+  </orderedlist>
+
+  <para>For example, we might have these paths:</para>
+
+<programlisting>
+debug/optimization-off
+debug/main-target-a
+</programlisting>
+
+          </section>
+        </section>
+      </section>
+    </section>
+  </appendix>
+
+<!--
+     Local Variables:
+     mode: xml
+     sgml-indent-data: t     
+     sgml-parent-document: ("userman.xml" "chapter")
+     sgml-set-face: t
+     End:
+-->

Added: boost-jam/boost-build/branches/upstream/current/doc/src/catalog.xml
===================================================================
--- boost-jam/boost-build/branches/upstream/current/doc/src/catalog.xml	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/doc/src/catalog.xml	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<!DOCTYPE catalog 
+  PUBLIC "-//OASIS/DTD Entity Resolution XML Catalog V1.0//EN"
+  "http://www.oasis-open.org/committees/entity/release/1.0/catalog.dtd">
+<catalog xmlns="urn:oasis:names:tc:entity:xmlns:xml:catalog">
+  <rewriteURI uriStartString="http://www.boost.org/tools/boostbook/dtd/" rewritePrefix="file:///home/ccurrie/src/boost/tools/boostbook/dtd//"/>
+  <rewriteURI uriStartString="http://docbook.sourceforge.net/release/xsl/current/" rewritePrefix="file:///shared/ccurrie/share/sgml/docbook/docbook-xsl-1.64.1/"/>
+  <rewriteURI uriStartString="http://www.oasis-open.org/docbook/xml/4.2/" rewritePrefix="file:///shared/ccurrie/share/sgml/docbook/docbook-dtd-4.2/"/>
+</catalog>

Added: boost-jam/boost-build/branches/upstream/current/doc/src/extending.xml
===================================================================
--- boost-jam/boost-build/branches/upstream/current/doc/src/extending.xml	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/doc/src/extending.xml	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,756 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE appendix PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN"
+  "http://www.boost.org/tools/boostbook/dtd/boostbook.dtd">
+
+  <chapter id="bbv2.extender">
+    <title>Extender Manual</title>
+
+    <section id="bbv2.extender.intro">
+      <title>Introduction</title>
+
+  <para>This document explains how to extend Boost.Build to accomodate
+  your local requirements. Let's start with quite simple, but
+  realistic example.</para>
+
+  <para>Say you're writing an application which generates C++ code. If
+  you ever did this, you know that it's not nice. Embedding large
+  portions of C++ code in string literals is very awkward. A much
+  better solution is:</para>
+
+  <orderedlist>
+    <listitem>
+      <simpara>
+        Write the template of the code to be generated, leaving
+    placeholders at the points which will change
+      </simpara>
+    </listitem>
+
+    <listitem>
+      <simpara>
+        Access the template in your application and replace
+    placeholders with appropriate text.
+      </simpara>
+    </listitem>
+
+    <listitem>
+      <simpara>Write the result.</simpara>
+    </listitem>
+  </orderedlist>
+
+  <para>It's quite easy to achieve. You write special verbatim files,
+  which are just C++, except that the very first line of the file
+  gives a name of variable that should be generated. A simple tool
+  is created which takes verbatim file and creates a cpp file with
+  a single char* variable, which name is taken from the first line
+  of verbatim file, and which value is properly quoted content of
+  the verbatim file.</para>
+
+  <para>Let's see what Boost.Build can do.</para>
+
+  <para>First off, Boost.Build has no idea about "verbatim files". So,
+  you must register a new type. The following code does it:</para>
+
+<programlisting>
+import type ;
+type.register VERBATIM : verbatim ;
+</programlisting>
+
+  <para>The first parameter to 'type.register' gives the name of
+  declared type. By convention, it's uppercase. The second
+  parameter is suffix for this type. So, if Boost.Build sees
+  "code.verbatim" in the list of sources, it knows that it's of
+  type <literal>VERBATIM</literal>.</para>
+
+  <para>Lastly, you need a tool to convert verbatim files to C++. Say
+  you've sketched such a tool in Python. Then, you have to inform
+  Boost.Build about the tool. The Boost.Build concept which
+  represents a tool is <emphasis>generator</emphasis>.</para>
+
+  <para>First, you say that generator 'inline-file' is able to convert
+  VERBATIM type into C++:</para>
+
+<programlisting>
+import generators ;
+generators.register-standard verbatim.inline-file : VERBATIM : CPP ;
+</programlisting>
+
+  <para>Second, you must specify the commands to be run to actually
+  perform convertion:</para>
+
+<programlisting>
+actions inline-file
+{
+    "./inline-file.py" $(&lt;) $(&gt;)
+}
+</programlisting>
+<!-- We use verbatim.inline-file in one place and just inline-file in
+             another. Is this confusing for user?
+        -->
+
+  <para>Now, we're ready to tie it all together. Put all the code
+  above in file "verbatim.jam", add "import verbatim ;" to
+  "project-root.jam", and it's possible to write the following in
+  Jamfile:</para>
+
+<programlisting>
+exe codegen : codegen.cpp class_template.verbatim usage.verbatim ;
+</programlisting>
+
+  <para>
+The verbatim files will be automatically converted into C++
+and linked it.
+  </para>
+
+      <para>In the subsequent sections, we will extend this example, and review
+        all the mechanisms in detail. The complete code is available in <ulink url=
+          "../../example/customization">example/customization</ulink>
+        directory.
+      </para>
+
+  </section>
+  <section id="bbv2.extending.targets">
+    <title>Target types</title>
+      <para>The first thing we did in the <link
+          linkend="bbv2.extender.intro">intruduction</link> was declaring a
+      new target type:
+<programlisting>
+import type ;
+type.register VERBATIM : verbatim ;
+</programlisting>
+        The type is the most important property of a target. Boost.Build can
+        automatically generate necessary build actions only because you
+        specify the desired type (using the different main target rules), and
+        because Boost.Build can guess the type of sources from their
+        extensions.        
+      </para>
+
+      <para>The first two parameters for the <code>type.register</code> rule
+        are the name of new type and the list of extensions associated with
+        it. A file with an extension from the list will have the given target
+        type. In the case where a target of the declared type is generated
+        from other sources, the first specified extension will be used. This
+        behaviour can be changed using the
+        <code>type.set-generated-target-suffix</code> rule.
+      </para>
+
+      <para>
+        Something about 'main' types.
+      </para>
+
+      <para>Something about base types.
+      </para>
+
+      <section id="bbv2.extending.scanners">
+        <title>Scanners</title>
+        <para>
+          Sometimes, a file can refer to other files via some include
+          mechanism. To make Boost.Build track dependencies to the included
+          files, you need to provide a scanner. The primary limitation is that
+          only one scanner can be assigned to a target type.
+        </para>
+
+        <para>First, we need to declare a new class for the scanner:
+<programlisting>
+class verbatim-scanner : common-scanner
+{
+    rule pattern ( )
+    {
+        return "//###include[ ]*\"([^\"]*)\"" ;
+    }
+}
+</programlisting>         
+          All the complex logic is in the <code>common-scanner</code> class,
+          and you only need to override the method which returns the regular
+          expression to be used for scanning. The paranthethis in the regular
+          expression indicate which part of the string is the name of the
+          included file. 
+        </para>
+
+        <para>After that, we need to register our scanner class:
+<programlisting>
+scanner.register verbatim-scanner : include ;
+</programlisting>
+            The value of the second parameter, in this case
+            <code>include</code>, specifies which properties contain the list
+            of paths which should be searched for the included files.
+         </para>
+
+        <para>Finally, we assign the new scaner to the <code>VERBATIM</code>
+        target type:
+<programlisting>
+type.set-scanner VERBATIM : verbatim-scanner ;
+</programlisting>
+          That's enough for scanning include dependencies.
+        </para>
+
+      </section>
+
+
+  </section>
+  
+  <section id="bbv2.extending.tools">
+    <title>Tools and generators</title>
+      <para>
+        This section will describe how Boost.Build can be extended to support
+        new tools.
+      </para>
+
+      <para>For each additional tool, a Boost.Build object called generator
+        must be created. That object has specific types of targets which it
+        accepts an produces. Using that information, Boost.Build is able
+        to automatically invoke the generator. For example, if you declare a
+        generator which takes a target of the type <literal>D</literal> and
+        produces a target of the type <literal>OBJ</literal>, when placing a
+        file with extention <literal>.d</literal> in a list of sources will
+        cause Boost.Build to invoke your generator, and then to link the
+        resulting object file into an application. (Of course, this requires
+        that you specify that the <literal>.d</literal> extension corresponds
+        to the <literal>D</literal> type.)
+      </para>
+
+      <para>Each generator should be an instance of a class derived from the
+        <code>generator</code> class. In the simplest case, you don't need to
+        create a derived class, but simply create an instance of the
+        <code>generator</code> class. Let's review the example we've seen in the
+        <link linkend="bbv2.extender.intro">introduction</link>.
+<programlisting>
+import generators ;
+generators.register-standard verbatim.inline-file : VERBATIM : CPP ;
+actions inline-file
+{
+    "./inline-file.py" $(&lt;) $(&gt;)
+}
+</programlisting>
+      </para>
+
+      <para>We declare a standard generator, specifying its id, the source type
+        and the target type. When invoked, the generator will create a target
+        of type <literal>CPP</literal> which will have the source target of
+        type <literal>VERBATIM</literal> as the only source. But what command
+        will be used to actually generate the file? In bjam, actions are
+        specified using named "actions" blocks and the name of the action
+        block should be specified when creating targets. By convention,
+        generators use the same name of the action block as their own id. So,
+        in above example, the "inline-file" actions block will be use to
+        convert the source into the target.
+      </para>
+
+      <para>
+        There are two primary kinds of generators: standard and composing,
+        which are registered with the
+        <code>generators.register-standard</code> and the
+        <code>generators.register-composing</code> rules, respectively. For
+        example:
+<programlisting>
+generators.register-standard verbatim.inline-file : VERBATIM : CPP ;
+generators.register-composing mex.mex : CPP LIB : MEX ;
+</programlisting>
+        The first generators takes a <emphasis>single</emphasis> source of type
+        <code>VERBATIM</code> and produces a result. The second generator
+        takes any number of sources, which can have either the
+        <code>CPP</code> or the <code>LIB</code> type. Composing generators
+        are typically used for generating top-level target type. For example,
+        the first generator invoked when building an <code>exe</code> target
+        is a composing generator corresponding to the proper linker.
+      </para>
+
+      <para>You should also know about two specific function for registering
+        generators: <code>generators.register-c-compiler</code> and
+        <code>generators.register-linker</code>. The first sets up header
+        dependecy scanning for C files, and the seconds handles various
+        complexities like searched libraries. For that reason, you should always
+        use those functions when adding support for compilers and linkers.
+      </para>
+
+      <para>(Need a note about UNIX)</para>
+
+      <bridgehead>Custom generator classes</bridgehead>
+
+      <para>The standard generators allows you to specify source and target
+        types, action, and a set of flags. If you need anything more complex,
+        you need to create a new generator class with your own logic. Then,
+        you have to create an instance of that class and register it. Here's
+        an example how you can create your own generator class:
+<programlisting>
+class custom-generator : generator
+{
+    rule __init__ ( * : * )
+    {
+        generator.__init__ $(1) : $(2) : $(3) : $(4) : $(5) : $(6) : $(7) : $(8) : $(9) ;
+    }
+}
+
+generators.register 
+  [ new custom-generator verbatim.inline-file : VERBATIM : CPP ] ;
+</programlisting>
+        This generator will work exactly like the
+        <code>verbatim.inline-file</code> generator we've defined above, but
+        it's possible to customize the behaviour by overriding methods of the
+        <code>generator</code> class.
+      </para>
+
+      <para>There are two methods of interest. The <code>run</code> methods is
+        responsible for overall process - it takes a number of source targets,
+        converts them the the right types, and creates the result. The
+        <code>generated-targets</code> method is called when all sources are
+        converted to the right types to actually create the result.
+      </para>
+
+      <para>The <code>generated-target</code> method can be overridden when you
+        want to add additional properties to the generated targets or use
+        additional sources. For example (which is real), you have a tool for
+        analysing programs, which should be given a name of executable and the
+        list of all sources. Naturally, you don't want to list all source
+        files manually. Here's how the <code>generated-target</code> method
+        can find the list of sources automatically:
+<programlisting>
+class itrace-generator : generator {
+....
+    rule generated-targets ( sources + : property-set : project name ? )
+    {
+        local leafs ;
+        local temp = [ virtual-target.traverse $(sources[1]) : : include-sources ] ;
+        for local t in $(temp)
+        {
+            if ! [ $(t).action ]
+            {
+                leafs += $(t) ;
+            }
+        }
+        return [ generator.generated-targets $(sources) $(leafs)
+          : $(property-set) : $(project) $(name) ] ;
+    }
+}
+generators.register [ new itrace-generator nm.itrace : EXE : ITRACE ] ;
+</programlisting>
+        The <code>generated-targets</code> rule will be called with a single
+        source target of type <literal>EXE</literal>. The call to the
+        <code>virtual-target.traverse</code> will return all targets the
+        executable depends on, and we further find files which are not
+        produced from anything. The found targets are added to the sources.
+      </para>
+      
+      <para>The <code>run</code> method can be overriden to completely
+        customize the way generator works. In particular, the conversion of
+        sources to the desired types can be completely customized. Here's
+        another real example. Tests for the Boost Python library usually
+        consist of two parts: a Python program and a C++ file. The C++ file is
+        compiled to Python extension which is loaded by the Python
+        program. But in the likely case that both files have the same name,
+        the created Python extension must be renamed. Otherwise, Python
+        program will import itself, not the extension. Here's how it can be
+        done:
+<programlisting>
+rule run ( project name ? : property-set : sources * : multiple ? )
+{       
+    local python ;
+    for local s in $(sources)
+    {
+        if [ $(s).type ] = PY
+        {
+            python = $(s) ;
+        }
+    }
+    
+    local libs ;
+    for local s in $(sources)
+    {
+        if [ type.is-derived [ $(s).type ] LIB ]
+        {
+            libs += $(s) ;
+        }
+    }
+    
+    local new-sources ;
+    for local s in $(sources)
+    {
+        if [ type.is-derived [ $(s).type ] CPP ] 
+        {
+            local name = [ $(s).name ] ;
+            if $(name) = [ $(python).name ] 
+            {
+                name = $(name)_ext ;
+            }                                
+            new-sources += [ generators.construct $(project) $(name) :
+              PYTHON_EXTENSION : $(property-set) : $(s) $(libs) ] ;
+        }
+    }
+        
+    result = [ construct-result $(python) $(new-sources) : $(project) $(name) 
+                 : $(property-set) ] ;        
+}    
+</programlisting>        
+        First, we separate all source into python files, libraries and C++
+        sources. For each C++ source we create a separate Python extension by
+        calling <code>generators.construct</code> and passing the C++ source
+        and the libraries. At this point, we also change the extension's name,
+        if necessary.        
+      </para>
+
+ 
+    </section>
+
+    <section id="bbv2.extending.features">
+      <title>Features</title>
+      <para>
+        Often, we need to control the options passed the invoked tools. This 
+        is done with features. Consider an example:
+<programlisting>
+# Declare a new feature
+import feature : feature ;
+feature verbatim-options : : free ;
+
+# Cause the value of the 'verbatim-options' feature to be
+# available as 'OPTIONS' variable inside verbatim.inline-file
+import toolset : flags ;
+flags verbatim.inline-file OPTIONS &lt;verbatim-options&gt; ;
+
+# Use the "OPTIONS" variable
+actions inline-file
+{
+    "./inline-file.py" $(OPTIONS) $(&lt;) $(&gt;)
+}
+</programlisting>
+        We first define a new feature. Then, the <code>flags</code> invocation
+        says that whenever verbatin.inline-file action is run, the value of
+        the <code>verbatim-options</code> feature will be added to the
+        <code>OPTIONS</code> variable, an can be used inside the action body.
+        You'd need to consult online help (--help) to find all the features of
+        the <code>toolset.flags</code> rule.
+      </para>
+
+    <para>
+      Although you can define any set of features and interpret their values
+      in any way, Boost.Build suggests the following coding standard for
+      designing features.
+    </para>
+
+    <para>Most features should have a fixed set of values, which is portable
+      (tool neutral) across the class of tools they are designed to work
+      with. The user does not have to adjust the values for a exact tool.  For
+      example, <code>&lt;optimization&gt;speed</code> has the same meaning for
+      all C++ compilers and the user does not have to worry about the exact
+      options which are passed to the compiler's command line.
+    </para>
+
+    <para>
+      Besides such portable features there are special 'raw' features which
+      allow the user to pass any value to the command line parameters for a
+      particular tool, if so desired. For example, the
+      <code>&lt;cxxflags&gt;</code> feature allows to pass any command line
+      options to a C++ compiler. The <code>&lt;include&gt;</code> feature
+      allows to pass any value to the <code>-I</code> and the interpretation
+      is tool-specific. (There an <link
+      linkend="bbv2.faq.external">example</link> of very smart usage of that
+      feature).  Of course one should always strive to use the portable
+      features but these should still be provided as a backdoor just to make
+      sure Boost.Build does not take away any control from the user. 
+    </para>
+   
+    <para>
+      Some of the reasons why portable features are better are:
+      <itemizedlist>
+        <listitem>
+          <para>Since a portable feature have a fixed set of value, you will
+            be able to build your project with two different settings of the
+            feature. Boost.Build will automatically use two different
+            directories for produced files. If you pass raw compiler options,
+            Boost.Build assumes you know what you are doing, and would not
+            care about what options are passed.
+          </para>
+        </listitem>
+        
+        <listitem>
+          <para>Unlike "raw" features, you don't need to use specific
+            compiler flags in Jamfile, and it will more likely work on other systems.
+          </para>
+        </listitem>
+      </itemizedlist>
+    </para>
+           
+      <bridgehead>Steps for adding a feauture</bridgehead>
+      <para>Adding a feature requires three steps:
+
+        <orderedlist>
+          <listitem><para>Declaring a feature. For that, the "feature.feature"
+              rule is used. You should have to decide on the set of <link
+              linkend="bbv2.reference.features.attributes">feature
+              attributes</link>:
+
+              <itemizedlist>
+                <listitem><para>if feature has several values, and
+                    significally affects build, make it "propagated", so that
+                    whole project is build with the same value by
+                    default</para></listitem> 
+
+                <listitem><para>if a feature does not have a fixed list of
+                    values, it must be "free".</para></listitem>
+
+                <listitem><para>if feature is used to refer to a path, it must
+                be "path".</para></listitem>
+        
+                <listitem><para>if feature is used to refer to some target, it
+                must be "dependency".</para></listitem>
+              </itemizedlist>
+              </para>
+          </listitem>
+              
+
+          <listitem><para>Converting the feature value into variable. To use
+              feature in build action, it must be converted into a variable,
+              accessible in build action. This is accomplished by
+              "toolset.flags" rule.</para></listitem>
+
+      
+          <listitem><para>Using the variable. The variable set in step 2 can
+              be used in build action to form command parameters or
+              files.</para></listitem>
+
+        </orderedlist>
+      </para>
+
+      <bridgehead>Another example</bridgehead>
+
+      <para>Here's an another example.
+        Let's see how we can make a feature which refers to a target. For example,
+        when linking dynamic libraries on windows, one sometimes needs to specify
+        "DEF file", telling what functions should be exported. It would be nice to
+        use this file like this:
+<programlisting>
+        lib a : a.cpp : &lt;def-file&gt;a.def ;
+</programlisting>
+        Actually, this feature is already supported, but anyway...
+      </para>
+
+      <orderedlist>
+        <listitem>
+          <para>Since the feature refers to a target, it must be "dependency".
+<programlisting>
+feature def-file : : free dependency ;
+</programlisting>
+            </para></listitem>
+
+        <listitem><para>One of the toolsets which cares about DEF files is
+msvc. The following line should be added to it.
+
+<programlisting>
+flags msvc.link DEF_FILE &lt;def-file&gt; ;
+</programlisting>
+            </para></listitem>
+
+        <listitem><para>Since the DEF_FILE variable is not used by the
+msvc.link action, we need to modify it to be:
+
+<programlisting>
+actions link bind DEF_FILE
+{
+    $(.LD) .... /DEF:$(DEF_FILE) ....
+}
+</programlisting>
+            </para>
+          
+          
+          <para> Note the "bind DEF_FILE" part. It tells bjam that DEF_FILE
+            refers to a file, otherwise the variable will contain internal
+            target name, which is not likely to make sense for the linker.
+          </para>
+
+          <para>
+            We've almost done, but should stop for a small workaround. Add the following
+            code to msvc.jam
+
+<programlisting>
+rule link
+{
+    DEPENDS $(&lt;) : [ on $(&lt;) return $(DEF_FILE) ] ;
+}
+</programlisting>
+
+            This is needed to accomodate some bug in bjam, which hopefully
+            will be fixed one day.</para></listitem>
+
+      </orderedlist>
+
+      <bridgehead>Variants and composite features.</bridgehead>
+
+      <para>Sometimes you want to create a shorcut for some set of
+        features. For example, <code>release</code> is a value of the
+        <code>variant</code> and is a shortcut for a set of features.
+        </para>.
+
+      <para>It is possible to define your build variants. For example:
+<programlisting>
+variant crazy : &lt;optimization&gt;speed &lt;inlining&gt;off
+                &lt;debug-symbols&gt;on &lt;profiling&gt;on ;
+</programlisting>
+        will define a new variant with the specified set of properties. You
+        can also extend an existing variant:
+<programlisting>
+variant super_release : release : &lt;define&gt;USE_ASM ;
+</programlisting>
+        In this case, <code>super_release</code> will expand to all properties
+        specified by <code>release</code>, and the additional one you've specified.
+      </para>
+
+      <para>You are not restricted to using the <code>variant</code> feature
+      only. Here's example which defines a brand new feature:
+<programlisting>
+feature parallelism : mpi fake none : composite link-incompatible ;
+feature.compose &lt;parallelism&gt;mpi : &lt;library&gt;/mpi//mpi/&lt;parallelism&gt;none ;
+feature.compose &lt;parallelism&gt;fake : &lt;library&gt;/mpi//fake/&lt;parallelism&gt;none ;
+</programlisting>
+        This will allow you to specify value of feature
+        <code>parallelism</code>, which will expand to link to the necessary
+        library. 
+      </para>
+     
+  </section>
+  
+  <section id="bbv2.extending.rules">
+    <title>Main target rules</title>
+    <para>
+      The main target rule is what creates a top-level target, for example "exe" or
+      "lib". It's quite likely that you'll want to declare your own and
+      there are as many as three ways to do that.
+    </para>
+    
+    <para>The first is the simplest, but is sufficient in a number of
+      cases. Just write a wrapper rule, which will redirect to any of the
+      existing rules. For example, you have only one library per directory and
+      want all cpp files in the directory to be compiled. You can achieve this
+      effect with:
+<programlisting>
+lib codegen : [ glob *.cpp ] ;
+</programlisting>
+      but what if you want to make it even simple. Then, you add the following
+      definition to the project-root.jam file:
+<programlisting>
+rule glib ( name : extra-sources * : requirements * )
+{
+    lib $(name) : [ glob *.cpp ] $(extra-sources) : $(requirements) ;
+}
+</programlisting>
+which would allow to reduce Jamfile to
+<programlisting>
+glib codegen ;
+</programlisting>
+    </para>
+
+    <para>The second approach is suitable when your target rule should just
+      produce a target of specific type. Then, when declaring a type you
+      should tell Boost.Build that a main target rule should be created.
+      For example, if you create a module "obfuscate.jam" containing:
+
+<programlisting>
+import type ;
+type.register OBFUSCATED_CPP  : ocpp : : main ;
+
+import generators ;
+generators.register-standard obfuscate.file : CPP : OBFUSCATED_CPP ;
+</programlisting>
+      and import that module, you'll be able to use the rule "obfuscated-cpp"
+      in Jamfiles, which will convert source to the OBFUSCATED_CPP type.
+    </para>
+
+    <para>
+      The remaining method is to declare your own main target class. The
+      simplest example of this can be found in "build/alias.jam" file. The
+      current V2 uses this method when transformations are relatively
+      complex. However, we might deprecate this approach. If you find that you
+      need to use it (that is, the first two approaches are not sufficient),
+      please let us know by posting to the mailing list.
+    </para>
+    
+
+  </section>
+
+  <section id="bbv2.extending.toolset_modules">
+
+    <title>Toolset modules</title>
+
+    <para>If your extensions will be used only on one project, they can be
+      placed in a separate <filename>.jam</filename> file which will be
+      imported by your <filename>project-root.jam</filename>. If the
+      extensions will be used on many projects, the users will thank you for 
+      a finishing touch.
+    </para>
+
+    <para>The standard way to use a tool in Boost.Build is the
+      <code>using</code> rule. To make it work, you module should provide an
+      <code>init</code> rule. The rule will be called with the same parameters
+      which were passed to the <code>using</code> rule. The set of allowed
+      parameters is determined by you. For example, you can allow the user to
+      specify paths, tool version, or tool options.
+    </para>
+
+    <para>Here are some guidelines which help to make Boost.Build more
+      consistent:
+      <itemizedlist>
+        <listitem><para>The <code>init</code> rule should never fail. Even if
+          user provided a wrong path, you should emit a warning and go
+          on. Configuration may be shared between different machines, and
+          wrong values on one machine can be OK on another.
+          </para></listitem>
+
+        <listitem><para>Prefer specifying command to be executed to specifying
+            path. First of all, this gives more control: it's possible to
+            specify
+<programlisting>
+/usr/bin/g++-snapshot
+time g++
+</programlisting>
+            as the command. Second, while some tools have a logical
+            "installation root", it better if user don't have to remember if
+            a specific tool requires a full command or a path.            
+          </para></listitem>
+
+        <listitem><para>Check for multiple initialization. A user can try to
+            initialize the module several times. You need to check for this
+            and decide what to do. Typically, unless you support several
+            versions of a tool, duplicate initialization is a user error. If
+            tool version can be specified during initialization, make sure the
+            version is either always specified, or never specified (in which
+            case the tool is initialied only once). For example, if you allow:
+<programlisting>
+using yfc ;
+using yfc : 3.3 ;
+using yfc : 3.4 ;
+</programlisting>
+            Then it's not clear if the first initialization corresponds to
+            version 3.3 of the tool, version 3.4 of the tool, or some other
+            version. This can lead to building twice with the same version.
+            </para></listitem>
+
+        <listitem><para>If possible, the <code>init</code> must be callable
+          with no parameters. In which case, it should try to autodetect all
+          the necessary information, for example, by looking for a tool in
+          <envar>PATH</envar> or in common installation locations. Often this
+          is possible and allows the user to simply write:
+<programlisting>
+using yfc ;
+</programlisting>
+          </para></listitem>
+
+        <listitem><para>Consider using facilities in the
+          <code>tools/common</code> module. You can take a look at how
+          <code>tools/gcc.jam</code> uses that module in the <code>init</code> rule.
+          </para></listitem>
+
+      </itemizedlist>
+    </para>
+
+
+      
+
+  </section>
+
+  </chapter>
+
+<!--
+     Local Variables:
+     mode: xml
+     sgml-indent-data: t     
+     sgml-parent-document: ("userman.xml" "chapter")
+     sgml-set-face: t
+     End:
+-->

Added: boost-jam/boost-build/branches/upstream/current/doc/src/faq.xml
===================================================================
--- boost-jam/boost-build/branches/upstream/current/doc/src/faq.xml	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/doc/src/faq.xml	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,350 @@
+<?xml version="1.0" standalone="yes"?>
+<!DOCTYPE library PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN"
+     "http://www.boost.org/tools/boostbook/dtd/boostbook.dtd">
+
+  <chapter id="bbv2.faq">
+    <title>Frequently Asked Questions</title>
+
+    <section>
+      <title>
+        I'm getting "Duplicate name of actual target" error. What
+        does it mean?
+      </title>
+
+    <para>    
+    The most likely case is that you're trying to
+    compile the same file twice, with almost the same,
+    but differing properties. For example:
+
+<programlisting>
+exe a : a.cpp : &lt;include&gt;/usr/local/include ;
+exe b : a.cpp ;
+</programlisting>    
+
+    </para>
+
+    <para>
+    The above snippet requires two different compilations
+    of 'a.cpp', which differ only in 'include' property.
+    Since the 'include' property is free, Boost.Build
+    can't generate two objects files into different directories.
+    On the other hand, it's dangerous to compile the file only
+    once -- maybe you really want to compile with different
+    includes.
+    </para>
+
+    <para>
+    To solve this issue, you need to decide if file should
+    be compiled once or twice.</para>
+
+    <orderedlist>
+    <listitem>
+    <para>Two compile file only once, make sure that properties
+      are the same:
+
+<programlisting>
+exe a : a.cpp : &lt;include&gt;/usr/local/include ;
+exe b : a.cpp : &lt;include&gt;/usr/local/include ;
+</programlisting></para></listitem>
+
+    <listitem><para>
+      If changing the properties is not desirable, for example
+      if 'a' and 'b' target have other sources which need
+      specific properties, separate 'a.cpp' into it's own target:
+
+<programlisting>
+obj a_obj : a.cpp : &lt;include&gt;/usr/local/include ;
+exe a : a_obj ;
+</programlisting></para></listitem>
+   
+      <listitem><para>
+      To compile file twice, you can make the object file local
+      to the main target:
+
+<programlisting>
+      exe a : [ obj a_obj : a.cpp ] : &lt;include&gt;/usr/local/include ;
+      exe b : [ obj a_obj : a.cpp ] ;
+</programlisting></para></listitem>
+
+   </orderedlist>
+
+   <para>
+   A good question is why Boost.Build can't use some of the above
+   approaches automatically. The problem is that such magic would
+   require additional implementation complexities and would only
+   help in half of the cases, while in other half we'd be silently
+   doing the wrong thing. It's simpler and safe to ask user to
+   clarify his intention in such cases.
+   </para>
+
+    </section>
+
+    <section>
+      <title>
+      Accessing environment variables
+      </title>
+
+    <para>    
+      Many users would like to use environment variables in Jamfiles, for
+      example, to control location of external libraries. In many cases you
+      better declare those external libraries in the site-config.jam file, as
+      documented in the <link linkend="bbv2.recipies.site-config">recipes
+      section</link>. However, if the users already have the environment variables set
+      up, it's not convenient to ask them to set up site-config.jam files as
+      well, and using environment variables might be reasonable.
+    </para>
+
+    <para>In Boost.Build V2, each Jamfile is a separate namespace, and the
+    variables defined in environment is imported into the global
+    namespace. Therefore, to access environment variable from Jamfile, you'd
+    need the following code:
+<programlisting>
+import modules ;
+local SOME_LIBRARY_PATH = [ modules.peek : SOME_LIBRARY_PATH ] ;
+exe a : a.cpp : &lt;include&gt;$(SOME_LIBRARY_PATH) ;
+</programlisting>
+    </para>
+</section>
+
+    <section>
+      <title>
+        How to control properties order?
+      </title>
+
+    <para>For internal reasons, Boost.Build sorts all the properties
+    alphabetically. This means that if you write:
+<programlisting>
+exe a : a.cpp : &lt;include&gt;b &lt;include&gt;a ;
+</programlisting>
+      then the command line with first mention the "a" include directory, and
+      then "b", even though they are specified in the opposite order. In most
+      cases, the user doesn't care. But sometimes the order of includes, or
+      other properties, is important. For example, if one uses both the C++
+      Boost library and the "boost-sandbox" (libraries in development), then
+      include path for boost-sandbox must come first, because some headers may
+      override ones in C++ Boost. For such cases, a special syntax is
+      provided:
+<programlisting>
+exe a : a.cpp : &lt;include&gt;a&amp;&amp;b ;        
+</programlisting>
+    </para>
+
+    <para>The <code>&amp;&amp;</code> symbols separate values of an
+      property, and specify that the order of the values should be preserved. You
+      are advised to use this feature only when the order of properties really
+      matters, and not as a convenient shortcut. Using it everywhere might
+      negatively affect performance.
+    </para>
+
+  </section>
+
+  <section>
+    <title>
+      How to control the library order on Unix?
+    </title>
+
+    <para>On the Unix-like operating systems, the order in which static
+      libraries are specified when invoking the linker is important, because by
+      default, the linker uses one pass though the libraries list. Passing the
+      libraries in the incorrect order will lead to a link error. Further, this
+      behaviour is often used to make one library override symbols from
+      another. So, sometimes it's necessary to force specific order of
+      libraries.    
+    </para>
+
+    <para>Boost.Build tries to automatically compute the right order.  The
+      primary rule is that if library a "uses" library b, then library a will
+      appear on the command line before library b. Library a is considered to
+      use b is b is present either in the sources of a or in its
+      requirements. To explicitly specify the use relationship one can use the
+      &lt;use&gt; feature. For example, both of the following lines will cause
+      a to appear before b on the command line:
+<programlisting>
+lib a : a.cpp b ;
+lib a : a.cpp : &lt;use&gt;b ;
+</programlisting>
+    </para>
+
+    <para>
+      The same approach works for searched libraries, too:
+<programlisting>
+lib z ;
+lib png : : &lt;use&gt;z ;
+exe viewer : viewer png z ;
+</programlisting>
+    </para>
+
+  </section>
+
+  <section id="bbv2.faq.external">
+    <title>Can I get output of external program as a variable in a Jamfile?
+    </title>
+
+    <para>From time to time users ask how to run an external program and save
+    the result in Jamfile variable, something like:
+<programlisting>
+local gtk_includes = [ RUN_COMMAND gtk-config ] ;
+</programlisting>
+      Unfortunately, this is not possible at the moment. However, if the
+      result of command invocation is to be used in a command to some tool,
+      and you're working on Unix, the following workaround is possible.
+<programlisting>
+ alias gtk+-2.0 : : : :
+         &lt;cflags&gt;"`pkg-config --cflags gtk+-2.0`"
+         &lt;inkflags&gt;"`pkg-config --libs gtk+-2.0`"
+     ;
+</programlisting>
+      If you use the "gtk+-2.0" target in sources, then the properties
+      specified above will be added to the build properties and eventually
+      will appear in the command line. Unix command line shell processes
+      the backticks quoting by running the tool and using its output --
+      which is what's desired in that case. Thanks to Daniel James for
+      sharing this approach.
+    </para>
+
+  </section>
+
+  <section>
+    <title>How to get the project-root location?
+    </title>
+
+    <para>You might want to use the location of the project-root in your
+      Jamfiles. To do it, you'd need to declare path constant in your
+      project-root.jam:
+<programlisting>
+path-constant TOP : . ;
+</programlisting>
+      After that, the <code>TOP</code> variable can be used in every Jamfile.
+    </para>
+  </section>
+
+  <section>
+    <title>How to change compilation flags for one file?
+    </title>
+
+    <para>If one file must be compiled with special options, you need to
+      explicitly declare an <code>obj</code> target for that file and then use
+      that target in your <code>exe</code> or <code>lib</code> target:
+<programlisting>
+exe a : a.cpp b ;
+obj b : b.cpp : &lt;optimization&gt;off ;
+</programlisting>
+      Of course you can use other properties, for example to specify specific
+      compiler options:
+<programlisting>
+exe a : a.cpp b ;
+obj b : b.cpp : &lt;cflags&gt;-g ;
+</programlisting>
+      You can also use <link linkend="bbv2.tutorial.conditions">conditional
+      properties</link> for finer control:
+<programlisting>
+exe a : a.cpp b ;
+obj b : b.cpp : &lt;variant&gt;release:&lt;optimization&gt;off ;
+</programlisting>
+
+    </para>
+  </section>
+
+  <section id="bbv2.faq.dll-path">
+    <title>Why are the <code>dll-path</code> and
+    <code>hardcode-dll-paths</code> properties useful?
+    </title>
+
+    <para>(This entry is specific to Unix system.)Before answering the
+      questions, let's recall a few points about shared libraries. Shared
+      libraries can be used by several applications, or other libraries,
+      without phisycally including the library in the application. This can
+      greatly decrease the total size of applications. It's also possible to
+      upgrade a shared library when the application is already
+      installed. Finally, shared linking can be faster.
+    </para>
+
+    <para>However, the shared library must be found when the application is
+      started. The dynamic linker will search in a system-defined list of
+      paths, load the library and resolve the symbols. Which means that you
+      should either change the system-defined list, given by the
+      <envar>LD_LIBRARY_PATH</envar> environment variable, or install the
+      libraries to a system location. This can be inconvenient when
+      developing, since the libraries are not yet ready to be installed, and
+      cluttering system paths is undesirable. Luckily, on Unix there's another
+      way.
+    </para>
+
+    <para>An executable can include a list of additional library paths, which
+      will be searched before system paths. This is excellent for development,
+      because the build system knows the paths to all libraries and can include
+      them in executables. That's done when the <code>hardcode-dll-paths</code>
+      feature has the <literal>true</literal> value, which is the
+      default. When the executables should be installed, the story is
+      different.
+    </para>
+
+    <para>
+      Obviously, installed executable should not hardcode paths to your
+      development tree. (The <code>stage</code> rule explicitly disables the
+      <code>hardcode-dll-paths</code> feature for that reason.) However, you
+      can use the <code>dll-path</code> feature to add explicit paths
+      manually. For example:
+<programlisting>
+stage installed : application : &lt;dll-path&gt;/usr/lib/snake
+                                &lt;location&gt;/usr/bin ;          
+</programlisting>
+      will allow the application to find libraries placed to
+      <filename>/usr/lib/snake</filename>.
+    </para>
+
+    <para>If you install libraries to a nonstandard location and add an
+      explicit path, you get more control over libraries which will be used. A
+      library of the same name in a system location will not be inadvertently
+      used.  If you install libraries to a system location and do not add any
+      paths, the system administrator will have more control. Each library can
+      be individually upgraded, and all applications will use the new library.
+    </para>
+
+    <para>Which approach is best depends on your situation. If the libraries
+      are relatively standalone and can be used by third party applications,
+      they should be installed in the system location. If you have lots of
+      libraries which can be used only by our application, it makes sense to
+      install it to a nonstandard directory and add an explicit path, like the
+      example above shows. Please also note that guidelines for different
+      systems differ in this respect. The Debian guidelines prohibit any
+      additional search paths, and Solaris guidelines suggest that they should
+      always be used.
+    </para>
+      
+  </section>
+
+  <section id="bbv2.recipies.site-config">
+    <title>Targets in site-config.jam</title>
+
+    <para>It is desirable to declare standard libraries available on a
+      given system. Putting target declaration in Jamfile is not really
+      good, since locations of the libraries can vary. The solution is
+      to put the following to site-config.jam.</para>    
+<programlisting>
+import project ;
+project.initialize $(__name__) ;
+project site-config ;
+lib zlib : : &lt;name&gt;z ;
+</programlisting>
+
+    <para>The second line allows this module to act as project. The
+      third line gives id to this project &#x2014; it really has no location
+      and cannot be used otherwise. The fourth line just declares a
+      target. Now, one can write:
+<programlisting>
+exe hello : hello.cpp /site-config//zlib ;
+</programlisting>
+      in any Jamfile.</para>
+
+  </section>
+    
+  </chapter>
+<!--
+     Local Variables:
+     mode: xml
+     sgml-indent-data: t     
+     sgml-parent-document: ("userman.xml" "chapter")
+     sgml-set-face: t
+     End:
+-->
\ No newline at end of file

Added: boost-jam/boost-build/branches/upstream/current/doc/src/howto.xml
===================================================================
--- boost-jam/boost-build/branches/upstream/current/doc/src/howto.xml	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/doc/src/howto.xml	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE chapter PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN"
+  "http://www.boost.org/tools/boostbook/dtd/boostbook.dtd">
+
+  <chapter id="bbv2.howto">
+    <title>How to use this document</title>
+
+    <para>
+      If you've just found out about Boost.Build V2 and want to know
+      if it will work for you, start with <xref linkend=
+      "bbv2.tutorial" />. You can continue with the <xref
+      linkend="bbv2.advanced" />. When you're ready to try Boost.Build
+      in practice, go to <xref linkend="bbv2.installation"/>.
+    </para>
+
+    <para>
+      If you are about to use Boost.Build on your project, or already
+      using it and have a problem, look at <xref linkend=
+      "bbv2.advanced"/>.
+    </para>
+
+    <para>
+      If you're trying to build a project which uses Boost.Build,
+      look at <xref linkend="bbv2.installation"/> and then read about
+      <xref linkend="bbv2.reference.commandline"/>.
+    </para>
+
+    <para>
+      If you have questions, please post them to our <ulink
+      url="../../../../more/mailing_lists.htm#jamboost">mailing
+      list</ulink>, and be sure to indicate in the subject line that
+      you're asking about Boost.Build <emphasis
+      role="bold">V2</emphasis>.
+    </para>
+
+  </chapter>

Added: boost-jam/boost-build/branches/upstream/current/doc/src/install.xml
===================================================================
--- boost-jam/boost-build/branches/upstream/current/doc/src/install.xml	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/doc/src/install.xml	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,142 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE chapter PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN"
+  "http://www.boost.org/tools/boostbook/dtd/boostbook.dtd">
+
+  <chapter id="bbv2.installation">
+    <title>Installation</title>
+
+    <para>
+      This section describes how to install Boost.Build from a
+      released source distribution. All paths are given relative to
+      the <firstterm>Boost.Build v2 root directory</firstterm>, which is 
+
+      <!-- the normal location of the document you are reading.
+      Boost.Build is -->
+
+      <!-- That is a lie AFAICT, at least in a Boost distro.  You need
+      to say something that will be true if you want to cover BBv2 as
+      distributed separately -->
+
+      located in the <filename>tools/build/v2</filename> subdirectory
+      of a full <ulink url="http://www.boost.org">Boost</ulink>
+      distribution.
+    </para>
+
+    <orderedlist>
+      <listitem>
+        <simpara>
+          Boost.Build uses <ulink
+          url= "../jam_src/index.html">Boost.Jam</ulink>, an
+          extension of the <ulink
+          url="http://www.perforce.com/jam/jam.html">Perforce
+          Jam</ulink> portable <command>make</command> replacement. The
+          recommended way to get Boost.Jam is to <emphasis
+          role="bold"><ulink
+          url= "http://sourceforge.net/project/showfiles.php?group_id=7586&amp;package_id=72941">download
+          a prebuilt executable</ulink></emphasis> from SourceForge.
+          If a prebuilt executable is not provided for your platform
+          or you are using Boost's sources in an unreleased state, it
+          may be neccessary to <ulink
+          url= "../../jam_src/index.html#building_bjam">build <command>bjam</command>
+          from sources</ulink> included in the Boost source tree.
+        </simpara>
+      </listitem>
+
+      <listitem>
+        <para>
+
+          To install Boost.Jam, copy the executable,
+          called <command>bjam</command>
+          or <command>bjam.exe</command> to a location accessible in
+          your <envar>PATH</envar>.  Go to the Boost.Build root
+          directory and
+          run <command>bjam <option>--version</option></command>. You
+          should see:
+
+          <screen>
+            Boost.Build V2 (Milestone N)
+            Boost.Jam xx.xx.xx 
+          </screen>
+
+          where N is the version of Boost.Build you're using.
+        </para>
+      </listitem>
+
+      <listitem>
+        <simpara>
+          Configure Boost.Build to recognize the build resources (such
+          as compilers and libraries) you have installed on your
+          system.  Open the
+          <filename>user-config.jam</filename> file in the Boost.Build
+          root directory and follow the instructions there to describe
+          your toolsets and libraries, and, if neccessary, where they
+          are located.
+        </simpara>
+      </listitem>
+
+      <listitem>
+        <simpara>
+          You should now be able to go to the
+          <filename>example/hello/</filename> directory and run
+          <command>bjam</command> there. A simple application will be
+          built. You can also play with other projects in the
+          <filename>example/</filename> directory. 
+    <!-- This part should not go into intoduction docs, but we need to
+         place it somewhere. 
+
+    <para>It is slighly better way is to copy
+    <filename>new/user-config.jam</filename> into one of the locations
+    where it can be found (given in <link linkend=
+    "bbv2.reference.init.config">this table</link>). This prevent you
+    from accidentally overwriting your config when updating.</para>
+
+    -->
+        </simpara>
+      </listitem>
+    </orderedlist>
+
+    <para>
+      If you are using Boost's CVS state, be sure to
+      rebuild <command>bjam</command> even if you have a previous
+      version.  The CVS version of Boost.Build requires the CVS
+      version of Boost.Jam.
+    </para>
+
+    <para>
+      When <command>bjam</command> is invoked, it always needs to be
+      able to find the Boost.Build root directory, where the
+      interpreted source code of Boost.Build is located.  There are
+      two ways to tell <command>bjam</command> about the root directory:
+    </para>
+
+    <itemizedlist>
+      <listitem>
+        <simpara>
+          Set the environment variable <envar>BOOST_BUILD_PATH</envar>
+          to the absolute path of the Boost.Build root directory.
+        </simpara>
+      </listitem>
+
+      <listitem>
+        <para>
+          At the root directory of your project or in any of its
+          parent directories, create a file called
+          <filename>boost-build.jam</filename>, with a single line:
+
+<programlisting>
+boost-build <replaceable>/path/to/boost.build</replaceable> ;
+</programlisting>
+
+        </para>
+      </listitem>
+    </itemizedlist>
+
+  <para><emphasis role="bold">N.B.</emphasis>
+  When <command>bjam</command> is invoked from anywhere in the Boost
+  directory tree <emphasis>other than</emphasis> the Boost.Build root
+  and its subdirectories, <ulink url="../../tools/build">Boost.Build
+  v1</ulink> is used by default. To override the default and use
+  Boost.Build v2, you have to add the <option>--v2</option> command
+  line option to all <command>bjam</command> invocations.</para>
+
+  </chapter>

Added: boost-jam/boost-build/branches/upstream/current/doc/src/recipes.xml
===================================================================
--- boost-jam/boost-build/branches/upstream/current/doc/src/recipes.xml	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/doc/src/recipes.xml	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE appendix PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN"
+  "http://www.boost.org/tools/boostbook/dtd/boostbook.dtd">
+
+  <!-- The file is empty. It's not clear if it will be needed in
+       future or FAQ completely supercedes it. -->
+
+  <appendix id="bbv2.recipies">
+    <title>Boost Build System V2 recipes</title>
+
+  </appendix>

Added: boost-jam/boost-build/branches/upstream/current/doc/src/reference.xml
===================================================================
--- boost-jam/boost-build/branches/upstream/current/doc/src/reference.xml	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/doc/src/reference.xml	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,1260 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE chapter PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN"
+  "http://www.boost.org/tools/boostbook/dtd/boostbook.dtd">
+
+<chapter id="bbv2.reference">
+  <title>Detailed reference</title>
+
+  <section id="bbv2.reference.general">
+    <title>General information</title>
+
+    <section id="bbv2.reference.init">
+      <title>Initialization</title>
+
+      <para>bjam's first job upon startup is to load the Jam code which
+        implements the build system. To do this, it searches for a file
+        called "boost-build.jam", first in the invocation directory, then
+        in its parent and so forth up to the filesystem root, and finally
+        in the directories specified by the environment variable
+        BOOST_BUILD_PATH. When found, the file is interpreted, and should
+        specify the build system location by calling the boost-build
+        rule:</para>
+
+<programlisting>
+rule boost-build ( location ? )
+</programlisting>
+
+      <para>
+        If location is a relative path, it is treated as relative to
+        the directory of boost-build.jam. The directory specified by
+        location and directories in BOOST_BUILD_PATH are then searched for
+        a file called bootstrap.jam which is interpreted and is expected to
+        bootstrap the build system. This arrangement allows the build
+        system to work without any command-line or environment variable
+        settings. For example, if the build system files were located in a
+        directory "build-system/" at your project root, you might place a
+        boost-build.jam at the project root containing:
+
+<programlisting>
+boost-build build-system ;
+</programlisting>
+
+        In this case, running bjam anywhere in the project tree will
+        automatically find the build system.</para>
+
+      <para>The default "bootstrap.jam", after loading some standard
+        definitions, loads two files, which can be provided/customised by
+        user: "site-config.jam" and "user-config.jam".</para>
+
+      <para>Locations where those files a search are summarized below:</para>
+
+      <table id="bbv2.reference.init.config">
+        <title>Search paths for configuration files</title>
+
+        <tgroup cols="3">
+          <thead>
+
+            <row>
+              <entry></entry>
+
+              <entry>site-config.jam</entry>
+
+              <entry>user-config.jam</entry>
+            </row>
+
+          </thead>
+          <tbody>
+
+            <row>
+              <entry>Linux</entry>
+
+              <entry>
+                <simpara>/etc</simpara>
+                <simpara>$HOME</simpara>
+                <simpara>$BOOST_BUILD_PATH</simpara>
+              </entry>
+
+              <entry>
+                <simpara>$HOME</simpara>
+                <simpara>$BOOST_BUILD_PATH</simpara>
+              </entry>
+            </row>
+
+            <row>
+              <entry>Windows</entry>
+
+              <entry>
+                <simpara>$SystemRoot</simpara>
+                <simpara>$HOME</simpara>
+                <simpara>$BOOST_BUILD_PATH</simpara>
+              </entry>
+
+              <entry>
+                <simpara>$HOME</simpara>
+                <simpara>$BOOST_BUILD_PATH</simpara>
+              </entry>
+            </row>
+          </tbody>
+        </tgroup>
+      </table>
+
+      <para>
+        Boost.Build comes with default versions of those files,
+        which can serve as templates for customized versions.
+      </para>
+
+    </section>
+    <section id="bbv2.reference.commandline">
+      <title>Command line</title>
+
+      <para>The command line may contain:</para>
+
+      <itemizedlist>
+        <listitem><simpara>Jam options,</simpara></listitem>
+
+        <listitem><simpara>Boost.Build <link linkend=
+              "bbv2.reference.init.options">options</link>,</simpara></listitem>
+
+        <listitem><simpara>Command line arguments</simpara></listitem>
+      </itemizedlist>
+
+      <section id="bbv2.reference.init.args">
+        <title>Command line arguments</title>
+
+        <para>
+          Command line arguments specify targets and build
+          request using the following rules.
+        </para>
+
+        <itemizedlist>
+          <listitem>
+            <simpara>
+              An argument which does not contain slashes or the "="
+              symbol is either a value of an implicit feature, or target to
+              be built. It is taken to be value of a feature if appropriate
+              feature exists. Otherwise, it is considered a <link linkend=
+                "bbv2.reference.ids">target id</link>. Special target name "clean"
+              has the same effect as "--clean" option.
+            </simpara>
+          </listitem>
+
+          <listitem>
+            <para>
+              An argument with either slashes or the "=" symbol specifies
+              a number of <link linkend="bbv2.reference.buildreq">build
+                request</link>
+              elements. In the simplest form, it's just a set of properties,
+              separated by slashes, which become a single build request
+              element, for example:
+
+<programlisting>
+borland/&lt;runtime-link&gt;static
+</programlisting>
+
+              More complex form is used to save typing. For example,
+              instead of
+
+<programlisting>
+borland/runtime-link=static borland/runtime-link=dynamic
+</programlisting>
+
+              one can use
+
+<programlisting>
+borland/runtime-link=static,dynamic
+</programlisting>
+
+              Exactly, the conversion from argument to build request
+              elements is performed by (1) splitting the argument at each slash,
+              (2) converting each split part into a set of properties and (3)
+              taking all possible combination of the property sets. Each split
+              part should have the either the form
+
+<programlisting>
+<emphasis>feature-name</emphasis>=<emphasis>feature-value1</emphasis>[","<emphasis>feature-valueN</emphasis>]*   
+</programlisting>
+
+              or, in case of implicit feature
+
+<programlisting>
+<emphasis>feature-value1</emphasis>[","<emphasis>feature-valueN</emphasis>;]*   
+</programlisting>
+
+              and will be converted into property set
+
+<programlisting>
+&lt;feature-name&gt;feature-value1 .... &lt;feature-name&gt;feature-valueN
+</programlisting>
+
+            </para>
+          </listitem>
+        </itemizedlist>
+
+        <para>
+          For example, the command line
+
+<programlisting>
+target1 debug gcc/runtime-link=dynamic,static
+</programlisting>
+
+          would cause target called <literal>target1</literal> to be rebuilt in
+          debug mode, except that for gcc, both dynamically and statically
+          linked binaries would be created.
+        </para>
+
+      </section>
+      <section id="bbv2.reference.init.options">
+        <title>Command line options</title>
+
+        <para>All of the Boost.Build options start with the "--" prefix.
+          They are described in the following table.</para>
+
+        <table>
+          <title>Command line options</title>
+          <tgroup cols="2">
+
+            <thead>
+              <row>
+                <entry>Option</entry>
+
+                <entry>Description</entry>
+              </row>
+            </thead>
+
+            <tbody>
+              <row>
+                <entry><literal>--version</literal></entry>
+
+                <entry>Prints information on Boost.Build and Boost.Jam
+                  versions.</entry>
+              </row>
+
+              <row id="bbv2.reference.init.options.help">
+                <entry><literal>--help</literal></entry>
+
+                <entry>Access to the online help system. This prints general
+                  information on how to use the help system with additional
+                  --help* options.</entry>
+              </row>
+
+              <row>
+                <entry><literal>--clean</literal></entry>
+
+                <entry>Removes everything instead of building. Unlike
+                  <literal>clean</literal> target in make, it is possible to clean only
+                  some targets.</entry>
+              </row>
+
+              <row>
+                <entry><literal>--debug</literal></entry>
+
+                <entry>Enables internal checks.</entry>
+              </row>
+
+              <row>
+                <entry><literal>--dump-projects</literal></entry>
+
+                <entry>Cause the project structure to be output.</entry>
+              </row>
+
+              <row>
+                <entry><literal>--no-error-backtrace</literal></entry>
+
+                <entry>Don't print backtrace on errors. Primary useful for
+                  testing.</entry>
+              </row>
+
+              <row>
+                <entry><literal>--ignore-config</literal></entry>
+
+                <entry>Do not load <literal>site-config.jam</literal> and
+                  <literal>user-config.jam</literal></entry>
+              </row>
+            </tbody>
+          </tgroup>
+        </table>
+
+      </section>
+    </section>
+
+
+  </section>
+
+  <section id="bbv2.reference.jamfiles">
+    <title>Writing Jamfiles</title>
+
+    <para>This section describes specific information about writing Jamfiles.</para>
+
+    <section id="bbv2.reference.headers">
+      <title>Generated headers</title>
+
+      <para>Usually, Boost.Build handles implicit dependendies completely
+        automatically. For example, for C++ files, all <literal>#include</literal>
+        statements are found and handled. The only aspect where user help
+        might be needed is implicit dependency on generated files.</para>
+      
+      <para>By default, Boost.Build handles such dependencies within one
+        main target. For example, assume that main target "app" has two
+        sources, "app.cpp" and "parser.y". The latter source is converted
+        into "parser.c" and "parser.h". Then, if "app.cpp" includes
+        "parser.h", Boost.Build will detect this dependency. Moreover,
+        since "parser.h" will be generated into a build directory, the
+        path to that directory will automatically added to include
+        path.</para>
+      
+      <para>Making this mechanism work across main target boundaries is
+        possible, but imposes certain overhead. For that reason, if
+        there's implicit dependency on files from other main targets, the
+        <literal>&lt;implicit-dependency&gt;</literal> [ link ] feature must
+        be used, for example:</para>
+      
+<programlisting>
+lib parser : parser.y ;
+exe app : app.cpp : &lt;implicit-dependency&gt;parser ;
+</programlisting>
+
+      <para>
+        The above example tells the build system that when scanning
+        all sources of "app" for implicit-dependencies, it should consider
+        targets from "parser" as potential dependencies.
+      </para>
+    </section>
+
+
+  </section>
+
+  <section id="bbv2.reference.buildprocess">
+    <title>Build process</title>
+
+    <para>The general overview of the build process was given in the 
+      <link linkend="bbv2.advanced.build_process">user documentation</link>.
+      This section provides additional details, and some specific rules.
+    </para>
+
+    <para>To recap, building a target with specific properties includes the
+      following steps:
+      <orderedlist>
+
+        <listitem><para>applying default build,</para></listitem>
+
+        <listitem><para>selecting the main target alternative to use,
+          </para></listitem>
+
+        <listitem><para>determining "common" properties</para></listitem>
+
+        <listitem><para>building targets referred by the sources list and
+            dependency properties</para></listitem>
+
+        <listitem><para>adding the usage requirements produces when building
+            dependencies to the "common" properties</para></listitem>
+
+        <listitem><para>building the target using generators</para></listitem>
+
+        <listitem><para>computing the usage requirements to be returned</para></listitem>
+
+      </orderedlist>
+    </para>
+
+    <section id="bbv2.reference.buildprocess.alternatives">
+      <title>Alternative selection</title>
+
+      <para>When there are several alternatives, one of them must be
+        selected. The process is as follows:</para>
+      
+      <orderedlist>
+        <listitem>
+          <simpara>
+            For each alternative <emphasis>condition</emphasis> is defined
+            as the set of base properies in requirements. [Note: it might be
+            better to specify the condition explicitly, as in
+            conditional requirements].
+          </simpara>
+        </listitem>
+        
+        <listitem>
+          <simpara>
+            An alternative is viable only if all properties in condition
+            are present in build request.
+          </simpara>
+        </listitem>
+        
+        <listitem>
+          <simpara>
+            If there's one viable alternative, it's choosen. Otherwise,
+            an attempt is made to find one best alternative. An alternative
+            a is better than another alternative b, iff set of properties
+            in b's condition is strict subset of the set of properities of
+            'a's condition. If there's one viable alternative, which is
+            better than all other, it's selected. Otherwise, an error is
+            reported.
+          </simpara>
+        </listitem>
+      </orderedlist>
+      
+    </section>    
+
+    <section id="bbv2.reference.buildprocess.common">
+      <title>Determining common properties</title>
+
+      <para>The "common" properties is a somewhat artificial term. Those are
+        the intermediate property set from which both the build request for
+        dependencies and properties for building the target are derived.
+      </para>
+
+      <para>Since default build and alternatives are already handled, we have
+        only two inputs: build requests and requirements. Here are the rules
+        about common properties.
+      </para>
+
+      <orderedlist>
+        <listitem><para>Non-free feature can have only one
+            value</para></listitem>
+
+        <listitem><para>A non-conditional property in requirement in always
+            present in common properties.</para></listitem>
+        
+        <listitem><para>A property in build request is present in
+            common properties, unless (2) tells otherwise.</para></listitem>
+
+        <listitem><para>If either build request, or requirements (non-conditional
+            or conditional) include an expandable property (either composite,
+            or property with specified subfeature value), the behaviour is
+            equivalent to explicitly adding all expanded properties to build
+            request or requirements.</para></listitem>
+
+        <listitem><para>If requirements include a conditional property, and
+            condiiton of this property is true in context of common
+            properties, then the conditional property should be in common
+            properties as well.</para></listitem>
+
+        <listitem><para>If no value for a feature is given by other rules
+            here, it has default value in common properties.</para></listitem>
+      </orderedlist>
+
+      <para>Those rules are declarative, they don't specify how to compute the
+        common properties. However, they provide enough information for the
+        user. The important point is the handling of conditional
+        requirements. The condition can be satisfied either by property in
+        build request, by non-conditional requirements, or even by another
+        conditional property. For example, the following example works as
+        expected:
+<programlisting>
+exe a : a.cpp 
+      : &lt;toolset&gt;gcc:&lt;variant&gt;release 
+        &lt;variant&gt;release:&lt;define&gt;FOO ;
+</programlisting>
+      </para>        
+
+  </section>
+      
+    
+<!--
+
+    <para>Construction of each main target begins with finding
+      properties for <emphasis>this</emphasis> main target. They are found by
+      processing both build request, and <emphasis>target requirements</emphasis>,
+      which give properties needed for the target to build. For
+      example, a given main target might require certian defines, or
+      will not work unless compiled in multithreaded mode. The process
+      of finding properties for main target is described in <link linkend=
+        "bbv2.reference.variants.proprefine">property refinement</link>.
+    </para>
+    
+    <para>After that, dependencies (i.e. other main targets) are built
+      recursively. Build request for dependencies is not always equal
+      to those of dependent &#x2014; certain properties are dropped and
+      user can explicitly specify desired properties for dependencies.
+      See <link linkend="bbv2.reference.features.attributes.propagated">
+        propagated features</link> and <xref linkend=
+        "bbv2.advanced.targets.references"/> for details.</para>
+    
+    <para>When dependencies are constructed, the dependency graph for
+      this main target and for this property set is created, which
+      describes which files need to be created, on which other files
+      they depend and what actions are needed to construct those files.
+      There's more that one method, and user can define new ones, but
+      usually, this involves <emphasis>generators</emphasis> and <emphasis>target
+        types</emphasis>.</para>
+    
+    <para>Target type is just a way to classify targets. For example,
+      there are builtin types <literal>EXE</literal>, <literal>OBJ</literal> and
+      <literal>CPP</literal>. <link linkend=
+        "bbv2.reference.generators">Generators</link> are objects
+      that know how to convert between different target type. When a
+      target of a given type must be created, all generators for that
+      type, which can handle needed properties, are found. Each is
+      passed the list of sources, and either fails, or returns a
+      dependency graph. If a generator cannot produce desired type from
+      given sources, it may try to recursively construct types that it
+  can handle from the types is was passed. This allows to try all
+      possible transformations. When all generators are tried, a
+      dependency graph is selected.</para>
+    
+    <para>Finally, the dependency graph is passed to underlying
+      Boost.Jam program, which runs all actions needed to bring all
+      main targets up-to date. At this step, implicit dependencies are
+      also scanned and accounted for, as described "here." [ link? ]</para>
+    
+    <para>Given a list of targets ids and a build request, building goes
+      this way. First, for each id we obtain the abstract targets
+      corresponding to it. This also loads all necessary projects. If
+      no target id is given, project in the current directory is used.
+      Build request is expanded, and for each resulting property set,
+      the <literal>generate</literal> method of all targets is called, which
+      yields a list of virtual targets. After that all virtual targets
+      are actualized, and target "all" is set to depend on all created
+      actual targets. Lastly, depending on whether <literal>- XXXXXX -clean</literal>
+      option was given, either target "all" or target "clean" is
+      updated. Generation of virtual target from abstract one is
+      performed as follows:</para>
+    
+    <itemizedlist>
+      <listitem>
+        <para>For project targets, all of main targets are generated
+          with the same properties. Then all projects referred via
+          "build-project" are generated as well. If it's not possible
+          to refine requested properties with project requirements, the
+          project is skipped.</para>
+        
+        <para id="bbv2.reference.buildprocess.explict">
+          It is possible to disable building of certain target using the
+          <literal>explicit</literal> rule, available in all project
+          modules. The syntax is
+          
+<programlisting>
+rule explicit ( target-name )
+</programlisting>
+
+          If this rule is invoked on a target, it will be built only
+          when it's explicitly requested on the command line.
+        </para>
+      </listitem>
+      
+      <listitem>
+        <para>
+          For main target, with several alternatives, one of them is
+    selected as described <link linkend=
+            "bbv2.reference.buildprocess.alternatives">below</link>.
+          If there's only one
+          alternative, it's used unconditionally.
+
+          <orderedlist>
+            <listitem>
+              <simpara>
+                All main target alternatives which requirements are
+                satisfied by the build request are enumerated.
+          </simpara>
+            </listitem>
+            
+            <listitem>
+              <simpara>
+                If there are several such alternatives, the one which
+                longer requirements list is selected.
+              </simpara>
+            </listitem>
+          </orderedlist>
+      </para>
+      </listitem>
+      
+      <listitem>
+        <para>
+          For the selected alternative
+          
+          <orderedlist>
+            <listitem>
+              <simpara>
+                Each target reference in the source list are
+                recursively constructed.
+              </simpara>
+            </listitem>
+            
+            <listitem>
+              <simpara>
+                Properties are refined with alternative's requirements,
+                and active features in the resulting set are executed.
+              </simpara>
+            </listitem>
+            
+            <listitem>
+              <simpara>
+                Conditional properties are evaluated.
+              </simpara>
+            </listitem>
+            
+            <listitem>
+              <simpara>
+                The dependency graph for the target is constructed in a
+                way which depends on the kind of main target, typically
+                using generators.
+              </simpara>
+            </listitem>
+          </orderedlist>
+        </para>
+      </listitem>
+      
+      <listitem>
+        <simpara>
+          If, when building sources, the properties on recursively
+          created targets are not link-compatibile with build properties,
+          a warning is issued.
+        </simpara>
+      </listitem>
+    </itemizedlist>
+-->
+     
+  </section>
+
+
+
+  <section id="bbv2.reference.definitions">
+
+    <section id="bbv2.reference.features">
+      <title>Features and properties</title>
+
+      <para>A <emphasis>feature</emphasis> is a normalized (toolset-independent)
+        aspect of a build configuration, such as whether inlining is
+        enabled. Feature names may not contain the '<literal>&gt;</literal>'
+        character.</para>
+      
+  <!--
+    And what about dash?
+  -->
+
+      <para>Each feature in a build configuration has one or more
+        associated <emphasis>value</emphasis>s. Feature values for non-free features
+        may not contain the '<literal>&lt;</literal>', '<literal>:</literal>', or
+        '<literal>=</literal>' characters. Feature values for free features may not
+        contain the '<literal>&lt;</literal>' character.</para>
+      
+      <para>A <emphasis>property</emphasis> is a (feature,value) pair, expressed as
+        &lt;feature&gt;value.</para>
+
+      <para>A <emphasis>subfeature</emphasis> is a feature which only exists in the
+        presence of its parent feature, and whose identity can be derived
+        (in the context of its parent) from its value. A subfeature's
+        parent can never be another subfeature. Thus, features and their
+        subfeatures form a two-level hierarchy.</para>
+      
+      <para>A <emphasis>value-string</emphasis> for a feature <emphasis role="bold">F</emphasis> is a string of
+        the form
+        <literal>value-subvalue1-subvalue2</literal>...<literal>-subvalueN</literal>, where
+        <literal>value</literal> is a legal value for <emphasis role="bold">F</emphasis> and
+        <literal>subvalue1</literal>...<literal>subvalueN</literal> are legal values of some
+        of <emphasis role="bold">F</emphasis>'s subfeatures. For example, the properties
+        <literal>&lt;toolset&gt;gcc &lt;toolset-version&gt;3.0.1</literal> can be
+        expressed more conscisely using a value-string, as
+        <literal>&lt;toolset&gt;gcc-3.0.1</literal>.</para>
+      
+      <para>A <emphasis>property set</emphasis> is a set of properties (i.e. a
+        collection without duplicates), for instance:
+        <literal>&lt;toolset&gt;gcc &lt;runtime-link&gt;static</literal>.</para>
+      
+      <para>A <emphasis>property path</emphasis> is a property set whose elements have
+        been joined into a single string separated by slashes. A property
+        path representation of the previous example would be
+        <literal>&lt;toolset&gt;gcc/&lt;runtime-link&gt;static</literal>.</para>
+      
+      <para>A <emphasis>build specification</emphasis> is a property set which fully
+        describes the set of features used to build a target.</para>
+      
+      <section id="bbv2.reference.features.validity">
+        <title>Property Validity</title>
+        
+        <para>
+          For <link linkend=
+            "bbv2.reference.features.attributes.free">free</link>
+            features, all values are valid. For all other features,
+          the valid values are explicitly specified, and the build
+          system will report an error for the use of an invalid
+          feature-value. Subproperty validity may be restricted so
+          that certain values are valid only in the presence of
+          certain other subproperties. For example, it is possible
+          to specify that the <code>&lt;gcc-target&gt;mingw</code>
+          property is only valid in the presence of
+          <code>&lt;gcc-version&gt;2.95.2</code>.
+        </para>
+        
+      </section>
+      <section id="bbv2.reference.features.attributes">
+        <title>Feature Attributes</title>
+        
+        <para>Each feature has a collection of zero or more of the following
+          attributes. Feature attributes are low-level descriptions of how the
+          build system should interpret a feature's values when they appear in
+          a build request. We also refer to the attributes of properties, so
+          that an <emphasis>incidental</emphasis> property, for example, is
+          one whose feature has the <emphasis>incidental</emphasis>
+          attribute.</para>
+        
+        <itemizedlist>
+          <listitem>
+            <para><emphasis>incidental</emphasis></para>
+            
+            <para>Incidental features are assumed not to affect build
+              products at all. As a consequence, the build system may use
+              the same file for targets whose build specification differs
+              only in incidental features. A feature which controls a
+              compiler's warning level is one example of a likely
+              incidental feature.</para>
+            
+            <para>Non-incidental features are assumed to affect build
+              products, so the files for targets whose build specification
+              differs in non-incidental features are placed in different
+              directories as described in "target paths" below. [ where? ]
+            </para>
+          </listitem>
+          
+          <listitem>
+            <para>
+              <anchor id="bbv2.reference.features.attributes.propagated"/>
+              <emphasis>propagated</emphasis>
+            </para>
+            
+            <para>Features of this kind are
+              propagated to dependencies. That is, if a <link linkend=
+                "bbv2.advanced.targets.main">main target</link> is built using a
+              propagated
+              property, the build systems attempts to use the same property
+              when building any of its dependencies as part of that main
+              target. For instance, when an optimized exectuable is
+              requested, one usually wants it to be linked with optimized
+              libraries. Thus, the <literal>&lt;optimization&gt;</literal> feature is
+              propagated.</para>
+          </listitem>
+          
+          <listitem>
+            <para>
+              <anchor id="bbv2.reference.features.attributes.free"/>
+              <emphasis>free</emphasis>
+            </para>
+            
+            <para>Most features have a finite set of allowed values, and can
+              only take on a single value from that set in a given build
+              specification. Free features, on the other hand, can have
+              several values at a time and each value can be an arbitrary
+              string. For example, it is possible to have several
+              preprocessor symbols defined simultaneously:</para>
+            
+<programlisting>
+&lt;define&gt;NDEBUG=1 &lt;define&gt;HAS_CONFIG_H=1
+</programlisting>
+
+          </listitem>
+          
+          <listitem>
+            <para><emphasis>optional</emphasis></para>
+            
+            <para>An optional feature is a feature which is not required to
+              appear in a build specification. Every non-optional non-free
+              feature has a default value which is used when a value for
+              the feature is not otherwise specified, either in a target's
+              requirements or in the user's build request. [A feature's
+              default value is given by the first value listed in the
+              feature's declaration. -- move this elsewhere - dwa]</para>
+          </listitem>
+
+          <listitem>
+            <para><emphasis>symmetric</emphasis></para>
+
+            <para>A symmetric feature's default value is not automatically
+              included in <link linkend=
+                "bbv2.reference.variants">build variants</link>.  Normally
+              a feature only generates a subvariant directory when its
+              value differs from the value specified by the build variant,
+              leading to an assymmetric subvariant directory structure for
+              certain values of the feature. A symmetric feature, when
+              relevant to the toolset, always generates a corresponding
+              subvariant directory.</para>
+          </listitem>
+
+          <listitem>
+            <para><emphasis>path</emphasis></para>
+
+            <para>The value of a path feature specifies a path. The path is
+              treated as relative to the directory of Jamfile where path
+              feature is used and is translated appropriately by the build
+              system when the build is invoked from a different
+              directory</para>
+          </listitem>
+
+          <listitem>
+            <para><emphasis>implicit</emphasis></para>
+
+            <para>Values of implicit features alone identify the feature.
+              For example, a user is not required to write
+              "&lt;toolset&gt;gcc", but can simply write "gcc". Implicit
+              feature names also don't appear in variant paths, although
+              the values do. Thus: bin/gcc/... as opposed to
+              bin/toolset-gcc/.... There should typically be only a few
+              such features, to avoid possible name clashes.</para>
+          </listitem>
+
+          <listitem>
+            <para><emphasis>composite</emphasis></para>
+
+            <para>Composite features actually correspond to groups of
+              properties. For example, a build variant is a composite
+              feature. When generating targets from a set of build
+              properties, composite features are recursively expanded and
+              <emphasis>added</emphasis> to the build property set, so rules can find
+              them if neccessary. Non-composite non-free features override
+              components of composite features in a build property set.</para>
+          </listitem>
+
+          <listitem>
+            <para><emphasis>link-incompatible</emphasis></para>
+
+            <para>See <link linkend=
+                "bbv2.reference.variants.compat">below</link>.</para>
+          </listitem>
+
+          <listitem>
+            <para><emphasis>dependency</emphasis></para>
+
+            <para>The value of dependency feature if a target reference.
+              When used for building of a main target, the value of
+              dependency feature is treated as additional dependency.</para>
+
+            <para>For example, dependency features allow to state that
+              library A depends on library B. As the result, whenever an
+              application will link to A, it will also link to B.
+              Specifying B as dependency of A is different from adding B to
+              the sources of A. <!-- Need to clarify this. --></para>
+          </listitem>
+        </itemizedlist>
+
+        <para>Features which are neither free nor incidental are called
+          <emphasis>base</emphasis> features.</para>
+
+
+      </section>
+      <section id="bbv2.reference.features.declaration">
+        <title>Feature Declaration</title>
+        
+        <para>The low-level feature declaration interface is the
+          <literal>feature</literal> rule from the
+          <literal>feature</literal> module:
+          
+<programlisting>
+rule feature ( name : allowed-values * : attributes * )
+</programlisting>
+          
+          A feature's allowed-values may be extended with the
+          <code>feature.extend</code> rule.
+        </para>
+        
+      </section>
+    </section>
+
+    <section id="bbv2.reference.variants">
+      <title>Build Variants</title>
+      
+      <para>
+        A build variant, or (simply variant) is a special kind of composite
+        feature which automatically incorporates the default values of
+        features that . Typically you'll want at least two separate
+        variants: one for debugging, and one for your release code. [
+        Volodya says: "Yea, we'd need to mention that it's a composite
+        feature and describe how they are declared, in pacticular that
+        default values of non-optional features are incorporated into
+        build variant automagically. Also, do we wan't some variant
+        inheritance/extension/templates. I don't remember how it works in
+        V1, so can't document this for V2.". Will clean up soon -DWA ]
+      </para>
+
+<!-- I no longer think link compatibility is a great idea, so comment out
+     this part of docs.
+
+      <section id="bbv2.reference.variants.compat">
+        <title>Link compatible and incompatible properties</title>
+        
+        <para>When the build system tries to generate a target (such as
+          library dependency) matching a given build request, it may find
+          that an exact match isn't possible &#x2014; for example, the
+          target may impose additonal build requirements. We need to
+          determine whether a buildable version of that target can actually
+          be used.</para>
+        
+        <para>The build request can originate in many ways: it may come
+          directly from the user's command-line, from a dependency of a
+          main target upon a library, or from a dependency of a target upon
+          an executable used to build that target, for example. For each
+          way, there are different rules whether we can use a given
+          subvariant or not. The current rules are described below.</para>
+        
+        <para>Two property sets are called <emphasis>link-compatible</emphasis> when
+          targets with those property sets can be used interchangably. In
+          turn, two property sets are link compatible when there's no
+          link-incompatible feature which has different values in those
+          property sets.</para>
+        
+        <para>When building of a main target is requested from a command
+          line or some project, link-compatibility is not considered. When
+          building is requested by other main target, via sources or
+          dependency properties, the requested and actual property sets
+          must be link-compatible, otherwise a warning is produced.</para>
+
+  <para><emphasis role="bold">Rationale:</emphasis>Link-compatibility is not considered when
+  main target is requested by a project, because it causes problems
+  in practice. For example, some parts of a project might be
+  single-threaded, while others &#x2014; multi-threaded. They are
+  not link-compatible, but they are not linked, either. So, there's
+  no need to issue error or warning. The errors used to be
+  generated, and only caused problems.</para> -->
+
+      </section>
+
+    <section id="bbv2.reference.variants.proprefine">
+      <title>Property refinement</title>
+
+      <para>When a target with certain properties is requested, and that
+        target requires some set of properties, it is needed to find the
+        set of properties to use for building. This process is called
+        <emphasis>property refinement</emphasis> and is performed by these rules</para>
+      
+      <orderedlist>
+        <listitem>
+          <simpara>
+            If original properties and required properties are not
+            link-compatible, refinement fails.
+          </simpara>
+        </listitem>
+
+        <listitem>
+          <simpara>
+            Each property in the required set is added to the original
+            property set
+          </simpara>
+        </listitem>
+
+        <listitem>
+          <simpara>
+            If the original property set includes property with a different
+            value of non free feature, that property is removed.
+          </simpara>
+        </listitem>
+      </orderedlist>
+    </section>
+
+    <section id="bbv2.reference.variants.propcond">
+      <title>Conditional properties</title>
+
+      <para>Sometime it's desirable to apply certain requirements only for
+        a specific combination of other properties. For example, one of
+        compilers that you use issues a pointless warning that you want to
+        suppress by passing a command line option to it. You would not
+        want to pass that option to other compilers. Conditional
+        properties allow you to do just that. Their syntax is:</para>
+
+      <programlisting>
+        property ( "," property ) * ":" property
+      </programlisting>
+
+      <para>
+        For example, the problem above would be solved by:
+
+<programlisting>
+exe hello : hello.cpp : &lt;toolset&gt;yfc:&lt;cxxflags&gt;-disable-pointless-warning ;
+</programlisting>
+      </para>
+
+    </section>
+
+    <section id="bbv2.reference.ids">
+      <title>Target identifiers and references</title>
+      
+      <para><emphasis>Target identifier</emphasis> is used to denote a
+        target. The syntax is:</para>
+
+<programlisting>
+target-id -&gt; (project-id | target-name | file-name )
+              | (project-id | directory-name) "//" target-name   
+project-id -&gt; path
+target-name -&gt; path
+file-name -&gt; path
+directory-name -&gt; path                  
+</programlisting>
+
+      <para>
+        This grammar allows some elements to be recognized as either
+        
+        <itemizedlist>
+          <listitem>
+            <simpara>
+              project id (at this point, all project ids start with slash).
+            </simpara>
+          </listitem>
+
+          <listitem>
+            <simpara>
+              name of target declared in current Jamfile (note that target
+              names may include slash).
+            </simpara>
+          </listitem>
+
+          <listitem>
+            <simpara>
+              a regular file, denoted by absolute name or name relative to
+              project's sources location.
+            </simpara>
+          </listitem>
+        </itemizedlist>
+
+        To determine the real meaning a check is made if project-id
+        by the specified name exists, and then if main target of that
+        name exists. For example, valid target ids might be:
+
+<screen>
+a                                    -- target in current project
+lib/b.cpp                            -- regular file
+/boost/thread                        -- project "/boost/thread"
+/home/ghost/build/lr_library//parser -- target in specific project
+</screen>
+
+      </para>
+
+      <para><emphasis role="bold">Rationale:</emphasis>Target is separated from project by special
+        separator (not just slash), because:</para>
+
+      <itemizedlist>
+        <listitem>
+          <simpara>
+            It emphasises that projects and targets are different things.
+          </simpara>
+        </listitem>
+
+        <listitem>
+          <simpara>
+            It allows to have main target names with slashes. 
+
+            <!-- The motivation for which is:
+
+            So, to summarize:
+
+            1. The project which extract tarfile may extract all possible kinds
+            of targets, and it's reasonable to use them directly from other
+            project.
+
+            2. The rule for unpacking tar is inplemented in terms of
+            "patch-file", for maintainability, and therefore, must use main
+            target name which contains slashes?
+
+            3. Using sub-Jamfile in "foo" to declare extracted file "foo/b" is
+            not an option, because you should not change existing tree 
+
+            That makes good rationale for why main target must contain names.
+            -->
+          </simpara>
+        </listitem>
+      </itemizedlist>
+
+      <para id="bbv2.reference.targets.references">
+        <emphasis>Target reference</emphasis> is used to
+        specify a source target, and may additionally specify desired
+        properties for that target. It has this syntax:</para>
+
+<programlisting>
+target-reference -&gt; target-id [ "/" requested-properties ]
+requested-properties -&gt; property-path
+</programlisting>
+
+      <para>
+        For example,
+
+        <programlisting>
+          exe compiler : compiler.cpp libs/cmdline/&lt;optimization&gt;space ;
+        </programlisting>
+        
+        would cause the version of <literal>cmdline</literal> library,
+        optimized for space, to be linked in even if the
+        <literal>compiler</literal> executable is build with optimization for
+        speed.
+      </para>
+    </section>
+    
+  </section>
+
+  <section id="bbv2.reference.generators">
+    <title>Generators</title>
+
+    <warning><para>The information is this section is likely to be outdated
+        and misleading. 
+      </para></warning>
+
+    <para>To construct a main target with given properties from sources,
+      it is required to create a dependency graph for that main target,
+      which will also include actions to be run. The algorithm for
+      creating the dependency graph is described here.</para>
+
+    <para>The fundamental concept is <emphasis>generator</emphasis>. If encapsulates
+      the notion of build tool and is capable to converting a set of
+      input targets into a set of output targets, with some properties.
+      Generator matches a build tool as closely as possible: it works
+      only when the tool can work with requested properties (for
+      example, msvc compiler can't work when requested toolset is gcc),
+      and should produce exactly the same targets as the tool (for
+      example, if Borland's linker produces additional files with debug
+      information, generator should also).</para>
+
+    <para>Given a set of generators, the fundamental operation is to
+      construct a target of a given type, with given properties, from a
+      set of targets. That operation is performed by rule
+      <literal>generators.construct</literal> and the used algorithm is described
+      below.</para>
+
+    <section>
+      <title>Selecting and ranking viable generators</title>
+
+      <para>Each generator, in addition to target types that it can
+        produce, have attribute that affects its applicability in
+        particular sitiation. Those attributes are:</para>
+
+      <orderedlist>
+        <listitem>
+          <simpara>
+            Required properties, which are properties absolutely
+            necessary for the generator to work. For example, generator
+            encapsulating the gcc compiler would have &lt;toolset&gt;gcc as
+            required property.
+          </simpara>
+        </listitem>
+
+        <listitem>
+          <simpara>
+            Optional properties, which increase the generators
+            suitability for a particual build.
+          </simpara>
+        </listitem>
+      </orderedlist>
+      
+      <para>
+        Generator's required and optional properties may not include
+        either free or incidental properties. (Allowing this would
+        greatly complicate caching targets).
+      </para>
+
+      <para>When trying to construct a target, the first step is to select
+        all possible generators for the requested target type, which
+        required properties are a subset of requested properties.
+        Generators which were already selected up the call stack are
+        excluded. In addition, if any composing generators were selected
+        up the call stack, all other composing generators are ignored
+        (TODO: define composing generators). The found generators
+        are assigned a rank, which is the number of optional properties
+        present in requested properties. Finally, generators with highest
+        rank are selected for futher processing.</para>
+
+    </section>
+    <section>
+      <title>Running generators</title>
+
+      <para>When generators are selected, each is run to produce a list of
+        created targets. This list might include targets which are not of
+        requested types, because generators create the same targets as
+        some tool, and tool's behaviour is fixed. (Note: should specify
+        that in some cases we actually want extra targets). If generator
+        fails, it returns an empty list. Generator is free to call
+        'construct' again, to convert sources to the types it can handle.
+        It also can pass modified properties to 'construct'. However, a
+        generator is not allowed to modify any propagated properties,
+        otherwise when actually consuming properties we might discover
+        that the set of propagated properties is different from what was
+        used for building sources.</para>
+
+      <para>For all targets which are not of requested types, we try to
+        convert them to requested type, using a second call to
+        <literal>construct</literal>. This is done in order to support
+        transformation sequences where single source file expands to
+        several later. See <ulink url=
+          "http://groups.yahoo.com/group/jamboost/message/1667">this
+          message</ulink> for details.</para>
+
+    </section>
+
+    <section>
+      <title>Selecting dependency graph</title>
+
+      <para>
+        After all generators are run,
+        it is necessary to decide which of successfull invocation will be
+        taken as final result. At the moment, this is not done. Instead,
+        it is checked whether all successfull generator invocation
+        returned the same target list. Error is issued otherwise.
+      </para>
+
+    </section>
+
+    <section>
+      <title>Property adjustment</title>
+
+      <para>Because target location is determined by the build system, it
+        is sometimes necessary to adjust properties, in order to not
+        break actions. For example, if there's an action which generates
+        a header, say "a_parser.h", and a source file "a.cpp" which
+        includes that file, we must make everything work as if a_parser.h
+        is generated in the same directory where it would be generated
+        without any subvariants.</para>
+
+      <para>Correct property adjustment can be done only after all targets
+        are created, so the approach taken is:</para>
+
+      <orderedlist>
+        <listitem>
+          <para>
+            When dependency graph is constructed, each action can be
+            assigned a rule for property adjustment.
+          </para>
+        </listitem>
+
+        <listitem>
+          <para>
+            When virtual target is actualized, that rule is run and
+            return the final set of properties. At this stage it can use
+            information of all created virtual targets.
+          </para>
+        </listitem>
+      </orderedlist>
+
+      <para>In case of quoted includes, no adjustment can give 100% correct
+        results. If target dirs are not changed by build system, quoted
+        includes are searched in "." and then in include path, while angle
+        includes are searched only in include path. When target dirs are
+        changed, we'd want to make quoted includes to be search in "." then in
+        additional dirs and then in the include path and make angle includes
+        be searched in include path, probably with additional paths added at
+        some position. Unless, include path already has "." as the first
+        element, this is not possible. So, either generated headers should not
+        be included with quotes, or first element of include path should be
+        ".", which essentially erases the difference between quoted and angle
+        includes. <emphasis role="bold">Note:</emphasis> the only way to get
+        "." as include path into compiler command line is via verbatim
+        compiler option. In all other case, Boost.Build will convert "." into
+        directory where it occurs.</para>
+
+    </section>
+
+    <section>
+      <title>Transformations cache</title>
+
+      <para>
+        Under certain conditions, an
+        attempt is made to cache results of transformation search. First,
+        the sources are replaced with targets with special name and the
+        found target list is stored. Later, when properties, requested
+        type, and source type are the same, the store target list is
+        retrieved and cloned, with appropriate change in names.
+      </para>
+
+    </section>
+  </section>
+
+</chapter>
+
+<!--
+     Local Variables:
+     mode: xml
+     sgml-indent-data: t     
+     sgml-parent-document: ("userman.xml" "chapter")
+     sgml-set-face: t
+     End:
+-->

Added: boost-jam/boost-build/branches/upstream/current/doc/src/tutorial.xml
===================================================================
--- boost-jam/boost-build/branches/upstream/current/doc/src/tutorial.xml	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/doc/src/tutorial.xml	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,670 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE chapter PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN"
+  "http://www.boost.org/tools/boostbook/dtd/boostbook.dtd">
+
+<?psgml nofill screen programlisting literallayout?>
+
+<chapter id="bbv2.tutorial" status="draft">
+  <title>Tutorial</title>
+
+  <section id="bbv2.tutorial.hello">
+    <title>Hello, world</title>
+
+    <para>The simplest project that Boost.Build can construct is
+      stored in <filename>example/hello/</filename> directory. The
+      project is described by a file
+      called <filename>Jamfile</filename> that contains:
+
+<programlisting>
+exe hello : hello.cpp ;
+</programlisting>
+
+      Even with this simple setup, you can do some interesting
+      things. First of all, just invoking <command>bjam</command> will
+      build the debug variant of the <command>hello</command>
+      executable by compiling and
+      linking <filename>hello.cpp</filename>.  Now, to build the
+      release variant of <command>hello</command>, invoke
+
+<screen>
+bjam release
+</screen>
+
+      Note that debug and release variants are created in different
+      directories, so you can switch between variants or even build
+      multiple variants at once, without any unneccessary
+      recompilation. Let's extend the example by adding another line
+      to our project's <filename>Jamfile</filename>:
+
+<programlisting>
+exe hello2 : hello.cpp ;
+</programlisting>
+
+      Now we can build both the debug and release variants of our
+      project:
+
+<screen>
+bjam debug release
+</screen>
+
+      Note that two variants of <command>hello2</command> are linked.
+      Since we have already built both variants
+      of <command>hello</command>, hello.cpp won't be recompiled;
+      instead the existing object files will just be linked into the
+      corresponding variants of <command>hello2</command>. Now 
+      let's remove all the built products:
+
+<screen>
+bjam --clean debug release
+</screen>
+
+      It's also possible to build or clean specific targets.  The
+      following two commands, respectively, build or clean only the
+      debug version of <command>hello2</command>.
+
+<screen>
+bjam hello2
+bjam --clean hello2
+</screen>
+    </para>
+
+  </section>
+  <section id="bbv2.tutorial.properties">
+    <title>Properties</title>
+
+    <para>
+      To portably represent aspects of target configuration such as
+      debug and release variants, or single- and multi-threaded
+      builds, Boost.Build uses <firstterm>features</firstterm> with
+      associated <firstterm>values</firstterm>.  For
+      example, the "debug-symbols" feature can have a value of "on" or
+      "off".  A <firstterm>property</firstterm> is just a (feature,
+      value) pair.  When a user initiates a build, Boost.Build
+      automatically translates the requested properties into appropriate
+      command-line flags for invoking toolset components like compilers
+      and linkers.</para>
+
+    <para>There are many built-in features that can be combined to
+      produce arbitrary build configurations.  The following command
+      builds the project's &quot;release&quot; variant with inlining
+      disabled and debug symbols enabled:
+
+<screen>
+bjam release inlining=off debug-symbols=on
+</screen>
+</para>
+
+    <para>Properties on the command-line are specified with the syntax:
+
+<screen>
+<replaceable>feature-name</replaceable>=<replaceable>feature-value</replaceable>
+</screen>
+</para>
+
+    <para>The "release" and "debug" that we've seen
+      in <command>bjam</command> invocations are just a shorthand way to
+      specify values of the "variant" feature.  For example, the command
+      above could also have been written this way:
+
+      <screen>
+bjam variant=release inlining=off debug-symbols=on
+      </screen>
+    </para>
+
+    <para>  &quot;variant&quot; is so commonly-used that it has been given
+      special status as an <firstterm>implicit</firstterm> feature
+      &#x2014; Boost.Build will deduce the its identity just from the name
+      of one of its values.  
+    </para>
+
+    <para>
+      A complete description of features can be found
+      <link linkend="bbv2.reference.features">here</link>. 
+    </para>
+
+
+    <section id="bbv2.tutorial.properties.requirements">
+      <title>Build Requests and Target Requirements</title>
+
+      <para>      
+        The set of properties specified in the command line constitute a
+        <firstterm>build request</firstterm> &#x2014; a description of
+        the desired properties for building the requested targets (or,
+        if no targets were explicitly requested, the project in the
+        current directory).  The <emphasis>actual</emphasis> properties
+        used for building targets is typically a combination of the
+        build request and properties derived from the
+        project's <filename>Jamfile</filename>s.  For example, the
+        locations of <code>#include</code>d header files are normally
+        not specified on the command-line, but described
+        in <filename>Jamfile</filename>s as <firstterm>target
+          requirements</firstterm> and automatically combined with the
+        build request for those targets.  Multithread-enabled
+        compilation is another example of a typical target requirement.
+        The <filename>Jamfile</filename> fragment below illustrates how
+        these requirements might be specified.
+      </para>
+
+<programlisting>
+exe hello 
+    : hello.cpp
+    : &lt;include&gt;/home/ghost/Work/boost &lt;threading&gt;multi
+    ;
+</programlisting>
+
+      <para> 
+        When <filename>hello</filename> is built, the two
+        requirements specified above will normally always be present.
+        If the build request given on the <command>bjam</command>
+        command-line explictly contradicts a target's requirements,
+        the command-line usually overrides (or, in the case of
+        &quot;free&quot; feautures like <code>&lt;include&gt;</code>
+        <footnote>See <xref
+        linkend="bbv2.reference.features.attributes"/></footnote>,
+        augments) the target requirements.  However, when a
+        contradiction of a target's requrements involves certain
+        <firstterm>link-incompatible</firstterm> features, the target
+        will be skipped.  See <xref linkend=
+        "bbv2.reference.variants.compat"/> for more information.
+      </para>
+
+    </section>
+    <section id="bbv2.tutorial.properties.project_attributes">
+      <title>Project Attributes</title>
+
+      <para>
+        If we want the same requirements for our other
+        target, <filename>hello2</filename>, we could simply duplicate
+        them.  However, as projects grow, that approach leads to a great
+        deal of repeated boilerplate in Jamfiles.
+        
+        Fortunately, there's a better way. Each project (i.e. each
+        <filename>Jamfile</filename>), can specify a set of <firstterm>attributes</firstterm>,
+        including requirements:
+
+<programlisting>
+project 
+    : requirements &lt;include&gt;/home/ghost/Work/boost &lt;threading&gt;multi 
+    ;
+
+exe hello : hello.cpp ;
+exe hello2 : hello.cpp ;
+</programlisting>
+
+        The effect would be as if we specified the same requirement for
+        both <command>hello</command> and <command>hello2</command>.
+      </para>
+    </section>
+  </section>
+
+  <section id="bbv2.tutorial.hierarchy">
+    <title>Project Hierarchies</title>
+
+    <para>So far we've only considered examples with one project
+      (i.e. with one <filename>Jamfile</filename>). A typical large
+      software project would be composed of sub-projects organized
+      into a tree. The top of the tree is called the
+      <firstterm>project root</firstterm>.  Besides a
+      <filename>Jamfile</filename>, the project root directory
+      contains a file called <filename>project-root.jam</filename>. Every other
+      <filename>Jamfile</filename> in the project has a single parent
+      project, rooted in the nearest parent directory containing a
+      <filename>Jamfile</filename>. For example, in the following
+      directory layout:
+
+<screen>
+top/ 
+  |
+  +-- Jamfile
+  +-- project-root.jam
+  |
+  +-- src/
+  |    |
+  |    +-- Jamfile
+  |    `-- app.cpp
+  | 
+  `-- util/
+       |
+       +-- foo/
+       .    |
+       .    +-- Jamfile
+       .    `-- bar.cpp
+</screen>
+
+      <!-- "lib/lib1/lib1" changed to "util/foo/bar" to avoid confusion -->
+
+      the project root is <filename>top/</filename>.  Because there is
+      no <filename>Jamfile</filename> in
+      <filename>top/util/</filename>, the projects in
+      <filename>top/src/</filename> and
+      <filename>top/util/foo/</filename> are immediate children of the
+      root project.
+    </para>
+
+    <para>
+      Projects inherit all attributes (such as requirements)
+      from their parents.  Inherited requirements are combined with
+      any requirements specified by the sub-project.  
+      For example, if <filename>top/Jamfile</filename> has
+
+<programlisting>
+&lt;include&gt;/home/ghost/local
+</programlisting>
+
+      in its requirements, then all of its sub-projects will have it
+      in their requirements, too.  Of course, any project can add
+      additional includes. <footnote>Many features will be overridden,
+      rather than added-to, in sub-projects.  See <xref
+      linkend="bbv2.reference.features.attributes"/> for more
+      information</footnote> More details can be found in the section
+      on <link linkend= "bbv2.advanced.projects">projects</link>.
+    </para>
+
+    <para>
+      Invoking <command>bjam</command> without explicitly specifying
+      any targets on the command-line builds the project rooted in the
+      current directory.  Building a project does not automatically
+      cause its sub-projects to be built unless the parent project's
+      <filename>Jamfile</filename> explicitly requests it. In our
+      example, <filename>top/Jamfile</filename> might contain:
+
+<programlisting>
+build-project src ;
+</programlisting>
+
+      which would cause the project in <filename>top/src/</filename>
+      to be built whenever the project in <filename>top/</filename> is
+      built. However, targets in <filename>top/util/foo/</filename>
+      will be built only if they are needed by targets in
+      <filename>top/</filename> or <filename>top/src/</filename>.
+    </para>
+  </section>
+
+  <section id="bbv2.tutorial.libs">
+    <title>Libraries and Dependent Targets</title>
+
+    <comment>TODO: need to make this
+      section consistent with "examples-v2/libraries".</comment>
+
+    <para>
+      Targets that are "needed" by other targets are called
+      <firstterm>dependencies</firstterm> of those other targets.  The
+      targets that need the other targets are called
+      <firstterm>dependent</firstterm> targets.
+    </para>
+
+    <para>To get a feeling of target dependencies, let's continue the
+      above example and see how <filename>src/Jamfile</filename> can
+      use libraries from <filename>util/foo</filename>.  Assume
+      util/foo/Jamfile contains:
+
+<programlisting>
+lib bar : bar.cpp ;
+</programlisting>
+
+      Then, to use this library in <filename>src/Jamfile</filename>, we can write:
+
+<programlisting>
+exe app : app.cpp ../util/foo//bar ;
+</programlisting>
+
+      While <code>app.cpp</code> refers to a regular source file,
+      <code>../util/foo//bar</code> is a reference to another target:
+      a library "bar" declared in the <filename>Jamfile</filename> at
+      <filename>../util/foo</filename>.  When linking the
+      <command>app</command> executable, the appropriate version of
+      <code>bar</code> will be built and linked in. What do we mean by
+      "appropriate"? For example, suppose we build "app" with:
+
+<screen>
+bjam app optimization=full cxxflags=-w-8080
+</screen>
+
+      Which properties must be used to build <code>foo</code>? The
+      answer is that some properties are
+      <firstterm>propagated</firstterm> &#x2014; Boost.Build attempts to
+      use dependencies with the same value of propagated features. The
+      &lt;optimization&gt; feature is propagated, so both "app" and
+      "foo" will be compiled with full optimization. But
+      &lt;cxxflags&gt; feature is not propagated: its value will be
+      added as-is to compiler flags for "a.cpp", but won't affect
+      "foo". There is still a couple of problems. First, the library
+      probably has some headers which must be used when compiling
+      "app.cpp". We could use requirements on "app" to add those
+      includes, but then this work will be repeated for all programs
+      which use "foo". A better solution is to modify
+      util/foo/Jamfilie in this way:
+
+<programlisting>
+project 
+    : usage-requirements &lt;include&gt;.
+    ;
+
+lib foo : foo.cpp ;
+</programlisting>
+
+      Usage requirements are requirements which are applied to
+      dependents. In this case, &lt;include&gt; will be applied to all
+      targets which use "foo" &#x2014; i.e. targets which have "foo"
+      either in sources or in dependency properties. You'd need to
+      specify usage requirements only once, and programs which use "foo"
+      don't have to care about include paths any longer. Or course, the
+      path will be interpreted relatively to "util/foo" and will be
+      adjusted according to the <command>bjam</command>s invocation
+      directory. For
+      example, if building from project root, the final compiler's
+      command line will contain <option>-Ilib/foo</option>.
+    </para>
+
+    <para>The second problem is that we hardcode the path to library's
+      Jamfile. Imagine it's hardcoded in 20 different places and we
+      change the directory layout. The solution is to use project ids
+      &#x2014; symbolic names, not tied to directory layout. First, we
+      assign a project id to Jamfile in util/foo:</para>
+
+<programlisting>
+project foo
+    : usage-requirements &lt;include&gt;.
+    ;
+</programlisting>
+
+    <para>
+      Second, we use the project id to refer to the library in
+      src/Jamfile:
+
+<programlisting>
+exe app : app.cpp /foo//bar ;
+</programlisting>
+
+      The "/foo//bar" syntax is used to refer to target "foo" in
+      project with global id "/foo" (the slash is used to specify global
+      id). This way, users of "foo" do not depend on its location, only
+      on id, which is supposedly stable. The only thing left, it to make
+      sure that src/Jamfile knows the project id that it uses. We add to
+      top/Jamfile the following line:
+
+<programlisting>
+use-project /foo : util/foo ;
+</programlisting>
+
+      Now, all projects can refer to "foo" using the symbolic
+      name. If the library is moved somewhere, only a single line in the
+      top-level Jamfile should be changed.
+    </para>
+  </section>
+
+  <section id="bbv2.tutorial.depends">
+    <title>Library dependencies</title>
+
+    <para>The previous example was simple. Often, there are long chains
+      of dependencies between libraries. The main application is a thin
+      wrapper on top of library with core logic, which uses library of
+      utility functions, which uses boost filesystem library.
+      Expressing these dependencies is straightforward:</para>
+
+<programlisting>
+lib utils : utils.cpp /boost/filesystem//fs ;   
+lib core : core.cpp utils ;
+exe app : app.cpp core ;
+</programlisting>
+
+    <para>So, what's the reason to even mention this case? First,
+      because it's a bit more complex that it seems. When using shared
+      linking, libraries are build just as written, and everything will
+      work. However, what happens with static linking? It's not
+      possible to include another library in static library.
+      Boost.Build solves this problem by returning back library targets
+      which appear as sources for static libraries. In this case, if
+      everything is built statically, the "app" target will link not
+      only "core" library, but also "utils" and
+      "/boost/filesystem//fs".</para>
+
+    <para>So, the net result is that the above code will work for both
+      static linking and for shared linking.</para>
+
+    <para>Sometimes, you want all applications in some project to link
+      to a certain library. Putting the library in sources of all
+      targets is possible, but verbose. You can do better by using the
+      &lt;source&gt; property. For example, if "/boost/filesystem//fs"
+      should be linked to all applications in your project, you can add
+      &lt;source&gt;/boost/filesystem//fs to requirements of the
+      project, like this:</para>
+
+<programlisting>
+project 
+   : requirements &lt;source&gt;/boost/filesystem//fs
+   ;   
+</programlisting>
+    </section>
+
+  <section id="bbv2.tutorial.linkage">
+    <title>Static and shared libaries</title>
+
+    <para>While the
+      previous section explained how to create and use libraries, it
+      omitted one important detail. Libraries can be either
+      <emphasis>static</emphasis>, which means they are included in executable
+      files which use them, or <emphasis>shared</emphasis> (a.k.a.
+      <emphasis>dynamic</emphasis>), which are only referred to from executables,
+      and must be available at run time. Boost.Build can work with both
+      types. By default, all libraries are shared. This is much more
+      efficient in build time and space. But the need to install all
+      libraries to some location is not always convenient, especially
+      for debug builds. Also, if the installed shared library changes,
+      all application which use it might start to behave differently.
+    </para>
+
+    <para>Static libraries do not suffer from these problems, but
+      considerably increase the size of application. Before describing
+      static libraries, it's reasonable to give another, quite simple
+      approach. If your project is built with
+      &lt;hardcode-dll-paths&gt;true property, then the application
+      will include the full paths for all shared libraries, eliminating
+      the above problems. Unfortunately, you no longer can move shared
+      library to a different location, which makes this option suitable
+      only for debug builds. Further, only gcc compiler supports this
+      option.</para>
+
+    <para>Building a library statically is easy. You'd need to change
+      the value of &lt;link&gt; feature from it's deafault value
+      <literal>shared</literal>, to <literal>static</literal>. So, to build everything as
+      static libraries, you'd say</para>
+
+<screen>
+bjam link=static
+</screen>
+
+    <para>
+      on the command line. The linking mode can be fine-tuned on
+      per-target basis.
+
+      <orderedlist>
+        <listitem>
+          <para>
+            Suppose your library can be only build statically. This is
+            easily achieved using requirements:
+
+<programlisting>
+lib l : l.cpp : &lt;link&gt;static ;
+</programlisting>
+            
+          </para>
+        </listitem>
+
+        <listitem>
+          <para>
+            What if library can be both static and shared, but when
+            using it in specific executable, you want it static?
+            <link linkend="bbv2.advanced.targets.references">Target
+              references</link> are here to help:
+
+<programlisting>
+exe important : main.cpp helpers/&lt;link&gt;static ;
+</programlisting>
+
+          </para>
+        </listitem>
+
+        <listitem>
+          <para>
+            What if the library is defined in some other project, which
+            you cannot change. But still, you want static linking to that
+            library in all cases. You can use target references everywhere:
+
+<programlisting>
+exe e1 : e1.cpp /other_project//bar/&lt;link&gt;static ;
+exe e10 : e10.cpp /other_project//bar/&lt;link&gt;static ;
+</programlisting>
+
+            but that's far from being convenient. Another way is to
+            introduce a level of indirection: create a local target, which will
+            refer to static version of <filename>foo</filename>. Here's the
+            solution:
+
+<programlisting>
+alias foo : /other_project//bar/&lt;link&gt;static ;
+exe e1 : e1.cpp foo ;
+exe e10 : e10.cpp foo ;
+</programlisting>
+
+            Note that the <link linkend="bbv2.builtins.alias">alias</link> 
+            rule is specifically used for rename a reference to a target and possibly
+            change the properties.
+
+          </para>
+        </listitem>
+      </orderedlist>
+    </para>
+  </section>
+
+  <section id="bbv2.tutorial.conditions">
+    <title>Conditions and alternatives</title>
+
+    <para>As we've just figured out, properties can significally affect the
+      way targets are built. The processing of the &lt;link&gt; feature is
+      built in the build system, and is quite complex. But there is a couple
+      of mechanisms which allow ordinary users to do different things 
+      depending on properties.
+    </para>
+
+    <para>The first mechanism is called <firstterm>conditinal
+        requirement</firstterm>. For example, you might want to set specific
+      defines when the library is build as shared, or you have your own define
+      to be used in release mode. Here's a piece of Jamfile.
+<programlisting>
+lib network : network.cpp 
+    : &lt;link&gt;shared:&lt;define&gt;NEWORK_LIB_SHARED 
+      &lt;variant&gt;release:&lt;define&gt;EXTRA_FAST
+    ;
+</programlisting>
+      This will have exactly the effect we wanted: whenever &lt;link&gt;shared
+      is in properties, &lt;define&gt;NEWORK_LIB_SHARED will be in properties
+      as well.
+    </para>
+
+    <para>
+      Sometimes different variant of a target are so different, that
+      describing them using conditional requirements would be hard. Imagine
+      that a library has different sources on two supported toolsets, and
+      dummy implementation for all the other toolset. We can express this
+      situation using <firstterm>target alternatives</firstterm>:
+<programlisting>
+lib demangler : dummy_demangler.cpp ;
+lib demangler : demangler_gcc.cpp : &lt;toolset&gt;gcc ;
+lib demangler : demangler_msvc.cpp : &lt;toolset&gt;msvc ;
+</programlisting>
+      The proper alternative will be automatically selected. 
+    </para>
+    
+  </section>
+
+
+  <section id="bbv2.tutorial.prebuilt">
+    <title>Prebuilt targets</title>
+
+    <para>
+      We've just learned how to use libraries which are created by
+      Boost.Build. But some libraries are not. At the same time, those
+      libraries can have different versions (release and debug, for
+      example), that we
+      should select depending on build properties. Prebuilt targets
+      provide a mechanism for that. Jamfile in util/lib2 can contain:
+
+<programlisting>
+lib lib2
+    : 
+    : &lt;file&gt;lib2_release.a &lt;variant&gt;release
+    ;
+
+lib lib2
+    : 
+    : &lt;file&gt;lib2_debug.a &lt;variant&gt;debug
+    ;
+</programlisting>
+
+      This defines two alternatives for target "lib2", and for each
+      one names a prebuilt file. Naturally, there are no sources.
+      Instead, the &lt;file&gt; feature is used to specify the file name.
+      Which alternative is selected depends on properties of dependents.
+      If "app" binary should use "lib2", we can write:
+
+<programlisting>
+exe app : app.cpp ../util/lib2//lib2 ;
+</programlisting>
+
+      If we build release version of "app", then it will be linked
+      with "lib2_release.a", and debug version will use "lib2_debug.a".
+      Another important kind of prebuilt targets are system libraries
+      &#x2014; more specifically, libraries which are automatically found
+      by the compiler. E.g. gcc uses "-l" switch for that. Such libraries
+      should be declared almost like regular ones:
+
+<programlisting>
+lib zlib : : &lt;name&gt;z ;
+</programlisting>
+
+      We again don't specify any sources, but give a name which
+      should be passed to the compiler. In this example, and for gcc
+      compiler, the "-lz" option will be added. Paths where library
+      should be searched can also be specified:
+
+<programlisting>
+lib zlib : : &lt;name&gt;z &lt;search&gt;/opt/lib ;
+</programlisting>
+
+      And, of course, two variants can be used:
+
+<programlisting>
+lib zlib : : &lt;name&gt;z &lt;variant&gt;release ;
+lib zlib : : &lt;name&gt;z_d &lt;variant&gt;debug ;
+</programlisting>
+
+      Of course, you'll probably never in your life need debug
+      version of zlib, but for other libraries this is quite reasonable.
+    </para>
+
+    <para>More advanced use of prebuilt target is described in <ulink
+        url="doc/recipes.html#site_config_targets">recipes</ulink>.</para>
+
+  </section>
+
+</chapter>
+
+<!--
+     Local Variables:
+     mode: xml
+     sgml-indent-data:t
+     sgml-parent-document:("userman.xml" "chapter")
+     sgml-set-face: t
+     sgml-omittag:nil
+     sgml-shorttag:nil
+     sgml-namecase-general:t
+     sgml-general-insert-case:lower
+     sgml-minimize-attributes:nil
+     sgml-always-quote-attributes:t
+     sgml-indent-step:2
+     sgml-exposed-tags:nil
+     sgml-local-catalogs:nil
+     sgml-local-ecat-files:nil
+     End:
+-->

Added: boost-jam/boost-build/branches/upstream/current/doc/src/userman.xml
===================================================================
--- boost-jam/boost-build/branches/upstream/current/doc/src/userman.xml	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/doc/src/userman.xml	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE part PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN"
+  "http://www.boost.org/tools/boostbook/dtd/boostbook.dtd">
+
+<part xmlns:xi="http://www.w3.org/2001/XInclude"
+      id="bbv2" last-revision="$Date: 2004/10/21 10:05:15 $">
+
+  <title>Boost.Build v2 User Manual</title>
+
+  <!-- Chapters -->
+  <xi:include href="howto.xml"/>
+  <xi:include href="install.xml"/>
+  <xi:include href="tutorial.xml"/>
+  <xi:include href="advanced.xml"/>
+  <xi:include href="extending.xml"/>
+  <xi:include href="reference.xml"/>
+  <xi:include href="faq.xml"/>
+
+  <!-- Appendicies -->
+  <xi:include href="architecture.xml"/>
+
+</part>

Added: boost-jam/boost-build/branches/upstream/current/doc/tools.html
===================================================================
--- boost-jam/boost-build/branches/upstream/current/doc/tools.html	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/doc/tools.html	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,87 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+
+<html>
+  <head>
+    <meta name="generator" content=
+    "HTML Tidy for Linux/x86 (vers 1st April 2002), see www.w3.org">
+    <meta name="generator" content="Microsoft FrontPage 5.0">
+    <meta http-equiv="Content-Type" content=
+    "text/html; charset=windows-1252">
+    <!-- tidy options: &dash;&dash;tidy-mark false -i -wrap 78 !-->
+
+    <title>Boost Build System V2 &mdash; supported tools</title>
+  </head>
+
+  <body bgcolor="#FFFFFF" text="#000000">
+    <img src="../../../../boost.png" alt="boost.png (6897 bytes)" align="center"
+    width="277" height="86"> <a href="http://sourceforge.net"><img src=
+    "http://sourceforge.net/sflogo.php?group_id=7586&amp;type=1" width="88"
+    height="31" border="0" alt="SourceForge.net Logo" align="right"></a> 
+
+    <h1>Boost Build System V2 &mdash; supported tools</h1>
+
+    <h2>Compilers</h2>
+
+    <p>The following compilers are supported:</p>
+
+    <ul>
+      <li>GNU gcc (various versions), on Linux, NT, Cygwin and Darwin.</li>
+
+      <li>Microsoft VC++ compiler (various version), on NT and Cygwin.</li>
+
+      <li>Borland's compiler, on NT and Cygwin.</li>
+
+      <li>Metrowerks Code Warrior, on NT.</li>
+
+      <li>Intel C++ Compiler, on Linux and NT.</li>
+
+      <li>Sun's C++ Compiler.</li>
+        
+    </ul>
+
+    <h2>Libraries</h2>
+
+    <p>Some important libraries have special support in Boost.Build:</p>
+
+    <ul>
+      <li><a href="http://stlport.org">STLport</a> &mdash; on gcc and
+      msvc.</li>
+
+      <li><a href="http://www.trolltech.com/products/qt/index.html">QT</a>,
+      including the <tt>moc</tt> and <tt>uic</tt> tools &mdash; on gcc and msvc.</li>
+    </ul>
+
+    <h2>Other tools</h2>
+
+    <ul>
+      <li>Parser/lexer generators <tt>bison</tt> and <tt>lex</tt>.</li>
+
+      <li>XSLT processor <a href=
+      "http://xmlsoft.org/XSLT/">xsltproc</a>.</li>
+
+      <li>The Apache <a href="http://xml.apache.org/fop/index.html">FOP</a>
+      tool.</li>
+
+      <li>BoostBook documentation format.</li>
+
+      <li>GNU <a href=
+      "http://www.gnu.org/software/gettext/gettext.html">gettext</a>
+      internationalization tools.</li>
+    </ul>
+    <hr>
+
+    <p>&copy; Copyright Vladimir Prus 2003. Permission to copy, use, modify,
+    sell and distribute this document is granted provided this copyright
+    notice appears in all copies. This document is provided "as is" without
+    express or implied warranty, and with no claim as to its suitability for
+    any purpose.</p>
+
+    <p>Revised 
+    <!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %B, %Y" startspan
+                                        -->Jule 3, 2003 
+    <!--webbot bot="Timestamp" endspan i-checksum="13972"
+                                        -->
+    </p>
+  </body>
+</html>
+

Added: boost-jam/boost-build/branches/upstream/current/doc/tracker.html
===================================================================
--- boost-jam/boost-build/branches/upstream/current/doc/tracker.html	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/doc/tracker.html	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,69 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+
+<html>
+  <head>
+    <meta name="generator" content=
+    "HTML Tidy for Linux/x86 (vers 1st April 2002), see www.w3.org">
+    <meta name="generator" content="Microsoft FrontPage 5.0">
+    <meta http-equiv="Content-Type" content=
+    "text/html; charset=windows-1252">
+    <!-- tidy options: &dash;&dash;tidy-mark false -i -wrap 78 !-->
+
+    <title>Boost Build System V2 tracker</title>
+  </head>
+
+  <body bgcolor="#FFFFFF" text="#000000">
+    <img src="../../../../boost.png" alt="boost.png (6897 bytes)" align="center"
+    width="277" height="86"> <a href="http://sourceforge.net"><img src=
+    "http://sourceforge.net/sflogo.php?group_id=7586&amp;type=1" width="88"
+    height="31" border="0" alt="SourceForge.net Logo" align="right"></a> 
+
+    <h1>Boost Build System V2 tracker</h1>
+
+    <p>All bugs, planned features and enhancements for Boost.Build V2 are
+    kept in a online tracker, awailable at <a href=
+    "http://zigzag.cs.msu.su:7814/">http://zigzag.cs.msu.su:7814/</a></p>
+
+    <p>For read only access, please do the following:</p>
+
+    <ol>
+      <li>Point your browser to the above URL.</li>
+
+      <li>Type "anonymous" as username and password.</li>
+
+      <li>To see all issues, go to "Select query" menu, and choose
+      "Active"</li>
+
+      <li>To see issues planned for the next milestone, choose "Next
+      Milestone".</li>
+    </ol>
+
+    <p>If you want to create new issues and add comments, you'd need
+    read-write access. To obtain it, please do the following:</p>
+
+    <ol>
+      <li>Point your browser to the above URL.</li>
+
+      <li>Click on the "create an account" link and follow the
+      instructions.</li>
+
+      <li>Once you've registered and logged in, click "request roles" link
+      and request "Observe" role in "Boost-&gt;Build" module.</li>
+    </ol>
+    <hr>
+
+    <p>&copy; Copyright Vladimir Prus 2003. Permission to copy, use, modify,
+    sell and distribute this document is granted provided this copyright
+    notice appears in all copies. This document is provided "as is" without
+    express or implied warranty, and with no claim as to its suitability for
+    any purpose.</p>
+
+    <p>Revised 
+    <!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %B, %Y" startspan
+                                            -->Jule 8, 2003 
+    <!--webbot bot="Timestamp" endspan i-checksum="13972"
+                                            -->
+    </p>
+  </body>
+</html>
+

Added: boost-jam/boost-build/branches/upstream/current/example/boost-build.jam
===================================================================
--- boost-jam/boost-build/branches/upstream/current/example/boost-build.jam	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/example/boost-build.jam	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,2 @@
+
+boost-build ../kernel ;
\ No newline at end of file

Added: boost-jam/boost-build/branches/upstream/current/example/customization/Jamfile
===================================================================
--- boost-jam/boost-build/branches/upstream/current/example/customization/Jamfile	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/example/customization/Jamfile	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,3 @@
+
+exe codegen : codegen.cpp class.verbatim usage.verbatim 
+    t1.verbatim ;
\ No newline at end of file

Added: boost-jam/boost-build/branches/upstream/current/example/customization/class.verbatim
===================================================================
--- boost-jam/boost-build/branches/upstream/current/example/customization/class.verbatim	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/example/customization/class.verbatim	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,7 @@
+class_template
+
+class %class_name% {
+public:
+    %class_name%() {}
+    ~%class_name%() {}
+};
\ No newline at end of file

Added: boost-jam/boost-build/branches/upstream/current/example/customization/codegen.cpp
===================================================================
--- boost-jam/boost-build/branches/upstream/current/example/customization/codegen.cpp	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/example/customization/codegen.cpp	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,36 @@
+// (C) Copyright Vladimir Prus, 2003
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// Please see 'usage.verbatim' file for usage notes.
+
+#include <iostream>
+#include <string>
+#include <cstring>
+using std::cout;
+using std::string;
+using std::strlen;
+
+extern const char class_template[];
+extern const char usage[];
+
+int main(int ac, char* av[])
+{
+    if (av[1]) {        
+
+        string class_name = av[1];
+        string s = class_template;
+        
+        string::size_type n;
+        while((n = s.find("%class_name%")) != string::npos) {
+            s.replace(n, strlen("%class_name%"), class_name);
+        }
+        std::cout << "Output is:\n";
+        std::cout << s << "\n";        
+        return 0;
+    } else {
+        std::cout << usage << "\n";
+        return 1;
+    }
+}

Added: boost-jam/boost-build/branches/upstream/current/example/customization/inline_file.py
===================================================================
--- boost-jam/boost-build/branches/upstream/current/example/customization/inline_file.py	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/example/customization/inline_file.py	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,45 @@
+#!/usr/bin/python
+
+#  Copyright (C) Vladimir Prus 2003. Permission to copy, use, modify, sell and
+#  distribute this software is granted provided this copyright notice appears in
+#  all copies. This software is provided "as is" without express or implied
+#  warranty, and with no claim as to its suitability for any purpose.
+
+import sys
+from string import strip
+
+def quote_line(line):
+
+    result = ""
+
+    for i in line:
+        if (i == '\\'):
+            result = result + '\\\\'
+        elif (i == '\"'):
+            result = result + '\\\"'
+        elif (i != '\r' and i != '\n'):
+            result = result + i;
+
+    return '\"' + result + '\\n\"'
+
+def quote_file(file):
+    result = ""
+
+    for i in file.readlines():
+        result = result + quote_line(i) + "\n"
+
+    return result
+
+if len(sys.argv) < 3:
+    print "Usage: inline_file.py output_c_file file_to_include"
+else:
+    output_c_file = sys.argv[1]
+    out_file = open(output_c_file, "w");
+
+    file_to_include = sys.argv[2]
+
+    in_file  = open(file_to_include, "r");
+    variable_name = strip(in_file.readline())    
+    out_file.write("extern const char %s[] = {\n%s};\n\n" % (variable_name, quote_file(in_file)))
+    in_file.close()
+    out_file.close()


Property changes on: boost-jam/boost-build/branches/upstream/current/example/customization/inline_file.py
___________________________________________________________________
Name: svn:executable
   + 

Added: boost-jam/boost-build/branches/upstream/current/example/customization/project-root.jam
===================================================================
--- boost-jam/boost-build/branches/upstream/current/example/customization/project-root.jam	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/example/customization/project-root.jam	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,2 @@
+
+import verbatim ;
\ No newline at end of file

Added: boost-jam/boost-build/branches/upstream/current/example/customization/readme.txt
===================================================================
--- boost-jam/boost-build/branches/upstream/current/example/customization/readme.txt	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/example/customization/readme.txt	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,7 @@
+
+This example show how to add a new target type and a new tool
+support to Boost.Build. Please refer to extender manual for
+complete description of this example.
+
+Note that this example requires Python. If cygwin Python on Windows is
+to be used, please go to "verbatim.jam" and follow instructions there.

Added: boost-jam/boost-build/branches/upstream/current/example/customization/t1.verbatim
===================================================================
--- boost-jam/boost-build/branches/upstream/current/example/customization/t1.verbatim	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/example/customization/t1.verbatim	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,2 @@
+t1
+//###include "t2.verbatim"
\ No newline at end of file

Added: boost-jam/boost-build/branches/upstream/current/example/customization/t2.verbatim
===================================================================

Added: boost-jam/boost-build/branches/upstream/current/example/customization/usage.verbatim
===================================================================
--- boost-jam/boost-build/branches/upstream/current/example/customization/usage.verbatim	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/example/customization/usage.verbatim	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,6 @@
+usage
+Usage: codegen class_name
+
+This program takes a template of C++ code and replaces of
+occurences of %class_name% with the passed 'class_name'
+parameter.
\ No newline at end of file

Added: boost-jam/boost-build/branches/upstream/current/example/customization/verbatim.jam
===================================================================
--- boost-jam/boost-build/branches/upstream/current/example/customization/verbatim.jam	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/example/customization/verbatim.jam	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,53 @@
+#  Copyright (C) Vladimir Prus 2003-2004. Permission to copy, use, modify, sell and
+#  distribute this software is granted provided this copyright notice appears in
+#  all copies. This software is provided "as is" without express or implied
+#  warranty, and with no claim as to its suitability for any purpose.
+
+#
+#  This file shows some of the primary customization mechanisms in Boost.Build V2
+#  and should serve as a basic for your own customization.
+#  Each part has a comment describing its purpose, and you can pick the parts
+#  which are relevant to your case, remove everything else, and then change names
+#  and actions to taste.
+
+#  Declare a new target type. This allows Boost.Build to do something sensible
+#  when targets with the .verbatim extension are found in sources.
+import type ;
+type.register VERBATIM : verbatim ;
+
+#  Declare a dependency scanner for the new target type. The
+#  'inline-file.py' script does not handle includes, so this is
+#  only for illustraction.
+import scanner ;
+#  First, define a new class, derived from 'common-scanner',
+#  that class has all the interesting logic, and we only need
+#  to override the 'pattern' method which return regular
+#  expression to use when scanning.
+class verbatim-scanner : common-scanner 
+{
+    rule pattern ( )
+    {
+        return "//###include[ ]*\"([^\"]*)\"" ;
+    }
+}
+
+# Register the scanner class. The 'include' is
+# the property which specifies the search path
+# for includes.
+scanner.register verbatim-scanner : include ;
+# Assign the scanner class to the target type.
+# Now, all .verbatim sources will be scanned.
+# To test this, build the project, touch the 
+# t2.verbatim file and build again.
+type.set-scanner VERBATIM : verbatim-scanner ;
+
+import generators ;
+generators.register-standard verbatim.inline-file : VERBATIM : CPP ;
+
+# Note: To use Cygwin Python on Windows change the following line
+# to "python inline_file.py $(<) $(>)"
+# Also, make sure that "python" in in PATH.
+actions inline-file 
+{
+    "./inline_file.py" $(<) $(>)
+}
\ No newline at end of file

Added: boost-jam/boost-build/branches/upstream/current/example/gettext/Jamfile
===================================================================
--- boost-jam/boost-build/branches/upstream/current/example/gettext/Jamfile	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/example/gettext/Jamfile	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,22 @@
+
+# Declare a main target.
+exe main : main.cpp ;
+
+# Declare an action for updating translations
+# After changing main.cpp, invocation of
+#
+#   bjam update-russian
+# 
+# will update translations in russian.po
+gettext.update update-russian : russian.po main ;
+
+# Compiled message catalog.
+gettext.catalog russian : russian.po ;
+
+# A stage rule which installs message catalog to the
+# location gettext expects.
+stage messages-russian : russian
+    : <location>messages/ru_RU.KOI8-R/LC_MESSAGES 
+      <name>main
+    ;
+

Added: boost-jam/boost-build/branches/upstream/current/example/gettext/main.cpp
===================================================================
--- boost-jam/boost-build/branches/upstream/current/example/gettext/main.cpp	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/example/gettext/main.cpp	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,28 @@
+// Copyright Vladimir Prus 2003.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt
+// or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+
+#include <locale.h>
+#include <libintl.h>
+#define i18n(s) gettext(s)
+
+#include <iostream>
+using namespace std;
+
+int main()
+{    
+    // Specify that translations are stored in directory
+    // "messages".
+    bindtextdomain("main", "messages");
+    textdomain("main");
+
+    // Switch to russian locale.
+    setlocale(LC_MESSAGES, "ru_RU.KOI8-R");
+
+    // Output localized message.
+    std::cout << i18n("hello") << "\n";
+
+    return 0;
+}

Added: boost-jam/boost-build/branches/upstream/current/example/gettext/project-root.jam
===================================================================
--- boost-jam/boost-build/branches/upstream/current/example/gettext/project-root.jam	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/example/gettext/project-root.jam	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,2 @@
+
+using gettext ;
\ No newline at end of file

Added: boost-jam/boost-build/branches/upstream/current/example/gettext/readme.txt
===================================================================
--- boost-jam/boost-build/branches/upstream/current/example/gettext/readme.txt	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/example/gettext/readme.txt	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,21 @@
+
+This example shows how it's possible to used GNU gettext utilities with
+Boost.Build.
+
+A simple translation file is compiled and installed as message catalog for
+russian. The main application explicitly switches to russian locale and
+output the translation of "hello".
+
+To test:
+
+   bjam
+   bin/gcc/debug/main
+
+To test even more:
+
+   - add more localized strings to "main.cpp"
+   - run "bjam update-russian"
+   - edit "russian.po"
+   - run bjam
+   - run "main"
+

Added: boost-jam/boost-build/branches/upstream/current/example/gettext/russian.po
===================================================================
--- boost-jam/boost-build/branches/upstream/current/example/gettext/russian.po	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/example/gettext/russian.po	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,21 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# FIRST AUTHOR <EMAIL at ADDRESS>, YEAR.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE VERSION\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2003-07-01 15:45+0400\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: FULL NAME <EMAIL at ADDRESS>\n"
+"Language-Team: LANGUAGE <LL at li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=CHARSET\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: main.cpp:16
+msgid "hello"
+msgstr "international hello"

Added: boost-jam/boost-build/branches/upstream/current/example/hello/Jamfile
===================================================================
--- boost-jam/boost-build/branches/upstream/current/example/hello/Jamfile	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/example/hello/Jamfile	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,2 @@
+
+exe hello : hello.cpp ;

Added: boost-jam/boost-build/branches/upstream/current/example/hello/hello.cpp
===================================================================
--- boost-jam/boost-build/branches/upstream/current/example/hello/hello.cpp	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/example/hello/hello.cpp	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,16 @@
+//  Copyright (c) 2003 Vladimir Prus
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  http://www.boost.org
+// 
+
+#include <iostream>
+
+int main()
+{
+    std::cout << "Hello!\n";
+    return 1;
+}

Added: boost-jam/boost-build/branches/upstream/current/example/hello/project-root.jam
===================================================================
--- boost-jam/boost-build/branches/upstream/current/example/hello/project-root.jam	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/example/hello/project-root.jam	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,2 @@
+
+

Added: boost-jam/boost-build/branches/upstream/current/example/libraries/Jamfile
===================================================================
--- boost-jam/boost-build/branches/upstream/current/example/libraries/Jamfile	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/example/libraries/Jamfile	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,2 @@
+
+build-project app ;
\ No newline at end of file

Added: boost-jam/boost-build/branches/upstream/current/example/libraries/app/Jamfile
===================================================================
--- boost-jam/boost-build/branches/upstream/current/example/libraries/app/Jamfile	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/example/libraries/app/Jamfile	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,5 @@
+
+# Declare a executable file, which uses a library. Note that
+# includes that for library will be automatically used
+# when compiling 'app.cpp'
+exe app : app.cpp ../lib1//lib1 ; 
\ No newline at end of file

Added: boost-jam/boost-build/branches/upstream/current/example/libraries/app/app.cpp
===================================================================
--- boost-jam/boost-build/branches/upstream/current/example/libraries/app/app.cpp	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/example/libraries/app/app.cpp	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,15 @@
+//  Copyright (c) 2003 Vladimir Prus
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  http://www.boost.org
+// 
+
+#include <lib1.h>
+
+int main()
+{
+    foo();
+}

Added: boost-jam/boost-build/branches/upstream/current/example/libraries/lib1/Jamfile
===================================================================
--- boost-jam/boost-build/branches/upstream/current/example/libraries/lib1/Jamfile	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/example/libraries/lib1/Jamfile	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,5 @@
+
+project lib1
+    : usage-requirements <include>include ;
+
+lib lib1 : lib1.cpp ;
\ No newline at end of file

Added: boost-jam/boost-build/branches/upstream/current/example/libraries/lib1/include/lib1.h
===================================================================
--- boost-jam/boost-build/branches/upstream/current/example/libraries/lib1/include/lib1.h	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/example/libraries/lib1/include/lib1.h	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,10 @@
+//  Copyright (c) 2003 Vladimir Prus
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  http://www.boost.org
+// 
+
+void foo();

Added: boost-jam/boost-build/branches/upstream/current/example/libraries/lib1/lib1.cpp
===================================================================
--- boost-jam/boost-build/branches/upstream/current/example/libraries/lib1/lib1.cpp	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/example/libraries/lib1/lib1.cpp	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,13 @@
+//  Copyright (c) 2003 Vladimir Prus
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  http://www.boost.org
+// 
+
+#ifdef _WIN32
+__declspec(dllexport)
+#endif
+void foo() {};

Added: boost-jam/boost-build/branches/upstream/current/example/libraries/project-root.jam
===================================================================

Added: boost-jam/boost-build/branches/upstream/current/example/qt/Jamfile
===================================================================
--- boost-jam/boost-build/branches/upstream/current/example/qt/Jamfile	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/example/qt/Jamfile	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,11 @@
+# Copyright Vladimir Prus 2004.
+# Distributed under the Boost Software License, Version 1.0.
+# (See accompanying file LICENSE_1_0.txt
+# or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+project
+    # built MT version, unless asked otherwise.
+    : default-build <threading>multi 
+    ;
+
+exe canvas : main.cpp canvas.cpp canvas.h : <library>/qt//qt ;
\ No newline at end of file

Added: boost-jam/boost-build/branches/upstream/current/example/qt/canvas.cpp
===================================================================
--- boost-jam/boost-build/branches/upstream/current/example/qt/canvas.cpp	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/example/qt/canvas.cpp	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,73 @@
+// Copyright Vladimir Prus 2004.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt
+// or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include "canvas.h"
+
+#include <qlabel.h>
+#include <qcanvas.h>
+#include <qlayout.h>
+
+Canvas::Canvas(QWidget* parent)
+: QWidget(parent)
+{
+    m_pen = QPen(QColor(255, 128, 128));
+    m_brushes = new QBrush[2];
+    m_brushes[0] = QBrush(QColor(255, 0, 0));
+    m_brushes[1] = QBrush(QColor(0, 255, 0));
+    m_current_brush = 0;
+    
+    m_canvas = new QCanvas(this);
+    m_canvas->resize(4*1600, 600);
+    
+    redraw();   
+    
+    QVBoxLayout* l = new QVBoxLayout(this); 
+    
+    m_canvas_view = new QCanvasView(m_canvas, this);
+    l->addWidget(m_canvas_view);    
+    m_canvas_view->resize(rect().size());
+    m_canvas_view->show();    
+}
+
+Canvas::~Canvas()
+{
+    delete m_brushes;
+}
+
+void Canvas::redraw()
+{
+    QCanvasItemList l = m_canvas->allItems();    
+    for(QCanvasItemList::iterator i = l.begin(),
+            e = l.end(); i != e; ++i)
+    {
+        delete *i;
+    }
+    
+    unsigned count = 0;
+    for (unsigned x = 10; x < 4*1600; x += 20)
+        for (unsigned y = 10; y < 600; y += 20) {
+            QCanvasRectangle* r = new QCanvasRectangle(x, y, 10, 10, m_canvas);
+            r->setPen(m_pen);
+            r->setBrush(m_brushes[m_current_brush]);
+            r->show();  
+            ++count;  
+            QCanvasText* t = new QCanvasText("D", m_canvas);
+            t->move(x, y);
+            t->show();
+            ++count;
+        }
+    
+    (new QCanvasText(QString::number(count), m_canvas))->show();
+    m_canvas->setAllChanged();
+
+}
+
+void Canvas::change_color()
+{
+    m_current_brush = (m_current_brush + 1)%2;
+    redraw();
+    m_canvas->update();
+}
+

Added: boost-jam/boost-build/branches/upstream/current/example/qt/canvas.h
===================================================================
--- boost-jam/boost-build/branches/upstream/current/example/qt/canvas.h	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/example/qt/canvas.h	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,35 @@
+// Copyright Vladimir Prus 2004.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt
+// or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+
+#ifndef CANVAS_VP_2004_08_31
+#define CANVAS_VP_2004_08_31
+
+#include <qmainwindow.h>
+#include <qpen.h>
+#include <qbrush.h>
+
+class Canvas : public QWidget
+{
+    Q_OBJECT
+public:
+    Canvas(QWidget* parent);
+
+    virtual ~Canvas();
+    
+public slots:
+    void change_color();    
+    
+private:
+    void redraw();
+    class QCanvas* m_canvas;
+    class QCanvasView* m_canvas_view;
+    class QPen m_pen;
+    class QBrush* m_brushes;    
+    int m_current_brush;
+};
+
+#endif
+

Added: boost-jam/boost-build/branches/upstream/current/example/qt/main.cpp
===================================================================
--- boost-jam/boost-build/branches/upstream/current/example/qt/main.cpp	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/example/qt/main.cpp	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,36 @@
+// Copyright Vladimir Prus 2004.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt
+// or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include "canvas.h"
+#include <qapplication.h>
+#include <qvbox.h>
+#include <qpushbutton.h>
+
+class Window : public QMainWindow
+{
+public:
+    Window()
+    {
+        setCaption("QCanvas test");
+        QVBox* vb = new QVBox(this);
+        setCentralWidget(vb);   
+    
+        Canvas* c = new Canvas(vb); 
+        QPushButton* b = new QPushButton("Change color", vb);
+        connect(b, SIGNAL(clicked()), c, SLOT(change_color())); 
+    }        
+};
+
+int main(int argc, char **argv)
+{
+    QApplication app(argc, argv);
+    Window *w = new Window();
+
+    app.setMainWidget(w);
+    w->show();
+    
+    return app.exec();
+}
+

Added: boost-jam/boost-build/branches/upstream/current/example/qt/project-root.jam
===================================================================
--- boost-jam/boost-build/branches/upstream/current/example/qt/project-root.jam	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/example/qt/project-root.jam	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,9 @@
+
+import toolset ;
+
+# Tell that QT should be used. QTDIR will give installation
+# prefix. 
+toolset.using qt ;
+
+#Alternatively, the prefix can be given as second argument
+#toolset.using qt : /usr/share/qt ;
\ No newline at end of file

Added: boost-jam/boost-build/branches/upstream/current/example/qt-ui/Jamfile
===================================================================
--- boost-jam/boost-build/branches/upstream/current/example/qt-ui/Jamfile	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/example/qt-ui/Jamfile	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,10 @@
+# Copyright Felix E. Klee, 2003
+# Distributed under the Boost Software License, Version 1.0.
+# (See accompanying file LICENSE_1_0.txt
+# or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+project
+    : default-build <threading>multi
+    ;
+
+exe hello : main.cpp hello_world_widget.ui : <library>/qt//qt ;

Added: boost-jam/boost-build/branches/upstream/current/example/qt-ui/hello_world_widget.ui
===================================================================
--- boost-jam/boost-build/branches/upstream/current/example/qt-ui/hello_world_widget.ui	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/example/qt-ui/hello_world_widget.ui	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,58 @@
+<!DOCTYPE UI><UI version="3.0" stdsetdef="1">
+<class>HelloWorldWidget</class>
+<comment>
+<!--
+    Copyright Felix E. Klee, 2003
+    Distributed under the Boost Software License, Version 1.0.
+    (See accompanying file LICENSE_1_0.txt
+    or copy at http://www.boost.org/LICENSE_1_0.txt)
+-->
+</comment>
+<widget class="QWidget">
+    <property name="name">
+        <cstring>HelloWorldWidget</cstring>
+    </property>
+    <property name="geometry">
+        <rect>
+            <x>0</x>
+            <y>0</y>
+            <width>124</width>
+            <height>63</height>
+        </rect>
+    </property>
+    <property name="caption">
+        <string>Hello World!</string>
+    </property>
+    <vbox>
+        <property name="name">
+            <cstring>unnamed</cstring>
+        </property>
+        <property name="margin">
+            <number>11</number>
+        </property>
+        <property name="spacing">
+            <number>6</number>
+        </property>
+        <widget class="QLabel">
+            <property name="name">
+                <cstring>TextLabel2</cstring>
+            </property>
+            <property name="text">
+                <string>Hello World!</string>
+            </property>
+            <property name="alignment">
+                <set>AlignCenter</set>
+            </property>
+        </widget>
+        <widget class="QPushButton">
+            <property name="name">
+                <cstring>OkButton</cstring>
+            </property>
+            <property name="text">
+                <string>OK</string>
+            </property>
+        </widget>
+    </vbox>
+</widget>
+<layoutdefaults spacing="6" margin="11"/>
+</UI>

Added: boost-jam/boost-build/branches/upstream/current/example/qt-ui/main.cpp
===================================================================
--- boost-jam/boost-build/branches/upstream/current/example/qt-ui/main.cpp	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/example/qt-ui/main.cpp	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,18 @@
+// Copyright Felix E. Klee, 2003
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt
+// or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include "hello_world_widget.h"
+#include <qapplication.h>
+
+#include <qpushbutton.h>
+
+int main(int argc, char **argv) {
+    QApplication a(argc, argv);
+    HelloWorldWidget w;
+    QObject::connect(static_cast<QObject*>(w.OkButton), SIGNAL(clicked()), &w, SLOT(close()));
+    a.setMainWidget(&w);
+    w.show();
+    return a.exec();
+}

Added: boost-jam/boost-build/branches/upstream/current/example/qt-ui/project-root.jam
===================================================================
--- boost-jam/boost-build/branches/upstream/current/example/qt-ui/project-root.jam	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/example/qt-ui/project-root.jam	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,11 @@
+# Copyright Felix E. Klee, 2003
+# Distributed under the Boost Software License, Version 1.0.
+# (See accompanying file LICENSE_1_0.txt
+# or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+import gcc ;
+import toolset ;
+
+# Tell that QT should be used. QTDIR will give installation
+# prefix. 
+toolset.using qt ;

Added: boost-jam/boost-build/branches/upstream/current/example/variant/Jamfile
===================================================================
--- boost-jam/boost-build/branches/upstream/current/example/variant/Jamfile	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/example/variant/Jamfile	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,9 @@
+
+# By default, build the project with two variants
+# we've defined in project-root.jam
+project
+    : default-build crazy super_release
+    ;
+
+exe a : a.cpp libs//l ;
+

Added: boost-jam/boost-build/branches/upstream/current/example/variant/a.cpp
===================================================================
--- boost-jam/boost-build/branches/upstream/current/example/variant/a.cpp	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/example/variant/a.cpp	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,7 @@
+// Copyright Vladimir Prus 2004.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt
+// or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+void l();
+int main() { l(); return 0; }

Added: boost-jam/boost-build/branches/upstream/current/example/variant/libs/Jamfile
===================================================================
--- boost-jam/boost-build/branches/upstream/current/example/variant/libs/Jamfile	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/example/variant/libs/Jamfile	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,2 @@
+
+lib l : l.cpp ;
\ No newline at end of file

Added: boost-jam/boost-build/branches/upstream/current/example/variant/libs/l.cpp
===================================================================
--- boost-jam/boost-build/branches/upstream/current/example/variant/libs/l.cpp	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/example/variant/libs/l.cpp	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,9 @@
+// Copyright Vladimir Prus 2002-2004.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt
+// or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#ifdef _WIN32
+__declspec(dllexport)
+#endif
+void l() {}

Added: boost-jam/boost-build/branches/upstream/current/example/variant/project-root.jam
===================================================================
--- boost-jam/boost-build/branches/upstream/current/example/variant/project-root.jam	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/example/variant/project-root.jam	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,10 @@
+
+# Define a build variant which is just combination
+# of four properties. 
+variant crazy : <optimization>speed <inlining>off 
+                <debug-symbols>on <profiling>on ;
+		
+# Define a built variant inherited from 'release'.
+# It defines one new property and get all properties
+# from parent variant.		
+variant super_release : release : <define>USE_ASM ;
\ No newline at end of file

Added: boost-jam/boost-build/branches/upstream/current/example/variant/readme.txt
===================================================================
--- boost-jam/boost-build/branches/upstream/current/example/variant/readme.txt	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/example/variant/readme.txt	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,7 @@
+
+This example shows how user can create his own build variants.
+Two variants are defined: "crazy", which is just random combination
+of properties, and "super-release", which is inherited from "release",
+and differs by a single define.
+
+See the project-root.jam for the definitions.
\ No newline at end of file

Added: boost-jam/boost-build/branches/upstream/current/hacking.txt
===================================================================
--- boost-jam/boost-build/branches/upstream/current/hacking.txt	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/hacking.txt	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,153 @@
+
+             ----------------------------------
+             Boost.Build contributor guidelines
+             ----------------------------------
+
+Boost.Build is an open-source project. This means that we welcome and
+appreciate all contributions --- be it ideas, bug reports, or patches.
+This document contains guidelines which helps to assure that development
+goes on smoothly, and changes are made quickly. 
+
+The guidelines are not mandatory, and you can decide for yourself which one 
+to follow. But note, that 10 mins that you spare writing a comment, for
+example, might lead to significally longer delay for everyone.
+
+Before contributing, make sure you are subscribed to our mailing list
+
+   jamboost at yahoogroups.com
+
+Additional resources include
+
+   - brief issues list
+     http://www.crystalclearsoftware.com/cgi-bin/boost_wiki/wiki.pl?Boost.Build/Issues
+     
+   - the issue tracker
+     http://zigzag.cs.msu.su:7814
+
+   - commits mailing list: 
+     boost-build at lists.sourceforge.net
+     http://sourceforge.net/mailarchive/forum.php?forum_id=9097
+
+
+BUGS and PATCHES
+
+Both bugs and patches can be send to our mailing list.
+
+When reporting a bug, please try to provide the following information.
+
+   - What you did. A minimal reproducible testcase is very much appreciated.
+     Shell script with some annotations is much better than verbose description of
+     the problem. A regression test is the best (see test/test_system.html).
+   - What you got.
+   - What you expected.
+   - What version of Boost.Build and Boost.Jam did you use. If possible,
+     please try to test with the CVS HEAD state.
+
+When submitting a patch, please:
+
+  - make a single patch for a single logical change
+  - follow the policies and coding conventions below,
+  - send patches in unified diff format,
+    (using either "cvs diff -u" or "diff -u")
+  - provide a log message together with the patch
+  - put the patch and the log message as attachment to your email.
+
+The purpose of log message serves to communicate what was changed, and
+*why*. Without a good log message, you might spend a lot of time later,
+wondering where a strange piece of code came from and why it was necessary.
+
+The good log message mentions each changed file and each rule/method, saying
+what happend to it, and why. Consider, the following log message
+
+    Better direct request handling.
+     
+     * new/build-request.jam
+       (directly-requested-properties-adjuster): Redo.
+       
+     * new/targets.jam
+       (main-target.generate-really): Adjust properties here.
+     
+     * new/virtual-target.jam
+       (register-actual-name): New rule.
+       (virtual-target.actualize-no-scanner): Call the above, to detected bugs,
+       where two virtual target correspond to one Jam target name.
+ 
+The log messages for the last two files are good. They tell what was
+changed. The change to the first file is clearly undercommented.
+
+It's OK to use terse log messages for uninteresting changes, like
+ones induces by interface changes elsewhere. 
+
+
+POLICIES.
+
+1. Testing.
+
+All serious changes must be tested. New rules must be tested by the module
+where they are declared. Test system (test/test_system.html) should be used
+to verify user-observable behaviour.
+
+2. Documentation.
+
+It turns out that it's hard to have too much comments, but it's easy to have
+too little. Please predend each rule with a comment saying what the rule does
+and what arguments means. Stop for a minute and consider if the comment makes
+sense for anybody else, and completely describes what the rules does. Generic
+phrases like "adjusts properties" are really not enough.
+
+When applicable, make changes to the user documentation as well.
+
+
+CODING CONVENTIONS.
+
+    1. All names of rules and variables are lowercase with "-" to separate
+    words.
+
+        rule call-me-ishmael ( ) ...
+
+    2. Names with dots in them are "intended globals". Ordinary globals use
+    a dot prefix:
+
+        .foobar
+        $(.foobar)
+
+    3. Pseudofunctions or associations are <parameter>.<property>:
+
+        $(argument).name = hello ;
+        $($(argument).name)
+
+    4. Class attribute names are prefixed with "self.":
+
+        self.x
+        $(self.x)
+
+    5. Builtin rules are called via their ALL_UPPERCASE_NAMES:
+
+        DEPENDS $(target) : $(sources) ;
+
+    6. Opening and closing braces go on separate lines:
+
+        if $(a)
+        {
+            #
+        }
+        else
+        {
+            #
+        }
+
+HTML DOCUMENTATION.
+
+    Please pass HTML files though HTML Tidy (http://tidy.sf.net) before
+    comitting. This has to important purposes:
+    - detecting bad HTML
+    - converting files to uniform indentation style, which inverses effect
+      of different editors and makes differences between revisions much
+      smaller and easy for review.
+
+    Alas, the way Tidy indents HTML differs between version. Please use
+    the version awailable at
+
+       http://tidy.sourceforge.net/src/old/tidy_src_020411.tgz
+
+    and "-i -wrap 78" command line parameters.

Added: boost-jam/boost-build/branches/upstream/current/index.html
===================================================================
--- boost-jam/boost-build/branches/upstream/current/index.html	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/index.html	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,164 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+
+<html>
+  <head>
+    <meta name="generator" content=
+    "HTML Tidy for Linux/x86 (vers 1st April 2002), see www.w3.org">
+    <meta name="generator" content="Microsoft FrontPage 5.0">
+    <meta http-equiv="Content-Type" content=
+    "text/html; charset=windows-1252">
+    <!-- tidy options: &dash;&dash;tidy-mark false -i -wrap 78 !-->
+<style type="text/css">
+div.sidebar {
+  margin-left: 1em ;
+  border: medium outset ;
+  padding: 0em 1em ;
+  background-color: #ffffee ;
+  width: 40% ;
+  float: right ;
+  clear: right }
+
+div.sidebar p.rubric {
+  font-family: sans-serif ;
+  font-size: medium }
+</style>
+
+    <title>Boost Build System V2</title>
+  </head>
+
+  <body bgcolor="#FFFFFF" text="#000000">
+    <img src="boost.png" alt="boost.png (6897 bytes)" align="center"
+    width="277" height="86"> <!-- sf logo -->
+
+
+    <div class="contents sidebar topic" id="index">
+      <p>
+        <b>Quick access</b>
+        <ul>
+        <li>Download: <a href=
+    "http://prdownloads.sourceforge.net/boost/boost-build-2.0-m10.zip">[zip]
+          </a>, <a href=
+    "http://prdownloads.sourceforge.net/boost/boost-build-2.0-m10.tar.bz2">[tar.bz2]
+          </a>
+        <li>Nightly build: <a href="http://boost.org/boost-build2/boost-build.zip">[zip]</a>, 
+          <a href="http://boost.org/boost-build2/boost-build.tar.bz2">[tar.bz2]</a>
+        <li><a href="doc/html/index.html">Documentation</a> 
+          (<a href="userman.pdf">PDF</a>)
+        <li><a
+          href="http://www.crystalclearsoftware.com/cgi-bin/boost_wiki/wiki.pl?Boost.Build_V2">Wiki
+          (User-contibuted documentation)</a>
+        <li>Feedback: <a
+    href="http://groups.yahoo.com/group/jamboost/">[mailing list]</a>,
+          <a
+            href="news://news.gmane.org/gmane.comp.lib.boost.build">[newsgroup]</a>
+          <ul>
+            <li>Before posting, <a href="mailto:jamboost-subscribe at yahoogroups.com">subscribe</a>
+          </ul>
+<!--        <li>Rate Boost.Build: <a href="http://freshmeat.net/rate/38012/">Freshmeat</a>    -->
+      </ul>
+    </p>
+   </div>
+     
+
+    <h1>Boost Build System V2</h1>
+
+
+    <h2><a name="synopsis">Synopsis</a></h2>
+
+    <p>Boost.Build is a system for large project software construction, which
+    is simple to use and powerfull. Boost.Build V2 is an onging project to
+    rewrite Boost.Build, improving design and making it more extensible. The
+    distinguishing features are:</p>
+
+    <ul>
+      <li><b>Simple and high level target description language</b>. In most
+      cases name of target and list of sources is enough.</li>
+
+      <li><b>Variant builds</b>. You can build with your choice of basic
+      variants (e.g. debug, release, profile...), toolsets (e.g. gcc and
+      msvc) and specific properties (e.g. inlining off) from a single command
+      invocation.</li>
+
+      <li><b>Portability</b>. ``Feature Normalization'' allows to fine-tune
+      targets independently from the toolset used, and modular toolset
+      descriptions are employed to generate actual build instructions.</li>
+
+      <li><b>Multi-project builds</b>. Several projects can be combined and
+      built together, with dependencies correctly tracked. Typically, the
+      setting (like include paths and defines) needed to use other project
+      will be handled automatically.</li>
+
+      <li><b>Extensibility</b>. New file types and tools can be easily
+      added</li>
+    </ul>
+
+    <h2>Documentation</h2>
+
+    <p>The user manual, which includes installation instructions, tuturial
+    and initial reference is available <a href=
+    "doc/html/index.html">here</a>.</p>
+
+    <h2><a name="status">Status</a></h2>
+
+<!--    
+    <p><font size=4 color=blue>Boost.Build V2 is project in development, and for building
+    C++ Boost you should use V1, see the 
+    <a href="http://boost.org/more/getting_started.html">instructions</a>.
+        </font></p>
+-->
+   
+    <p>Enough of the core functionality is implemented to allow practical use
+    on medium-size projects. Several compilers and tools are supported, the
+    full list is available <a href="doc/tools.html">here</a>. 
+    The list of features
+    still to be implemented is outlined in the <a href=
+    "doc/development_plan.html">develepment plan</a>.</p>
+
+    <h2 id="download">Downloading</h2>
+
+    <p>The most up-to-date sources are available in <tt>tools/build</tt>
+    directory of Boost CVS. Please use "Boost CVS Repository" section in the
+    <a href="http://www.boost.org/more/download.html">download
+    instructions</a>.</p>
+
+    <p>Boost.Build releases are also available. There's <a href=
+    "http://prdownloads.sourceforge.net/boost/boost-build-2.0-m9.1.zip">zip
+    archive</a>, and <a href=
+    "http://prdownloads.sourceforge.net/boost/boost-build-2.0-m9.1.tar.bz2">tar.bz2
+    archive</a> of the current release. Older releases are available from the
+    <a href=
+    "http://sourceforge.net/project/showfiles.php?group_id=7586">SourceForce
+    download page</a>.</p>
+
+    <p>The installation is described in the
+    <a href="doc/html/bbv2.installation.html">user
+    manual</a>.</p>
+
+    <h2>Feedback</h2>
+
+    <p>Should you have any questions or comments, we'd be glad to hear them.
+    Post everything to the <a href=
+    "http://groups.yahoo.com/group/jamboost">jamboost</a> mailing list.</p>
+
+    <p>We have an online tracker for all Boost.Build bugs and features. Usage
+    instructions are available <a href="doc/tracker.html">here</a>.</p>
+
+    <p>If you'd like to help with development, there's a separate <a href=
+    "hacking.txt">guidelines document</a>.</p>
+    <hr>
+
+    <p>&copy; Copyright David Abrahams and Vladimir Prus 2002-2003.
+    Permission to copy, use, modify, sell and distribute this document is
+    granted provided this copyright notice appears in all copies. This
+    document is provided "as is" without express or implied warranty, and
+    with no claim as to its suitability for any purpose.</p>
+
+    <p>Revised 
+    <!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %B, %Y" startspan
+                                            -->Oct 29, 2004 
+    <!--webbot bot="Timestamp" endspan i-checksum="13972"
+                                            -->
+    </p>
+  </body>
+</html>
+

Added: boost-jam/boost-build/branches/upstream/current/jam_src/Jam.html
===================================================================
--- boost-jam/boost-build/branches/upstream/current/jam_src/Jam.html	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/jam_src/Jam.html	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,1356 @@
+<HTML>
+
+<TITLE> Jam/MR - Make(1) Redux </TITLE>
+
+<BODY>
+
+<CENTER>
+
+<H1> Jam/MR - Make(1) Redux </H1>
+
+<P> The <a href=http://www.perforce.com/jam/jam.html>Jam/MR</a> Executable
+
+</CENTER>
+
+<DL>
+
+<DT> <P> <H2> USAGE </H2> <DD>
+
+<PRE>
+jam [ -a ] [ -n ] [ -v ] [ -q ]
+    [ -d <I>debug</I> ] 
+    [ -f <I>jambase</I> ] 
+    [ -j <I>jobs</I> ] 
+    [ -o <I>actionsfile</I> ] 
+    [ -s <I>var</I>=<I>value</I> ] 
+    [ -t <I>target</I> ] 
+    [ <I>target</I> ... ]
+</PRE>
+
+<DT> <P> <H2> DESCRIPTION </H2> <DD>
+
+	<P>
+
+	<B>Jam</B> is a program construction tool, like <B>make</B>(1).
+
+	<P>
+
+	<B>Jam</B> recursively builds target files from source files,
+	using dependency information and updating actions expressed in
+	the Jambase file, which is written in <B>jam</B>'s own interpreted
+	language.  The default Jambase is compiled into <B>jam</B> and
+	provides a boilerplate for common use, relying on a user-provide
+	file "Jamfile" to enumerate actual targets and sources.
+
+	<P>
+
+	The Jambase is described in the <a href="Jambase.html">Jambase
+	Reference</a> and the document <a href="Jamfile.html">Using
+	Jamfiles and Jambase</A>.
+
+<DT> <P> <H2> OPTIONS </H2> <DD>
+
+	<P>
+
+	If <I>target</I> is provided on the command line, <B>jam</B>
+	builds <I>target;</I> otherwise <B>jam</B> builds the target
+	'all'.
+
+	<P>
+
+	<B>Jam</b> may be invoked with the following options:
+
+	<P> <TABLE WIDTH=75% ALIGN=CENTER>
+
+	    <TR><TD VALIGN=TOP><CODE> -a </CODE>
+	    <TD> Build all targets anyway, even if they are up-to-date.
+
+	    <TR><TD VALIGN=TOP><CODE> -d <I>n</I>  </CODE>
+	    <TD> Enable cummulative debugging levels from 1 to <I>n</I>.  
+	    Interesting values are:
+
+	    <DL COMPACT>
+	    <DT> 1 <DD> Show actions (the default) 
+	    <DT> 2 <DD> Show "quiet" actions and display all action text 
+	    <DT> 3 <DD> Show dependency analysis, and target/source 
+		    timestamps/paths  
+	    <DT> 4 <DD> Show shell arguments 
+	    <DT> 5 <DD> Show rule invocations and variable expansions 
+	    <DT> 6 <DD> Show directory/header file/archive scans 
+	    <DT> 7 <DD> Show variable settings 
+	    <DT> 8 <DD> Show variable fetches 
+	    <DT> 9 <DD> Show variable manipulation, scanner tokens 
+	    </DL>
+
+	    <TR><TD VALIGN=TOP><CODE> -d +<I>n</I> </CODE>
+	    <TD> Enable debugging level <I>n</I>.
+
+	    <TR><TD VALIGN=TOP><CODE> -d 0 </CODE>
+	    <TD> Turn off all debugging levels.  Only errors are not suppressed.
+
+	    <TR><TD VALIGN=TOP><CODE> -f <I>jambase</I></CODE>
+	    <TD>Read <I>jambase</I> instead of using the built-in Jambase.
+	    Only one -f flag is permitted, but the <i>jambase</i> may 
+	    explicitly include other files.
+
+	    <TR><TD VALIGN=TOP><CODE> -j <I>n</I></CODE>
+	    <TD> Run up to <I>n</I> shell commands concurrently (UNIX 
+	    and NT only).  The default is 1.
+
+	    <TR><TD VALIGN=TOP><CODE> -n</CODE>
+	    <TD> Don't actually execute the updating actions, but do
+	    everything else.  This changes the debug level default to -d2.
+
+	    <TR><TD VALIGN=TOP><CODE> -o <I>file</I></CODE>
+	    <TD> Write the updating actions to the specified file instead
+	    of running them (or outputting them, as on the Mac).
+
+	    <TR><TD VALIGN=TOP><CODE> -q </CODE>
+	    <TD> Quit quickly (as if an interrupt was received)
+	    as soon as any target fails.
+
+	    <TR><TD VALIGN=TOP><CODE> -s <I>var</I>=<I>value</I></CODE>
+	    <TD> Set the variable <I>var</I> to <I>value</I>, overriding
+	    both internal variables and variables imported from the
+	    environment.
+
+	    <TR><TD VALIGN=TOP><CODE> -t <I>target</I></CODE>
+	    <TD> Rebuild <I>target</I> and everything that depends on it, 
+	     even if it is up-to-date.
+
+	    <TR><TD VALIGN=TOP><CODE> -v</CODE>
+	    <TD> Print the version of <B>jam</B> and exit.
+
+	</TABLE>
+
+<DT> <P> <H2> OPERATION </H2> <DD>
+
+	<P>
+
+	<b>Jam</b> has four phases of operation: start-up, parsing, 
+	binding, and updating.
+
+<DT> <P> <H3> Start-up </H3> <DD>
+
+	<P>
+
+	Upon start-up, <b>jam</b> imports environment variable settings
+	into <b>jam</b> variables.  Environment variables are split at
+	blanks with each word becoming an element in the variable's list
+	of values.  Environment variables whose names end in PATH are
+	split at $(SPLITPATH) characters (e.g., ":" for Unix).
+
+	<P>
+
+	To set a variable's value on the command line, overriding the
+	variable's environment value, use the -s option.  To see variable
+	assignments made during <b>jam</b>'s execution, use the -d+7
+	option.
+
+<DT> <P> <H3> Parsing </H3> <DD>
+
+	<P>
+
+	In the parsing phase, <b>jam</b> reads and parses the Jambase
+	file, by default the built-in one.  It is written in the <b>jam</b>
+	language.  See <a href="#language"> Language</a> below.  The
+	last action of the Jambase is to read (via the "include" rule)
+	a user-provided file called "Jamfile".
+
+	<P>
+
+	Collectively, the purpose of the Jambase and the Jamfile is to
+	name built target and source files, construct the dependency
+	graph among them, and associate build actions with targets.
+	The Jambase defines boilerplate rules and variable assignments,
+	and the Jamfile uses these to specify the actual relationship
+	among the target and source files.  See the <a
+	href="Jambase.html">Jambase Reference</a> and the document <a
+	href="Jamfile.html">Using Jamfiles and Jambase</A> for information.
+
+<A NAME="binding">
+<DT> <P> <H3> Binding </H3> <DD>
+</A>
+
+	<P>
+
+	<P> <H5> Binding </H5>
+
+	After parsing, <B>jam</B> recursively descends the dependency
+	graph and binds every file target with a location in the
+	filesystem.  If <B>jam</B> detects a circular dependency in the
+	graph, it issues a warning.
+
+	<P>
+
+	File target names are given as absolute or relative path names
+	in the filesystem.  If the path name is absolute, it is bound
+	as is.  If the path name is relative, it is normally bound as
+	is, and thus relative to the current directory.  This can be
+	modified by the settings of the $(SEARCH) and $(LOCATE) variables,
+	which enable <b>jam</b> to find and build targets spread across
+	a directory tree.  See <A HREF="#search">SEARCH and LOCATE
+	Variables</a> below.
+
+	<P> <H5> Update Determination </H5>
+
+	After binding each target, <B>jam</B> determines whether the
+	target needs updating, and if so marks the target for the updating
+	phase.  A target is normally so marked if it is missing, it is
+	older than any of its sources, or any of its sources are marked
+	for updating.  This behavior can be modified by the application
+	of special built-in rules, ALWAYS, LEAVES, NOCARE, NOTFILE,
+	NOUPDATE, and TEMPORARY.  See <A HREF="#bindingmods">Modifying
+	Binding</A> below.
+
+	<P> <H5> Header File Scanning </H5>
+
+	<P>
+
+	During the binding phase, <b>jam</b> also performs header file
+	scanning, where it looks inside source files for the implicit
+	dependencies on other files caused by C's #include syntax.  This
+	is controlled by the special variables $(HDRSCAN) and $(HDRRULE).
+	The result of the scan is formed into a rule invocation, with
+	the scanned file as the target and the found included file names
+	as the sources.  Note that this is the only case where rules
+	are invoked outside the parsing phase.  See <A
+	HREF="#hdrscan">HDRSCAN and HDRRULE Variables</A> below.
+
+<DT> <P> <H3> Updating </H3> <DD>
+
+	<P>
+
+	After binding, <B>jam</B> again recursively descends the dependency
+	graph,  this time executing the update actions for each target
+	marked for update during the binding phase.  If a  target's
+	updating actions fail, then all other targets which depend on
+	that target are skipped.
+
+	<P>
+
+	The -j flag instructs <B>jam</B> to build more than one target
+	at a time.  If there are multiple actions on a single target,
+	they are run sequentially.  
+
+<A NAME="language">
+<DT> <P> <H2> LANGUAGE </H2> <DD>
+</A>
+
+<DT> <P> <H3> Overview </H3> <DD>
+
+	<B>Jam</b> has an interpreted, procedural language.  Statements
+	in <b>jam</b> are rule (procedure) definitions, rule invocations,
+	flow-of-control structures, variable assignments, and sundry
+	language support.
+
+<DT> <P> <H3> Lexical Features </H3> <DD>
+
+	<P>
+
+	<B>Jam</b> treats its input files as whitespace-separated tokens,
+	with two exceptions: double quotes (") can enclose whitespace
+	to embed it into a token, and everything between the matching
+	curly braces ({}) in the definition of a  rule action is treated
+	as a single string.  A backslash (\) can escape a double quote,
+	or any single whitespace character.
+
+	<P>
+
+	<B>Jam</b> requires whitespace (blanks, tabs, or newlines) to
+	surround all tokens, <i>including the colon (:) and semicolon
+	(;) tokens</i>.
+
+	<P>
+
+	<B>Jam</b> keywords (an mentioned in this document) are reserved
+	and generally must be quoted with double quotes (") to be used
+	as arbitrary tokens, such as variable or target names.
+
+<DT> <P> <H3> Targets </H3> <DD>
+
+	<P>
+
+	The essential <b>jam</b> data entity is a target.  Built targets
+	are files to be updated.  Source targets are the files used in
+	updating built targets.  Built targets and source targets are
+	collectively referred to as file targets, and frequently built
+	targets are source targets for other built targets.  Pseudotargets
+	are symbols which represent dependencies on other targets, but
+	which are not themselves associated with any real file.
+
+	<P>
+
+	A file target's identifier is generally the file's name, which
+	can be absolutely rooted, relative to the directory of <b>jam</b>'s
+	invocation, or simply local (no directory).  Most often it is
+	the last case, and the actual file path is bound using the
+	$(SEARCH) and $(LOCATE) special variables.  See <A HREF="#search">
+	SEARCH and LOCATE Variables</A> below.  A local filename is
+	optionally qualified with grist, a string value used to assure
+	uniqueness.  A file target with an identifier of the form
+	<I>file(member)</I> is a library member (usually an ar(1) archive
+	on UNIX).
+
+<DT> <P> <H3> Rules </H3> <DD>
+
+	<P>
+
+	The basic <B>jam</b> language entity is called a rule.  A rule
+	is defined in two parts: the procedure and the actions.  The
+	procedure is a body of <b>jam</b> statements to be run when the
+	rule is invoked; the actions are the OS shell commands to execute
+	when updating the built targets of the rule.
+
+	<P>
+
+	Rules can return values, which can be expanded into a list with
+        "[ <i>rule</i> <i>args</i> ... ]". A rule's value is the value
+	of its last statement, though only the following statements
+	have values: 'if' (value of the leg chosen), 'switch' (value of the case
+	chosen), set (value of the resulting variable), and 'return' (value
+        of its arguments). Note that 'return' doesn't actually cause a
+        return, i.e., is a no-op unless it is the last statement
+        of the last block executed within rule body.
+
+	<P>
+
+	The <b>jam</b> statements for defining and invoking rules are
+	as follows:
+
+	<P><TABLE WIDTH=75% ALIGN=CENTER><TR><TD><DL>
+
+	    <P> <DT> <CODE>
+	    rule <I>rulename</I> { <I>statements</I> }
+	    </CODE>
+
+	    <DD> Define a rule's procedure, replacing any previous
+	    definition.
+
+	    <P> <DT> <CODE>
+	    actions [ <I>modifiers</I> ] <I>rulename</I> { <I>commands</I> }
+	    </CODE>
+
+	    <DD> Define a rule's updating actions, replacing any
+	    previous definition.
+
+	    <P> <DT> <CODE>
+	    <I>rulename field1</I> : <I>field2</I> : <I>...</I> 
+	    : <I>fieldN</I> ;
+	    </CODE>
+
+	    <DD> Invoke a rule.
+
+	    <P> <DT> <CODE>
+	    on <I>target</I> <I>rulename field1</I> : <I>field2</I> : <I>...</I> 
+	    : <I>fieldN</I> ;
+	    </CODE>
+
+	    <DD> Invoke a rule under the influence of <I>target</I>'s specific
+            variables..
+
+	    <P> <DT> <CODE>
+	    [ <I>rulename field1</I> : <I>field2</I> : <I>...</I>
+            : <I>fieldN</I> ] <br>
+	    [  on <I>target</I> <I>rulename field1</I> : <I>field2</I> : <I>...</I>
+            : <I>fieldN</I> ] <br>
+
+	    </CODE>
+
+	    <DD> Used as an argument, expands to the return value of the rule invoked.
+
+	</DL></TABLE>
+
+	<P>
+
+	A rule is invoked with values in <I>field1</I> through
+	<I>fieldN</I>.  They may be referenced in the procedure's
+	<I>statements</I> as $(1) through $(<I>N</I>) (9 max), and the
+	first two only may be referenced in the action's <I>commands</I>
+	as $(1) and $(2).  $(&lt;) and $(&gt;) are synonymous with $(1)
+	and $(2).
+
+	<P>
+
+	Rules fall into two categories: updating rules (with actions),
+	and pure procedure rules (without actions).  Updating rules
+	treat arguments $(1) and $(2) as built targets and sources,
+	respectively, while pure procedure rules can take arbitrary
+	arguments.
+
+	<P>
+
+	When an updating rule is invoked, its updating actions are added
+	to those associated with its built targets ($(1)) before the
+	rule's procedure is run.  Later, to build the targets in the
+	updating phase, <I>commands</I> are passed to the OS command
+	shell, with $(1) and $(2) replaced by bound versions of the
+	target names.  See <A HREF="#binding"> Binding</A> above.
+
+	<P>
+
+	Rule invokation may be indirected through a variable:
+
+	<P><TABLE WIDTH=75% ALIGN=CENTER><TR><TD><DL>
+
+	    <P> <DT> <CODE>
+	    $(<I>var</I>) <I>field1</I> : <I>field2</I> : <I>...</I> 
+	    : <I>fieldN</I> ;
+	    </CODE>
+
+	    <P> <DT> <CODE>
+	    on <I>target</I> $(<I>var</I>) <I>field1</I> : <I>field2</I> : <I>...</I> 
+	    : <I>fieldN</I> ;
+	    </CODE>
+
+	    <P> <DT> <CODE>
+	    [ $(<I>var</I>) <I>field1</I> : <I>field2</I> : <I>...</I>
+	
+            : <I>fieldN</I> ] <br>
+	    [  on <I>target</I> $(<I>var</I>) <I>field1</I> : <I>field2</I> : <I>...</I>
+            : <I>fieldN</I> ] <br>
+
+	    </CODE>
+
+	</DL></TABLE>
+
+ 	The variable's value names the rule (or rules) to be invoked.
+	A rule is invoked for each element in the list of
+	<TT>$(<I>var</I>)</TT>'s values. The fields
+	<I>field1</I> : <I>field2</I> : <I>...</I> are passed as
+	arguments for each invokation. For the <TT> [ ... ] </TT> forms,
+	the return value is the concatenation of the return values for
+	all of the invokations.
+
+	<A NAME="actionmods">
+	<P> <H4> Action Modifiers </H4>
+	</A>
+
+	<P>
+
+	The following action <i>modifiers</i> are understood:
+
+	<P><TABLE WIDTH=75% ALIGN=CENTER><TR><TD><DL>
+
+	    <P><DT><CODE> actions bind <I>vars</I> </CODE>
+	    <DD> $(vars) will be replaced with bound values.
+
+	    <P><DT><CODE> actions existing </CODE>
+	    <DD> $(>) includes only source targets currently existing.
+
+	    <P><DT><CODE> actions ignore </CODE>
+	    <DD> The return status of the <I>commands</I> is ignored.
+
+	    <P><DT><CODE> actions piecemeal </CODE>
+	    <DD> <I>commands</I>  are repeatedly invoked with a subset
+	    of $(>) small enough to fit in the command buffer on this
+	    OS.
+
+	    <P><DT><CODE> actions quietly </CODE>
+	    <DD> The action is not echoed to the standard output.
+
+	    <P><DT><CODE> actions together </CODE>
+	    <DD> The $(>) from multiple invocations of the same action
+	    on the same built target are glommed together.
+
+	    <P><DT><CODE> actions updated </CODE>
+	    <DD> $(>) includes only source targets themselves marked
+	    for updating.
+
+	</DL></TABLE>
+
+
+<DT> <P> <H3> Built-in Rules </H3> <DD>
+
+	<P>
+	<B>Jam</b> has eleven built-in rules, all of which are pure
+	procedure rules without updating actions.  They are in
+	three groups:  the first builds the dependency graph;
+	the second modifies it; and the third are just utility
+	rules.
+
+	<P>
+
+	<P> <H5> Dependency Building </H5> 
+
+	<P><TABLE WIDTH=75% ALIGN=CENTER><TR><TD><DL>
+
+	<P><DT><CODE> 
+	DEPENDS <I>targets1</I> : <I>targets2</I> ; 
+	</CODE>
+
+	<DD> Builds a direct dependency: makes each of <I>targets1</I>
+	depend on each of <I>targets2</I>.  Generally, <I>targets1</I>
+	will be rebuilt if <I>targets2</I> are themselves rebuilt are
+	or are newer than <I>targets1</I>.
+
+	<P><DT><CODE>
+	INCLUDES <I>targets1</I> : <I>targets2</I> ;
+	</CODE>
+
+	<DD> Builds a sibling dependency: makes any target that depends
+	on any of <I>targets1</I> also depend on each of <I>targets2</I>.
+	This reflects the dependencies that arise when one source file
+	includes another:  the object built from the source file depends
+	both on the original and included source file,  but the two
+	sources files don't depend on each other.  For example:
+
+	<CODE>
+	<P>DEPENDS foo.o : foo.c ;
+	<BR>INCLUDES foo.c : foo.h ;
+	</CODE>
+
+	<P>
+
+	"foo.o" depends on "foo.c" and "foo.h" in this example.
+
+	</DL></TABLE>
+
+	<A NAME="bindingmods">
+	<P> <H5> Modifying Binding </H5> 
+	</A>
+
+	<P>
+
+	The six rules ALWAYS, LEAVES, NOCARE, NOTFILE, NOUPDATE, and
+	TEMPORARY modify the dependency graph so that <b>jam</b> treats
+	the targets differently during its target binding phase.  See
+	<A HREF="#binding">Binding</A> above.  Normally, <b>jam</b>
+	updates a target if it is missing, if its filesystem modification
+	time is older than any of its dependencies (recursively), or if
+	any of its dependencies are being updated.  This basic behavior
+	can be changed by invoking the following rules:
+
+	<P><TABLE WIDTH=75% ALIGN=CENTER><TR><TD><DL>
+
+	<P><DT><CODE>
+	ALWAYS <I>targets</I> ;
+	</CODE>
+
+	<DD> Causes <I>targets</I> to be rebuilt regardless of whether
+	they are up-to-date (they must still be in the dependency graph).
+	This is used for the clean and uninstall targets, as they have
+	no dependencies and would otherwise appear never to need building.
+	It is best applied to targets that are also NOTFILE targets,
+	but it can also be used to force a real file to be updated as
+	well.
+
+	<P><DT><CODE>
+	LEAVES <I>targets</I> ;
+	</CODE>
+
+	<DD> Makes each of <I>targets</I> depend only on its leaf sources,
+	and not on any intermediate targets.  This makes it immune to
+	its dependencies being updated, as the "leaf" dependencies are
+	those without their own dependencies and without updating actions.
+	This allows a target to be updated only if original source files
+	change.
+
+	<P><DT><CODE>
+	NOCARE <I>targets</I> ;
+	</CODE>
+
+	<DD> Causes <b>jam</b> to ignore <I>targets</I> that neither
+	can be found nor have updating actions to build them.  Normally
+	for such targets <B>jam</B> issues a warning and then skips
+	other targets that depend on these missing targets.  The HdrRule
+	in Jambase uses NOCARE on the header file names found during
+	header file scanning, to let <b>jam</b> know that the included
+	files may not exist.   For example,  if a #include is within an
+	#ifdef, the included file may not actually be around.
+
+	<P><DT><CODE>
+	NOTFILE <I>targets</I> ;
+	</CODE>
+
+	<DD> Marks <I>targets</I> as pseudotargets and not real files.
+	No timestamp is checked, and so the actions on such a target
+	are only executed if the target's dependencies are updated, or
+	if the target is also marked with ALWAYS.  The default <b>jam</b>
+	target "all" is a pseudotarget. In Jambase, NOTFILE is used to
+	define several addition convenient pseudotargets.
+
+	<P><DT><CODE>
+	NOUPDATE <I>targets</I> ;
+	</CODE>
+
+	<DD> Causes the timestamps on <I>targets</I> to be ignored.
+	This has two effects:  first,  once the target has been created
+	it will never be updated; second, manually updating target will
+	not cause other targets to be updated.  In Jambase, for example,
+	this rule is applied to directories by the MkDir rule, because
+	MkDir only cares that the target directory exists, not when it
+	has last been updated.
+
+	<P><DT><CODE>
+	TEMPORARY <I>targets</I> ;
+	</CODE>
+
+	<DD> Marks <I>targets</I> as temporary, allowing them to be
+	removed after other targets that depend upon them have been
+	updated.  If a TEMPORARY target is missing, <b>jam</b> uses the
+	timestamp of the target's parent.  Jambase uses TEMPORARY to
+	mark object files that are archived in a library after they are
+	built, so that they can be deleted after they are archived.
+
+	</DL></TABLE>
+
+	<P> <H5> Utility Rules </H5> 
+
+	<P>
+
+	The two rules ECHO and EXIT are utility rules, used only in
+	<b>jam</b>'s parsing phase.
+
+	<P><TABLE WIDTH=75% ALIGN=CENTER><TR><TD><DL>
+
+	<P><DT><CODE>
+	ECHO <i>args</I> ;
+	</CODE>
+
+	<DD> Blurts out the message <i>args</I> to stdout.
+
+	<P><DT><CODE>
+	EXIT <i>args</I> ;
+	</CODE>
+
+	<DD> Blurts out the message <i>args</I> to stdout and then exits
+	with a failure status.
+
+	<P>
+
+	"Echo", "echo", "Exit", and "exit" are accepted as aliases for ECHO
+	and EXIT, since it is hard to tell that these are built-in
+	rules and not part of the language, like "include".
+
+	</DL></TABLE>
+
+	<P>
+
+	The GLOB rule does filename globbing.
+
+	<P><TABLE WIDTH=75% ALIGN=CENTER><TR><TD><DL>
+
+	<P><DT><CODE>
+	GLOB <i>directories</I> : <I>patterns</I> : <I>downcase-opt</I>
+	</CODE>
+
+	<DD>  Using the same wildcards as for the patterns in the <A
+	HREF="#switch">switch</A> statement).  It is invoked by being
+	used as an argument to a rule invocation inside of `[ ]`. For
+	example: "<TT>FILES = [ GLOB dir1 dir2 : *.c *.h ]</TT>" sets
+	A to the list of C source and header files in dir1 or dir2.
+	The resulting filenames are the full pathnames, including the
+	directory, but the pattern is applied only to the file name
+	without the directory.  
+
+    <p>If <I>downcase-opt</I> is supplied, filenames are converted to
+	all-lowercase before matching against the pattern; you can use
+	this to do case-insensitive matching using lowercase patterns.
+	The paths returned will still have mixed case if the OS supplies
+	them.  On Windows NT and Cygwin, filenames are always downcased
+	before matching.
+
+	</DL></TABLE>
+
+	<P>
+
+	The MATCH rule does pattern matching.
+
+	<P><TABLE WIDTH=75% ALIGN=CENTER><TR><TD><DL>
+
+	<P><DT><CODE>
+	MATCH <i>regexps</I> : <I>list</I>
+	</CODE>
+
+	<DD> Matches the <b>egrep</b>(1) style regular expressions
+	<I>regexps</I> against the strings in <I>list</I>.  The result
+	is the concatenation of matching <tt>()</tt> subexpressions for
+	each string in <I>list</I>, and for each regular expression in    
+	<I>regexps</I>.  Only useful within the <tt>[ ]</tt> construct,
+	to change the result into a list.
+
+	</DL></TABLE>
+
+<DT> <P> <H3> Flow-of-Control </H3> <DD>
+
+	<P>
+
+	Jam has several simple flow-of-control statements:
+
+	<P><TABLE WIDTH=75% ALIGN=CENTER><TR><TD><DL>
+
+	    <P><DT><CODE> 
+
+		for <I>var</I> in <I>list</I> { <I>statements</I> }
+
+	    </CODE>
+
+	    <P><DD> Executes <i>statements</i> for each element in
+	    <i>list</i>, setting the variable <i>var</i> to the element
+	    value.
+
+	    <A name=if>
+	    <P><DT><CODE>
+	    </A>
+
+		if <I>cond</I> { <I>statements</I> } 
+		<BR> [ else <I>statements</I> ]
+
+	    </CODE>
+
+	    <P><DD> Does the obvious;  the else clause is optional.
+	    <i>cond</i> is built of:
+
+	    <TABLE> 
+
+		<TR><TD> <CODE><I>a</I></CODE></TD>
+		<TD> true if any <I>a</I> element is a non-zero-length 
+		string</TD>
+		<TR><TD> <CODE><I>a</I> = <I>b</I></CODE> </TD>
+		<TD> list <I>a</I> matches list <I>b</I> 
+		string-for-string</TD>
+		<TR><TD> <CODE><I>a</I> != <I>b</I> </CODE></TD>
+		<TD> list <I>a</I> does not match list <I>b</I></TD>
+		<TR><TD> <CODE><I>a</I> &lt; <I>b</I> </CODE></TD>
+		<TD> <I>a[i]</I> string is less than <I>b[i]</I>
+		string, where <i>i</i> is first mismatched element
+		in lists <I>a</I> and <I>b</I></TD>
+		<TR><TD> <CODE><I>a</I> &lt;= <I>b</I> </CODE></TD>
+		<TD> every <I>a</I> string is less than or equal to
+		its <I>b</I> counterpart</TD>
+		<TR><TD> <CODE><I>a</I> &gt; <I>b</I> </CODE></TD>
+		<TD> <I>a[i]</I> string is greater than <I>b[i]</I>
+		string, where <i>i</i> is first mismatched element</TD>
+		<TR><TD> <CODE><I>a</I> &gt;= <I>b</I> </CODE></TD>
+		<TD> every <I>a</I> string is greater than or equal to
+		its <I>b</I> counterpart</TD>
+		<TR><TD> <CODE><I>a</I> in <I>b</I> </CODE></TD>
+		<TD> true if all elements of <I>a</I> can be found
+		in <I>b</I>, or if <I>a</I> has no elements</TD>
+		<TR><TD> <CODE>! <I>cond</I> </CODE></TD>
+		<TD> condition not true</TD>
+		<TR><TD> <CODE><I>cond</I> && <I>cond</I> </CODE></TD>
+		<TD> conjunction</TD>
+		<TR><TD> <CODE><I>cond</I> || <I>cond</I> </CODE></TD>
+		<TD> disjunction</TD>
+		<TR><TD> <CODE>( <I>cond</I> ) </CODE></TD>
+		<TD> precedence grouping</TD>
+
+	    </TABLE>
+
+	    <P><DT> <CODE>
+
+		include <I>file</I> ;
+
+	    </CODE>
+
+	    <P><DD> Causes <b>jam</b> to read the named <i>file</i>.
+	    The file is bound like a regular target (see <A
+	    HREF="#binding"> Binding</A> above) but unlike a regular
+	    target the include file cannot be built.
+
+	    <P>
+
+	    The include file is inserted into the input stream during
+	    the parsing phase. The primary input file and all the included
+	    file(s) are treated as a single file; that is, <b>jam</b>
+	    infers no scope boundaries from included files.
+
+	    <P><DT> <CODE>
+
+		local <i>vars</I> [ = <i>values</i> ] ;
+
+	    </CODE>
+
+	    <P><DD> Creates new <i>vars</i> inside to the enclosing {}
+	    block, obscuring any previous values they might have.  The
+	    previous values for <i>vars</i> are restored when the current
+	    block ends.  Any rule called or file included will see the
+	    local and not the previous value (this is sometimes called
+	    Dynamic Scoping).  The local statement may appear anywhere,
+	    even outside of a block (in which case the previous value
+	    is restored when the input ends).  The <i>vars</i> are
+	    initialized to <i>values</i> if present, or left uninitialized
+	    otherwise.
+
+	    <P><DT> <CODE>
+
+		return <I>values</I> ; 
+
+	    </CODE>
+
+	    <P><DD> Within a rule body, the return statement sets the return
+            value for an invocation of the rule. It does <i>not</i> cause the
+            rule to return; a rule's value is actually the value of the
+            last statement executed, so a return should be the
+	    last statement executed before the rule "naturally" returns.
+
+	    <P><DT> <CODE>
+
+		<A NAME="switch">
+		switch <I>value</I> 
+		</A>
+		<BR> { 
+		<BR> case <I>pattern1</I> : <I>statements</I> ; 
+		<BR> case <I>pattern2</I> : <I>statements</I> ; 
+		<BR> ... 
+		<BR> }
+
+	    </CODE>
+
+	    <P><DD> The switch statement executes zero or one of the
+	    enclosed <i>statements</i>, depending on which, if any, is
+	    the first case whose <i>pattern</I> matches <i>value</i>.
+	    The <i>pattern</I> values are not variable-expanded.  The
+	    <i>pattern</I>  values may include the following wildcards:
+
+	    <TABLE>
+
+		<TR><TD><CODE> ? </CODE></TD>
+		<TD> match any single character </TD>
+		<TR><TD><CODE> * </CODE></TD>
+		<TD> match zero or more characters </TD>
+		<TR><TD><CODE> [<i>chars</i>] </CODE></TD>
+		<TD> match any single character in <i>chars</i> </TD>
+		<TR><TD><CODE> [^<i>chars</i>] </CODE></TD>
+		<TD> match any single character not in <i>chars</i> </TD>
+		<TR><TD><CODE> \<i>x</i> </CODE></TD>
+		<TD> match <i>x</i> (escapes the other wildcards)</i> </TD>
+
+	    </TABLE>
+
+	    <P><DT> <CODE>
+
+		while <I>cond</I> { <I>statements</I> }
+
+	    </CODE>
+
+	    <P><DD> Repeatedly execute <I>statements</I> while <I>cond</I>
+	    remains true upon entry. (See the description of <I>cond</I>
+	    expression syntax under <a href="#if">if</a>, above).
+	</DL></TABLE>
+
+<DT> <P> <H3> Variables </H3> <DD>
+
+	<P>
+
+	<B>Jam</b> variables are lists of zero or more elements, with
+	each element being a string value.  An undefined variable is
+	indistinguishable from a variable with an empty list, however,
+	a defined variable may have one more elements which are null
+	strings.  All variables are referenced as $(<I>variable</I>).
+
+	<P>
+
+	Variables are either global or target-specific.  In the latter
+	case, the variable takes on the given value only during the
+	updating of the specific target.
+
+	<P>
+
+	A variable is defined with:
+
+	<P> <TABLE WIDTH=75% ALIGN=CENTER> <TR><TD> <DL>
+
+	    <DT><CODE> 
+	    <I>variable</I> = <I>elements</I> ; </CODE>
+	    <DT><CODE> 
+	    <I>variable</I> += <I>elements</I> ; </CODE>
+	    <DT><CODE> 
+	    <I>variable</I> on <I>targets</I> = <I>elements</I> ; </CODE>
+	    <DT><CODE> 
+	    <I>variable</I> on <I>targets</I> += <I>elements</I> ; </CODE>
+	    <DT><CODE> 
+	    <I>variable</I> default = <I>elements</I> ; </CODE>
+	    <DT><CODE> 
+	    <I>variable</I> ?= <I>elements</I> ; </CODE>
+
+	</DL></TABLE>
+
+	<P>
+
+	The first two forms set <I>variable</I> globally.  The third
+	and forth forms set a target-specific variable.  The = operator
+	replaces any previous elements of <I>variable</I> with
+	<I>elements</I>; the += operation adds <I>elements</I> to
+	<I>variable</I>'s list of elements.  The final two forms are
+	synonymous: they set <I>variable</I> globally, but only if it
+	was previously unset.
+
+	<P>
+
+	Variables referenced in updating commands will be replaced with
+	their values; target-specific values take precedence over global
+	values.  Variables passed as arguments ($(1) and $(2)) to actions
+	are replaced with their bound values; the "bind" modifier can
+	be used on actions to cause other variables to be replaced with
+	bound values.  See <A HREF="#actionmods">Action Modifiers</A>
+	above.
+
+	<P>
+
+	<B>Jam</b> variables are not re-exported to the environment of
+	the shell that executes the updating actions, but the updating
+	actions can reference <b>jam</b> variables with $(<I>variable</I>).
+
+	<P> <H4> Variable Expansion </H4>
+
+	<P>
+
+	During parsing, <b>jam</b> performs variable expansion on each
+	token that is not a keyword or rule name.  Such tokens with
+	embedded variable references are replaced with zero or more
+	tokens.  Variable references are of the form $(<I>v</I>) or
+	$(<I>vm</I>), where <i>v</i> is the variable name,  and  <I>m</I>
+	are optional modifiers.
+
+	<P>
+
+	Variable expansion in a rule's actions is similar to variable
+	expansion in statements,  except that the action string is
+	tokenized at whitespace regardless of quoting.
+
+	<P>
+
+	The result of a token after variable expansion is the
+	<i>product</i> of the components of the token, where each
+	component is a literal substring or a list substituting a variable
+	reference.  For example:
+
+	<P> <TABLE WIDTH=75% ALIGN=CENTER><TR><TD><CODE>
+
+	    <BR>$(X)      -> a b c
+	    <BR>t$(X)     -> ta tb tc
+	    <BR>$(X)z     -> az bz cz
+	    <BR>$(X)-$(X) -> a-a a-b a-c b-a b-b b-c c-a c-b c-c
+
+	</CODE></TABLE>
+
+	<P>
+
+	The variable name and modifiers can themselves contain
+	a variable reference,  and this partakes of the product
+	as well:
+
+	<P> <TABLE WIDTH=75% ALIGN=CENTER><TR><TD><CODE>
+
+	    <BR>$(X)      -> a b c
+	    <BR>$(Y)      -> 1 2
+	    <BR>$(Z)      -> X Y
+	    <BR>$($(Z))   -> a b c 1 2
+
+	</CODE></TABLE>
+
+	<P>
+
+	Because of this product expansion, if any variable reference in
+	a token is undefined, the result of the expansion is an empty
+	list.  If any variable element is a null string, the result
+	propagates the non-null elements:
+
+	<P> <TABLE WIDTH=75% ALIGN=CENTER><TR><TD><CODE>
+
+	    <BR>$(X)        -> a ""
+	    <BR>$(Y)        -> "" 1
+	    <BR>$(Z)	  -> 
+	    <BR>*$(X)$(Y)*  -> *a* *a1* ** *1*
+	    <BR>*$(X)$(Z)*  ->
+
+	</CODE></TABLE>
+
+	<P>
+
+	A variable element's string value can be parsed into grist and
+	filename-related components.  Modifiers to a variable are used
+	to select elements, select components, and replace components.
+	The modifiers are:
+
+	<P> <TABLE WIDTH=75% ALIGN=CENTER>
+
+	    <TR><TD><CODE> [<I>n</I>] </CODE>
+	    <TD>Select element number <I>n</I> (starting at 1).  If
+	    the variable contains fewer than <I>n</I> elements,
+	    the result is a zero-element list.
+
+	    <TR><TD><CODE> [<I>n</I>-<I>m</I>] </CODE>
+	    <TD>Select elements number <I>n</I> through <I>m</I>.
+
+	    <TR><TD><CODE> [<I>n</I>-] </CODE>
+	    <TD>Select elements number <I>n</I> through the last.
+
+	    <TR><TD><CODE> :B </CODE>
+	    <TD>Select filename base.
+
+	    <TR><TD><CODE> :S </CODE>
+	    <TD>Select (last) filename suffix.
+
+	    <TR><TD><CODE> :M </CODE>
+	    <TD>Select archive member name.
+
+	    <TR><TD><CODE> :D </CODE>
+	    <TD>Select directory path.
+
+	    <TR><TD><CODE> :P </CODE>
+	    <TD>Select parent directory.
+
+	    <TR><TD><CODE> :G </CODE>
+	    <TD>Select grist.
+
+	    <TR><TD><CODE> :U </CODE>
+	    <TD>Replace lowercase characters with uppercase.
+
+	    <TR><TD><CODE> :L </CODE>
+	    <TD>Replace uppercase characters with lowercase.
+
+	    <TR><TD><CODE> :<i>chars</I> </CODE>
+	    <TD>Select the components listed in <i>chars</i>.
+
+	    <TR><TD><CODE> :G=<I>grist</I> </CODE>
+	    <TD>Replace grist with <I>grist</I>.
+
+	    <TR><TD><CODE> :D=<I>path</I> </CODE>
+	    <TD>Replace directory with <I>path</I>.
+
+	    <TR><TD><CODE> :B=<I>base</I> </CODE>
+	    <TD>Replace the base part of file name with <I>base</I>.
+
+	    <TR><TD><CODE> :S=<I>suf</I> </CODE>
+	    <TD>Replace the suffix of file name with <I>suf</I>.
+
+	    <TR><TD><CODE> :M=<I>mem</I> </CODE>
+	    <TD>Replace the archive member name with <I>mem</I>.
+
+	    <TR><TD><CODE> :R=<I>root</I> </CODE>
+	    <TD>Prepend <I>root</I> to the whole file name,  if not
+	    already rooted.
+
+	    <TR><TD><CODE> :E=<I>value</I> </CODE>
+	    <TD>Assign <I>value</I> to the variable if it is unset.
+
+	    <TR><TD><CODE> :J=<I>joinval</I> </CODE>
+	    <TD>Concatentate list elements into single
+            element, separated by <I>joinval</I>.
+
+	</TABLE>
+
+	<P>
+
+	On VMS, $(var:P) is the parent directory of $(var:D).
+
+<DT> <P> <H3> Built-in Variables </H3> <DD>
+
+	<P>
+
+	This section discusses variables that have special meaning to
+	<b>jam</b>.
+
+	<A NAME="search">
+	<P> <H4> SEARCH and LOCATE Variables </H4>
+	</A>
+
+	<P>
+
+	These two variables control the binding of file target names to
+	locations in the file system.  Generally, $(SEARCH) is used to
+	find existing sources while $(LOCATE) is used to fix the location
+	for built targets.
+
+	<P>
+
+	Rooted (absolute path) file targets are bound as is.  Unrooted
+	file target names are also normally bound as is, and thus relative
+	to the current directory, but the settings of $(LOCATE) and
+	$(SEARCH) alter this:
+
+	<P>
+
+	<UL>
+
+	<LI> If $(LOCATE) is set then the target is bound relative to
+	the first directory in $(LOCATE).  Only the first element is
+	used for binding.
+
+	<LI> If $(SEARCH) is set then the target is bound to the first
+	directory in $(SEARCH) where the target file already exists.
+
+	<LI> If the $(SEARCH) search fails, the target is bound relative
+	to the current directory anyhow.
+
+	</UL>
+
+	<P>
+
+	Both $(SEARCH) and $(LOCATE) should be set target-specific and
+	not globally.  If they were set globally,  <b>jam</b> would use
+	the same paths for all file binding, which is not likely to
+	produce sane results.  When writing your own rules,  especially
+	ones not built upon those in Jambase, you may need to set
+	$(SEARCH) or $(LOCATE) directly.  Almost all of the rules defined
+	in Jambase set $(SEARCH) and $(LOCATE) to sensible values for
+	sources they are looking for and targets they create, respectively.
+
+	<A NAME="hdrscan">
+	<P> <H4> HDRSCAN and HDRRULE Variables </H4>
+	</A>
+
+	<P>
+
+	These two variable control header file scanning.  $(HDRSCAN) is
+	an <b>egrep</b>(1) pattern, with ()'s surrounding the file name,
+	used to find file inclusion statements in source files.  Jambase
+	uses $(HDRPATTERN) as the pattern for $(HDRSCAN).  $(HDRRULE)
+	is the name of a rule to invoke with the results of the scan:
+	the scanned file is the target, the found files are the sources.
+	This is the only place where <b>jam</b> invokes a rule through
+	a variable setting.
+
+	<P>
+
+	Both $(HDRSCAN) and $(HDRRULE) must be set for header file
+	scanning to take place, and they should be set target-specific
+	and not globally.  If they were set globally, all files, including
+	executables and libraries, would be scanned for header file
+	include statements.
+
+	<P>
+
+	The scanning for header file inclusions is not exact, but it is
+	at least dynamic, so there is no need to run something like
+	<b>makedepend</b>(GNU) to create a static dependency file. The
+	scanning mechanism errs on the side of inclusion (i.e., it is
+	more likely to return filenames that are not actually used by
+	the compiler than to miss include files) because it can't tell
+	if #include lines are inside #ifdefs or other conditional logic.
+	In Jambase, HdrRule applies the NOCARE rule to each header file
+	found during scanning so that if the file isn't present yet
+	doesn't cause the compilation to fail, <b>jam</b> won't care.
+
+	<P>
+
+	Also, scanning for regular expressions only works where the
+	included file name is literally in the source file.  It can't
+	handle languages that allow including files using variable names
+	(as the Jam language itself does).
+
+	<P> <H4> Platform Identifier Variables </H4>
+
+	<P>
+
+	A number of Jam built-in variables can be used to identify
+	runtime platform:
+
+	<P>
+
+	<TABLE WIDTH=75% ALIGN=CENTER>
+
+	    <TR><TD>OS<TD>OS identifier string 
+	    <TR><TD>OSPLAT<TD>Underlying architecture, when applicable
+	    <TR><TD>MAC<TD>true on MAC platform
+	    <TR><TD>NT<TD>true on NT platform
+	    <TR><TD>OS2<TD>true on OS2 platform
+	    <TR><TD>UNIX<TD>true on Unix platforms
+	    <TR><TD>VMS<TD>true on VMS platform
+
+	</TABLE>
+
+	<P> <H4> Jam Version Variables </H4>
+
+	<P>
+
+	<TABLE WIDTH=75% ALIGN=CENTER>
+
+	    <TR><TD>JAMDATE<TD>Time and date at <b>jam</b> start-up.
+	    <TR><TD>JAMUNAME<TD>Ouput of <b>uname</b>(1) command (Unix only)
+	    <TR><TD>JAMVERSION<TD><b>jam</b> version, currently "2.3"
+
+	</TABLE>
+
+	<P> <H4> JAMSHELL Variable </H4>
+
+	<P>
+
+	When  <b>jam</b>  executes a  rule's action block, it forks and
+	execs a shell, passing the action block as an argument to the
+	shell.   The invocation of the shell can be controlled by
+	$(JAMSHELL).  The default on Unix is, for example:
+
+	<P>
+
+	<CODE>JAMSHELL = /bin/sh -c % ;</CODE>
+
+	<P>
+
+	The % is replaced with the text of the action block.
+
+	<P>
+
+	<B>Jam</b>  does not directly support building in parallel across
+	multiple hosts, since that is heavily dependent on the local
+	environment.   To build in parallel across multiple hosts, you
+	need to write your own shell that provides access to the multiple
+	hosts.  You then reset $(JAMSHELL) to reference it.
+
+	<P>
+
+	Just as <b>jam</b> expands a % to be the text of the rule's
+	action block, it expands a ! to be the multi-process slot number.
+	The slot number varies between 1 and the number of concurrent
+	jobs permitted by the -j flag given on the command line.  Armed
+	with this, it is possible to write a multiple host shell.  For
+	example:
+
+	<P>
+
+	<TABLE WIDTH=75% ALIGN=CENTER><TR><TD><CODE>
+
+	    <BR>#!/bin/sh
+	    <BR>
+	    <BR># This sample JAMSHELL uses the SunOS on(1) command to execute a
+	    <BR># command string with an identical environment on another host.
+	    <BR>
+	    <BR># Set JAMSHELL = jamshell ! %
+	    <BR>#
+	    <BR># where jamshell is the name of this shell file.
+	    <BR>#
+	    <BR># This version handles up to -j6; after that they get executed
+	    <BR># locally.
+	    <BR>
+	    <BR>case $1 in
+	    <BR>1|4) on winken sh -c "$2";;
+	    <BR>2|5) on blinken sh -c "$2";;
+	    <BR>3|6) on nod sh -c "$2";;
+	    <BR>*)   eval "$2";;
+	    <BR>esac
+
+	</CODE></TABLE>
+
+
+<DT> <P> <H2> DIAGNOSTICS </H2>  <DD>
+
+	<P>
+
+       In addition to generic error messages, <B>jam</B> may emit one of
+       the following:
+
+       <P><TABLE WIDTH=75% ALIGN=CENTER><TR><TD><DL>
+
+       <P><DT><CODE> warning: unknown rule X </CODE> <DD>
+
+              A rule was invoked that has not been defined with
+              an "actions" or "rule" statement.
+
+       <P><DT><CODE> using N temp target(s) </CODE> <DD>
+
+              Targets marked as being temporary (but nonetheless
+              present) have been found.
+
+       <P><DT><CODE> updating N target(s) </CODE> <DD>
+
+              Targets are out-of-date and will be updated.
+
+       <P><DT><CODE> can't find N target(s) </CODE> <DD>
+
+              Source files can't be found and there are no
+              actions to create them.
+
+       <P><DT><CODE> can't make N target(s) </CODE> <DD>
+
+              Due to sources not being found, other targets cannot be made.
+
+       <P><DT><CODE> warning: X depends on itself </CODE> <DD>
+
+              A target depends on itself either directly or
+              through its sources.
+
+       <P><DT><CODE> don't know how to make X </CODE> <DD>
+
+              A target is not present and no actions have been
+              defined to create it.
+
+       <P><DT><CODE> X skipped for lack of Y </CODE> <DD>
+
+              A source failed to build, and thus a target cannot
+              be built.
+
+       <P><DT><CODE> warning: using independent target X </CODE> <DD>
+
+              A target that is not a dependency of any other
+              target is being referenced with $(&lt;) or $(&gt;).
+
+       <P><DT><CODE> X removed </CODE> <DD>
+
+              <b>Jam</b>  removed a  partially built target after being
+              interrupted.
+
+	</DL></TABLE>
+
+<DT> <P> <H2> BUGS, LIMITATIONS </H2> <DD>
+
+	<P>
+
+	The -j flag can cause <B>jam</B> to get confused when single
+	actions update more than one target at a time. <B>jam</B> may
+	proceed as if the targets were built even though they are still
+	under construction.
+
+	<P>
+
+	For parallel building to be successful, the dependencies among
+	files must be properly spelled out, as targets tend to get built
+	in a quickest-first ordering.  Also, beware of un-parallelizable
+	commands that drop fixed-named files into the current directory,
+	like <b>yacc</b>(1) does.
+
+	<P>
+
+	With the -j flag, errors from failed commands can get staggeringly
+	mixed up.  
+
+	<P>
+
+	A poorly set $(JAMSHELL) is likely to result in silent failure.
+
+<DT> <P> <H2> SEE ALSO </H2> <DD>
+
+	<P>
+
+	<UL>
+
+	<LI> <a href="Jambase.html">Jambase Reference</a>
+
+	<LI> <a href="Jamfile.html">Using Jamfiles and Jambase</a>
+
+	</UL>
+
+	<P>
+
+	Jam documentation and source are available from the <A
+	HREF="http://public.perforce.com/public/index.html">Perforce
+	Public Depot</a>.
+
+<DT> <P> <H2> AUTHOR </H2>   <DD>
+
+	<P>
+	Jam's author is Christopher Seiwald (<a 
+	href="mailto:seiwald at perforce.com">seiwald at perforce.com</A>).
+	Documentation is provided by 
+	<A HREF="http://www.perforce.com">Perforce Software, Inc.</A>
+
+</DL>
+
+<P> <HR>   
+
+	<P>
+
+        Copyright 1993-2002 Christopher Seiwald and Perforce Software, Inc.
+        <BR>
+        Comments to <A HREF="mailto:info at perforce.com">info at perforce.com</A>
+        <BR>
+        Last updated: April 1, 2002
+	<BR>
+	$Id: Jam.html,v 1.6 2003/09/01 08:04:33 vladimir_prus Exp $
+
+</BODY> 
+</HTML>
+

Added: boost-jam/boost-build/branches/upstream/current/jam_src/Jambase
===================================================================
--- boost-jam/boost-build/branches/upstream/current/jam_src/Jambase	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/jam_src/Jambase	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,2461 @@
+#
+# /+\
+# +\    Copyright 1993, 2000 Christopher Seiwald.
+# \+/
+#
+# This file is part of Jam - see jam.c for Copyright information.
+#
+
+# This file is ALSO:
+# Copyright 2001-2004 David Abrahams.
+# Copyright 2002-2004 Rene Rivera.
+# Distributed under the Boost Software License, Version 1.0.
+# (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+
+if $(NT)
+{
+    SLASH ?= \\ ;
+}
+SLASH ?= / ;
+
+# Glob for patterns in the directories starting from the given
+# start directory, up to and including the root of the file-system.
+# We stop globbing as soon as we find at least one match.
+#
+rule find-to-root ( dir : patterns + )
+{
+    local globs = [ GLOB $(dir) : $(patterns) ] ;
+    while ! $(globs) && $(dir:P) != $(dir)
+    {
+        dir = $(dir:P) ;
+        globs = [ GLOB $(dir) : $(patterns) ] ;
+    }
+    return $(globs) ;
+}
+
+# This global will hold the location of the user's boost-build.jam file.
+.boost-build-file = ;
+
+# This global will hold the location of the build system bootstrap file.
+.bootstrap-file = ;
+
+# Remember the value of $(BOOST_BUILD_PATH) supplied to us by the user.
+BOOST_BUILD_PATH.user-value = $(BOOST_BUILD_PATH) ;
+
+# On Unix only, when BOOST_BUILD_PATH is not supplied by user, put
+# sensible default value. This allowes Boost.Build to work without
+# any environment variables, which is good in itself and also
+# required by Debian Policy.
+if ! $(BOOST_BUILD_PATH) && $(UNIX)
+{
+    BOOST_BUILD_PATH = /usr/share/boost-build ;
+}
+
+
+
+# This rule can be invoked from an optional user's boost-build.jam
+# file to both indicate where to find the build system files, and to
+# load them. The path indicated is relative to the location of the
+# boost-build.jam file. 
+#
+rule boost-build ( dir ? )
+{
+    if $(.bootstrap-file)
+    {
+        EXIT "Error: Illegal attempt to re-bootstrap the build system by invoking" ;
+        ECHO ;
+        ECHO "   'boost-build" $(dir) ";'" ;
+        ECHO ;
+        EXIT "Please consult the documentation at 'http://www.boost.org'." ;
+    }
+    
+    # Add the given directory to the path so we can find the build
+    # system. If dir is empty, has no effect.
+    #
+    BOOST_BUILD_PATH = $(dir:R=$(.boost-build-file:D)) $(BOOST_BUILD_PATH) ;
+    
+    # Try to find the build system bootstrap file 'bootstrap.jam'.
+    #
+    local bootstrap-file =
+        [ GLOB $(BOOST_BUILD_PATH) : bootstrap.jam ] ;
+    .bootstrap-file = $(bootstrap-file[1]) ;
+            
+    # There is no boost-build.jam we can find, exit with an error
+    #
+    if ! $(.bootstrap-file)
+    {
+        ECHO "Unable to load Boost.Build: could not find build system." ;
+        ECHO --------------------------------------------------------- ;
+        ECHO "$(.boost-build-file) attempted to load the build system by invoking" ;
+        ECHO ;
+        ECHO "   'boost-build" $(dir) ";'" ;
+        ECHO ;
+        ECHO "but we were unable to find \"bootstrap.jam\" in the specified directory" ;
+        ECHO "or in BOOST_BUILD_PATH (searching "$(BOOST_BUILD_PATH:J=", ")")." ;
+        ECHO ;
+        EXIT "Please consult the documentation at 'http://www.boost.org'." ;
+    }
+    
+    if [ MATCH .*(--debug-configuration).* : $(ARGV) ]
+    {
+        ECHO "notice: loading Boost.Build from" 
+          [ NORMALIZE_PATH $(.bootstrap-file:D) ] ;
+    }
+    
+    
+    # Load the build system, now that we know where to start from.
+    #
+    include $(.bootstrap-file) ;
+}
+
+
+if [ MATCH .*(bjam).* : $(ARGV[1]:BL) ]
+  || $(BOOST_ROOT)    # A temporary measure so Jam works with Boost.Build v1
+{
+    # We attempt to load "boost-build.jam" by searching from the current invocation directory
+    # up to the root of the file-system.
+    #
+    # boost-build.jam is expected to invoke the "boost-build" rule to
+    # load the Boost.Build files.
+    
+    local search-path = $(BOOST_BUILD_PATH) $(BOOST_ROOT) ;
+    
+    local boost-build-files =
+        [ find-to-root [ PWD ] : boost-build.jam ]
+        # Another temporary measure so Jam works with Boost.Build v1
+        [ GLOB $(search-path) : boost-build.jam ] ;
+    
+    .boost-build-file = $(boost-build-files[1]) ;
+    
+    if [ MATCH .*(--debug-configuration).* : $(ARGV) ]
+    {
+        ECHO "notice: found boost-build.jam at" 
+          [ NORMALIZE_PATH $(.boost-build-file) ] ;
+    }
+        
+    # There is no boost-build.jam we can find, exit with an error, and information.
+    #
+    if ! $(.boost-build-file)
+    {
+        ECHO "Unable to load Boost.Build: could not find \"boost-build.jam\"" ;
+        ECHO --------------------------------------------------------------- ;
+        
+        if ! [ MATCH .*(bjam).* : $(ARGV[1]:BL) ]
+        {
+            ECHO "BOOST_ROOT must be set, either in the environment, or " ;
+            ECHO "on the command-line with -sBOOST_ROOT=..., to the root" ;
+            ECHO "of the boost installation." ;
+            ECHO ;
+        }
+
+        ECHO "Attempted search from" [ PWD ] "up to the root" ;
+        ECHO "and in these directories from BOOST_BUILD_PATH and BOOST_ROOT: "$(search-path:J=", ")"." ;
+        EXIT "Please consult the documentation at 'http://www.boost.org'." ;
+    }
+    
+    # Now load the boost-build.jam to get the build system loaded. This
+    # incidentaly loads the users jamfile and attempts to build targets.
+    #
+    # We also set it up so we can tell wether we are loading the new V2
+    # system or the the old V1 system.
+    #
+    include $(.boost-build-file) ;
+    
+    # Check that, at minimum, the bootstrap file was found.
+    #
+    if ! $(.bootstrap-file)
+    {
+        ECHO "Unable to load Boost.Build" ;
+        ECHO -------------------------- ;
+        ECHO "\"$(.boost-build-file)\" was found by searching from" [ PWD ] "up to the root" ;
+        ECHO "and in these directories from BOOST_BUILD_PATH and BOOST_ROOT: "$(search-path:J=", ")"." ;
+        ECHO ;
+        ECHO "However, it failed to call the \"boost-build\" rule to indicate" ;
+        ECHO "the location of the build system." ;
+        ECHO ;
+        EXIT "Please consult the documentation at 'http://www.boost.org'." ;
+    }
+}
+else
+{
+
+#
+# JAMBASE - jam 2.3 ruleset providing make(1)-like functionality
+#
+# Supports UNIX, NT, and VMS.
+#
+# 12/27/93 (seiwald) - purturb library sources with SOURCE_GRIST
+# 04/18/94 (seiwald) - use '?=' when setting OS specific vars
+# 04/21/94 (seiwald) - do RmTemps together
+# 05/05/94 (seiwald) - all supported C compilers support -o: relegate
+#              RELOCATE as an option; set Ranlib to "" to disable it
+# 06/01/94 (seiwald) - new 'actions existing' to do existing sources
+# 08/25/94 (seiwald) - new ObjectCcFlags rule to append to per-target CCFLAGS
+# 08/29/94 (seiwald) - new ObjectHdrs rule to append to per-target HDRS
+# 09/19/94 (seiwald) - LinkLibraries and Undefs now append
+#            - Rule names downshifted.
+# 10/06/94 (seiwald) - Dumb yyacc stuff moved into Jamfile.
+# 10/14/94 (seiwald) - (Crude) support for .s, .C, .cc, .cpp, and .f files.
+# 01/08/95 (seiwald) - Shell now handled with awk, not sed
+# 01/09/95 (seiwald) - Install* now take dest directory as target
+# 01/10/95 (seiwald) - All entries sorted.
+# 01/10/95 (seiwald) - NT support moved in, with LauraW's help.  
+# 01/10/95 (seiwald) - VMS support moved in.
+# 02/06/95 (seiwald) - ObjectC++Flags and SubDirC++Flags added.
+# 02/07/95 (seiwald) - Iron out when HDRSEARCH uses "" or SEARCH_SOURCE.
+# 02/08/95 (seiwald) - SubDir works on VMS.
+# 02/14/95 (seiwald) - MkDir and entourage.
+# 04/30/95 (seiwald) - Use install -c flag so that it copies, not moves.
+# 07/10/95 (taylor) - Support for Microsoft C++.
+# 11/21/96 (peterk) - Support for BeOS
+# 07/19/99 (sickel) - Support for Mac OS X Server (and maybe client)
+# 02/18/00 (belmonte)- Support for Cygwin.
+
+# Special targets defined in this file:
+#
+# all       - parent of first, shell, files, lib, exe
+# first     - first dependent of 'all', for potential initialization
+# shell     - parent of all Shell targets 
+# files     - parent of all File targets
+# lib       - parent of all Library targets
+# exe       - parent of all Main targets
+# dirs      - parent of all MkDir targets
+# clean     - removes all Shell, File, Library, and Main targets
+# uninstall - removes all Install targets
+#   
+
+# Rules defined by this file:
+#
+# as obj.o : source.s ;         .s -> .o
+# Bulk dir : files ;            populate directory with many files
+# Cc obj.o : source.c ;         .c -> .o
+# C++ obj.o : source.cc ;       .cc -> .o
+# Clean clean : sources ;       remove sources with 'jam clean'
+# File dest : source ;          copy file
+# Fortran obj.o : source.f ;        .f -> .o
+# GenFile source.c : program args ; make custom file
+# Hardlink target : source ;        make link from source to target
+# HdrRule source : headers ;        handle #includes
+# InstallInto dir : sources ;       install any files
+# InstallBin dir : sources ;        install binaries
+# InstallLib dir : sources ;        install files
+# InstallFile dir : sources ;       install files
+# InstallMan dir : sources ;        install man pages
+# InstallShell dir : sources ;      install shell scripts
+# Lex source.c : source.l ;     .l -> .c
+# Library lib : source ;        archive library from compiled sources
+# LibraryFromObjects lib : objects ;    archive library from objects
+# LinkLibraries images : libraries ;    bag libraries onto Mains
+# Main image : source ;         link executable from compiled sources
+# MainFromObjects image : objects ; link executable from objects
+# MkDir dir ;               make a directory, if not there
+# Object object : source ;      compile object from source
+# ObjectCcFlags source : flags ;    add compiler flags for object
+# ObjectC++Flags source : flags ;   add compiler flags for object
+# ObjectHdrs source : dirs ;        add include directories for object
+# Objects sources ;         compile sources
+# RmTemps target : sources ;        remove temp sources after target made
+# Setuid images ;           mark executables Setuid
+# SubDir TOP d1 d2 ... ;        start a subdirectory Jamfile
+# SubDirCcFlags flags ;         add compiler flags until next SubDir
+# SubDirC++Flags flags ;        add compiler flags until next SubDir
+# SubDirHdrs dirs ;         add include dirs until next SubDir
+# SubInclude TOP d1 d2 ... ;        include a subdirectory Jamfile
+# Shell exe : source ;          make a shell executable
+# Undefines images : symbols ;      save undef's for linking
+# UserObject object : source ;      handle unknown suffixes for Object
+# Yacc source.c : source.y ;        .y -> .c
+#
+# Utility rules that have no side effects (not supported):
+#
+# FAppendSuffix f1 f2 ... : $(SUF) ;    return $(<) with suffixes
+# FConcat value ... ;               return contatenated values
+# FDirName d1 d2 ... ;          return path from root to dir
+# FGrist d1 d2 ... ;            return d1!d2!...
+# FGristFiles value ;           return $(value:G=$(SOURCE_GRIST))
+# FGristSourceFiles value ;     return $(value:G=$(SOURCE_GRIST))
+# FRelPath d1 : d2 ;            return rel path from d1 to d2
+# FSubDir d1 d2 ... ;           return path to root
+#
+
+
+# Brief review of the jam language:
+#
+# Statements:
+#   rule RULE - statements to process a rule
+#   actions RULE - system commands to carry out target update
+#
+# Modifiers on actions:
+#   together - multiple instances of same rule on target get executed
+#          once with their sources ($(>)) concatenated
+#   updated - refers to updated sources ($(>)) only
+#   ignore - ignore return status of command
+#   quietly - don't trace its execution unless verbose
+#   piecemeal - iterate command each time with a small subset of $(>)
+#   existing - refers to currently existing sources ($(>)) only
+#   bind vars - subject to binding before expanding in actions
+#
+# Special rules:
+#   ALWAYS - always build a target
+#   DEPENDS - builds the dependency graph
+#   ECHO - blurt out targets on stdout
+#   EXIT - blurt out targets and exit
+#   INCLUDES - marks sources as headers for target (a codependency)
+#   NOCARE - don't panic if the target can't be built
+#   NOUPDATE - create the target if needed but never update it 
+#   NOTFILE - ignore the timestamp of the target (it's not a file)
+#   TEMPORARY - target need not be present if sources haven't changed
+#
+# Special variables set by jam:
+#   $(<) - targets of a rule (to the left of the :)
+#   $(>) - sources of a rule (to the right of the :)
+#   $(xxx) - true on xxx (UNIX, VMS, NT, OS2, MAC)
+#   $(OS) - name of OS - varies wildly
+#   $(JAMVERSION) - version number (2.3)
+#
+# Special variables used by jam:
+#   SEARCH - where to find something (used during binding and actions)
+#   LOCATE - where to plop something not found with SEARCH
+#   HDRRULE - rule to call to handle include files
+#   HDRSCAN - egrep regex to extract include files
+#
+# Special targets:
+#   all - default if none given on command line
+#
+
+# Initialize variables
+#
+
+#
+# OS specific variable settings
+#
+if $(NT)
+{
+    # the list of supported toolsets on Windows NT and Windows 95/98
+    #
+    local SUPPORTED_TOOLSETS = "BORLANDC" "VC7" "VISUALC" "VISUALC16" "INTELC" "WATCOM"
+                               "MINGW" "LCC" ;
+  
+    # this variable holds the current toolset
+    #
+    TOOLSET = "" ;
+    
+    # if the JAM_TOOLSET environment variable is defined, check that it is
+    # one of our supported values
+    #
+    if $(JAM_TOOLSET)
+    {
+      local t ;
+      
+      for t in $(SUPPORTED_TOOLSETS)
+      {
+        $(t) = $($(t):J=" ") ; # reconstitute paths with spaces in them
+        if $(t) = $(JAM_TOOLSET) { TOOLSET = $(t) ; }
+      }
+      
+      if ! $(TOOLSET)
+      {
+        ECHO  "The JAM_TOOLSET environment variable is defined but its value" ;
+        ECHO  "is invalid, please use one of the following:" ;
+        ECHO  ;
+        
+        for t in $(SUPPORTED_TOOLSETS) { ECHO "  " $(t) ; }
+        EXIT ;
+      }
+    }
+    
+    # if TOOLSET is empty, we'll try to detect the toolset from other
+    # environment variables to remain backwards compatible with Jam 2.3
+    #
+    if ! $(TOOLSET)
+    {
+      if $(BCCROOT)
+      {
+        TOOLSET  = BORLANDC ;
+        BORLANDC = $(BCCROOT:J=" ") ;
+      }
+      else if $(MSVC)
+      {
+        TOOLSET   = VISUALC16 ;
+        VISUALC16 = $(MSVC:J=" ") ;
+      }
+      else if $(MSVCNT)
+      {
+        TOOLSET = VISUALC ;
+        VISUALC = $(MSVCNT:J=" ") ;
+      }
+      else if $(MSVCDir)
+      {
+        TOOLSET = VISUALC ;
+        VISUALC = $(MSVCDir:J=" ") ;
+      }
+      else if $(MINGW)
+      {
+        TOOLSET = MINGW ;
+      }
+      else
+      {
+        ECHO  "Jam cannot be run because, either:" ;
+        ECHO  "   a. You didn't set BOOST_ROOT to indicate the root of your" ;
+        ECHO  "      Boost installation." ;
+        ECHO  "   b. You are trying to use stock Jam but didn't indicate which" ;
+        ECHO  "      compilation toolset to use. To do so, follow these simple" ;
+        ECHO  "      instructions:" ;
+        ECHO  ;
+        ECHO  "  - define one of the following environment variable, with the" ;
+        ECHO  "    appropriate value according to this list:" ;
+        ECHO  ;
+        ECHO  "   Variable    Toolset                      Description" ;
+        ECHO  ;
+        ECHO  "   BORLANDC    Borland C++                  BC++ install path" ;
+        ECHO  "   VISUALC     Microsoft Visual C++         VC++ install path" ;
+        ECHO  "   VISUALC16   Microsoft Visual C++ 16 bit  VC++ 16 bit install" ;
+        ECHO  "   INTELC      Intel C/C++                  IC++ install path" ;
+        ECHO  "   WATCOM      Watcom C/C++                 Watcom install path" ;
+        ECHO  "   MINGW       MinGW (gcc)                  MinGW install path" ;
+        ECHO  "   LCC         Win32-LCC                    LCC-Win32 install path" ;
+        ECHO  ;
+        ECHO  "  - define the JAM_TOOLSET environment variable with the *name*" ;
+        ECHO  "    of the toolset variable you want to use." ;
+        ECHO  ;
+        ECHO  "  e.g.:  set VISUALC=C:\\Visual6" ;
+        ECHO  "         set JAM_TOOLSET=VISUALC" ;
+        EXIT  ;
+      }
+    }
+
+    CP          ?= copy ;
+    RM          ?= del /f/q ;
+    SLASH       ?= \\ ;
+    SUFLIB      ?= .lib ;
+    SUFOBJ      ?= .obj ;
+    SUFEXE      ?= .exe ;
+
+    if $(TOOLSET) = BORLANDC
+    {
+    ECHO "Compiler is Borland C++" ;
+
+    AR          ?= tlib /C /P64 ;
+    CC          ?= bcc32 ;
+    CCFLAGS     ?= -q -y -d -v -w-par -w-ccc -w-rch -w-pro -w-aus ;
+    C++         ?= bcc32 ;
+    C++FLAGS    ?= -q -y -d -v -w-par -w-ccc -w-rch -w-pro -w-aus -P ;
+    LINK        ?= $(CC) ;
+    LINKFLAGS   ?= $(CCFLAGS) ;
+    STDLIBPATH  ?= $(BORLANDC)\\lib ;
+    STDHDRS     ?= $(BORLANDC)\\include ;
+    NOARSCAN    ?= true ;
+    }
+    else if $(TOOLSET) = VISUALC16
+    {
+    ECHO "Compiler is Microsoft Visual C++ 16 bit" ;
+
+    AR          ?= lib /nologo ;
+    CC          ?= cl /nologo ;
+    CCFLAGS     ?= /D \"WIN\" ;
+    C++         ?= $(CC) ;
+    C++FLAGS    ?= $(CCFLAGS) ;
+    LINK        ?= $(CC) ;
+    LINKFLAGS   ?= $(CCFLAGS) ;
+    LINKLIBS    ?= 
+                \"$(VISUALC16)\\lib\\mlibce.lib\"
+                \"$(VISUALC16)\\lib\\oldnames.lib\"
+                ;
+    LINKLIBS    ?= ;
+    NOARSCAN    ?= true ;
+    OPTIM       ?= "" ;
+    STDHDRS     ?= $(VISUALC16)\\include ;
+    UNDEFFLAG   ?= "/u _" ;
+    }
+    else if $(TOOLSET) = VISUALC
+    {
+    ECHO "Compiler is Microsoft Visual C++" ;
+
+    AR          ?= lib ;
+    AS          ?= masm386 ;
+    CC          ?= cl /nologo ;
+    CCFLAGS     ?= "" ;
+    C++         ?= $(CC) ;
+    C++FLAGS    ?= $(CCFLAGS) ;
+    LINK        ?= link /nologo ;
+    LINKFLAGS   ?= "" ;
+    LINKLIBS    ?= \"$(VISUALC)\\lib\\advapi32.lib\"
+                   # $(VISUALC)\\lib\\libc.lib
+                   # $(VISUALC)\\lib\\oldnames.lib
+                   \"$(VISUALC)\\lib\\gdi32.lib\"
+                   \"$(VISUALC)\\lib\\user32.lib\"
+                   \"$(VISUALC)\\lib\\kernel32.lib\" ;
+    OPTIM       ?= "" ;
+    STDHDRS     ?= $(VISUALC)\\include ;
+    UNDEFFLAG   ?= "/u _" ;
+    }
+    else if $(TOOLSET) = VC7
+    {
+    ECHO "Compiler is Microsoft Visual C++ .NET" ;
+
+    AR          ?= lib ;
+    AS          ?= masm386 ;
+    CC          ?= cl /nologo ;
+    CCFLAGS     ?= "" ;
+    C++         ?= $(CC) ;
+    C++FLAGS    ?= $(CCFLAGS) ;
+    LINK        ?= link /nologo ;
+    LINKFLAGS   ?= "" ;
+    LINKLIBS    ?= \"$(VISUALC)\\PlatformSDK\\lib\\advapi32.lib\"
+                   # $(VISUALC)\\lib\\libc.lib
+                   # $(VISUALC)\\lib\\oldnames.lib
+                   \"$(VISUALC)\\PlatformSDK\\lib\\gdi32.lib\"
+                   \"$(VISUALC)\\PlatformSDK\\lib\\user32.lib\"
+                   \"$(VISUALC)\\PlatformSDK\\lib\\kernel32.lib\" ;
+    OPTIM       ?= "" ;
+    STDHDRS     ?= \"$(VISUALC)\\include\"
+									 \"$(VISUALC)\\PlatformSDK\\include\" ;
+    UNDEFFLAG   ?= "/u _" ;
+    }
+    else if $(TOOLSET) = INTELC
+    {
+    ECHO "Compiler is Intel C/C++" ;
+
+        if ! $(VISUALC)
+        {
+          ECHO "As a special exception, when using the Intel C++ compiler, you need" ;
+          ECHO "to define the VISUALC environment variable to indicate the location" ;
+          ECHO "of your Visual C++ installation. Aborting.." ;
+          EXIT ;
+        }
+
+    AR          ?= lib ;
+    AS          ?= masm386 ;
+    CC          ?= icl /nologo ;
+    CCFLAGS     ?= "" ;
+    C++         ?= $(CC) ;
+    C++FLAGS    ?= $(CCFLAGS) ;
+    LINK        ?= link /nologo ;
+    LINKFLAGS   ?= "" ;
+    LINKLIBS    ?= $(VISUALC)\\lib\\advapi32.lib
+                   # $(VISUALC)\\lib\\libc.lib
+                   # $(VISUALC)\\lib\\oldnames.lib
+                   $(VISUALC)\\lib\\kernel32.lib
+                   ;
+    OPTIM       ?= "" ;
+    STDHDRS     ?= $(INTELC)\include $(VISUALC)\\include ;
+    UNDEFFLAG   ?= "/u _" ;
+    }
+    else if $(TOOLSET) = WATCOM
+    {
+        ECHO "Compiler is Watcom C/C++" ;
+
+    AR          ?= wlib ;
+    CC          ?= wcc386 ;
+    CCFLAGS     ?= /zq /DWIN32 /I$(WATCOM)\\h ; # zq=quiet
+    C++         ?= wpp386 ;
+    C++FLAGS    ?= $(CCFLAGS) ;
+    CP          ?= copy ;
+    DOT         ?= . ;
+    DOTDOT      ?= .. ;
+    LINK        ?= wcl386 ;
+    LINKFLAGS   ?= /zq ; # zq=quiet
+    LINKLIBS    ?= ;
+    MV          ?= move ;
+    NOARSCAN    ?= true ;
+    OPTIM       ?= ;
+    RM          ?= del /f ;
+    SLASH       ?= \\ ;
+    STDHDRS     ?= $(WATCOM)\\h $(WATCOM)\\h\\nt ;
+    SUFEXE      ?= .exe ;
+    SUFLIB      ?= .lib ;
+    SUFOBJ      ?= .obj ;
+    UNDEFFLAG   ?= "/u _" ;
+    }
+    else if $(TOOLSET) = MINGW
+    {
+        ECHO "Compiler is GCC with Mingw" ;
+        
+        AR              ?= ar -ru ;
+        CC              ?= gcc ;
+        CCFLAGS         ?= "" ;
+        C++             ?= $(CC) ;
+        C++FLAGS        ?= $(CCFLAGS) ;
+        LINK            ?= $(CC) ;
+        LINKFLAGS       ?= "" ;
+        LINKLIBS        ?= "" ;
+        OPTIM           ?= ;
+        SUFOBJ           = .o ;
+        SUFLIB           = .a ;
+        SLASH            = / ;
+#       NOARSCAN        ?= true ;
+    }
+    else if $(TOOLSET) = LCC
+    {
+        ECHO "Compiler is Win32-LCC" ;
+        
+        AR              ?= lcclib ;
+        CC              ?= lcc ;
+        CCFLAGS         ?= "" ;
+        C++             ?= $(CC) ;
+        C++FLAGS        ?= $(CCFLAGS) ;
+        LINK            ?= lcclnk ;
+        LINKFLAGS       ?= "" ;
+        LINKLIBS        ?= "" ;
+        OPTIM           ?= ;
+        NOARSCAN         = true ;
+    }
+    else
+    {
+#
+# XXX: We need better comments here !!
+#    
+    EXIT On NT, set BCCROOT, MSVCNT, MINGW or MSVC to the root of the
+        Borland or Microsoft directories. ;
+    }
+
+}
+else if $(OS2)
+{
+    # the list of supported toolsets on Windows NT and Windows 95/98
+    #
+    local SUPPORTED_TOOLSETS = "EMX" "WATCOM" ;
+  
+    # this variable holds the current toolset
+    #
+    TOOLSET = "" ;
+    
+    # if the JAM_TOOLSET environment variable is defined, check that it is
+    # one of our supported values
+    #
+    if $(JAM_TOOLSET)
+    {
+      local t ;
+      
+      for t in $(SUPPORTED_TOOLSETS)
+      {
+        $(t) = $($(t):J=" ") ; # reconstitute paths with spaces in them
+        if $(t) = $(JAM_TOOLSET) { TOOLSET = $(t) ; }
+      }
+
+      if ! $(TOOLSET)
+      {
+        ECHO  "The JAM_TOOLSET environment variable is defined but its value" ;
+        ECHO  "is invalid, please use one of the following:" ;
+        ECHO  ;
+        
+        for t in $(SUPPORTED_TOOLSETS) { ECHO "  " $(t) ; }
+        EXIT ;
+      }
+    }
+    
+    # if TOOLSET is empty, we'll try to detect the toolset from other
+    # environment variables to remain backwards compatible with Jam 2.3
+    #
+    if ! $(TOOLSET)
+    {
+      if $(watcom)
+      {
+        WATCOM   = $(watcom:J=" ") ;
+        TOOLSET  = WATCOM ;
+      }
+      else
+      {
+        ECHO  "Jam cannot be run because you didn't indicate which compilation toolset" ;
+        ECHO  "to use. To do so, follow these simple instructions:" ;
+        ECHO  ;
+        ECHO  "  - define one of the following environment variable, with the" ;
+        ECHO  "    appropriate value according to this list:" ;
+        ECHO  ;
+        ECHO  "   Variable    Toolset                      Description" ;
+        ECHO  ;
+        ECHO  "   WATCOM      Watcom C/C++                 Watcom install path" ;
+        ECHO  "   EMX         EMX (gcc)                    EMX install path" ;
+        ECHO  "   VISUALAGE   IBM Visual Age C/C++         VisualAge install path" ;
+        ECHO  ;
+        ECHO  "  - define the JAM_TOOLSET environment variable with the *name*" ;
+        ECHO  "    of the toolset variable you want to use." ;
+        ECHO  ;
+        ECHO  "  e.g.:  set WATCOM=C:\WATCOM" ;
+        ECHO  "         set JAM_TOOLSET=WATCOM" ;
+        ECHO  ;
+        EXIT  ;
+      }
+    }
+
+    RM       = del /f ;
+    CP       = copy ;
+    MV      ?= move ;
+    DOT     ?= . ;
+    DOTDOT  ?= .. ;
+    SUFLIB  ?= .lib ;
+    SUFOBJ  ?= .obj ;
+    SUFEXE  ?= .exe ;
+  
+    if $(TOOLSET) = WATCOM
+    {
+       AR           ?= wlib ;
+       BINDIR       ?= \\os2\\apps ;
+       CC           ?= wcc386 ;
+       CCFLAGS      ?= /zq /DOS2 /I$(WATCOM)\\h ; # zq=quiet
+       C++          ?= wpp386 ;
+       C++FLAGS     ?= $(CCFLAGS) ;
+       LINK         ?= wcl386 ;
+       LINKFLAGS    ?= /zq ; # zq=quiet
+       LINKLIBS     ?= ;
+       NOARSCAN     ?= true ;
+       OPTIM        ?= ;
+       SLASH        ?= \\ ;
+       STDHDRS      ?= $(WATCOM)\\h ;
+       UNDEFFLAG    ?= "/u _" ;
+    }
+    else if $(TOOLSET) = EMX
+    {
+      ECHO "Compiler is GCC-EMX" ;
+      AR            ?= ar -ru ;
+      CC            ?= gcc ;
+      CCFLAGS       ?= "" ;
+      C++           ?= $(CC) ;
+      C++FLAGS      ?= $(CCFLAGS) ;
+      LINK          ?= $(CC) ;
+      LINKFLAGS     ?= "" ;
+      LINKLIBS      ?= "" ;
+      OPTIM         ?= ;
+      SUFOBJ         = .o ;
+      SUFLIB         = .a ;
+      UNDEFFLAG     ?= "-U" ;
+      SLASH          = / ;
+#     NOARSCAN      ?= true ;
+    }
+    else
+    {
+      # should never happen
+      EXIT  "Sorry, but the $(JAM_TOOLSET) toolset isn't supported for now" ;
+    }
+}
+else if $(VMS)
+{
+    C++         ?= cxx ;
+    C++FLAGS    ?= ;
+    CC          ?= cc ;
+    CCFLAGS     ?= ;
+    CHMOD       ?= set file/prot= ;
+    CP          ?= copy/replace ;
+    CRELIB      ?= true ;
+    DOT         ?= [] ;
+    DOTDOT      ?= [-] ;
+    EXEMODE     ?= (w:e) ;
+    FILEMODE    ?= (w:r) ;
+    HDRS        ?= ;
+    LINK        ?= link ;
+    LINKFLAGS   ?= "" ;
+    LINKLIBS    ?= ;
+    MKDIR       ?= create/dir ;
+    MV          ?= rename ;
+    OPTIM       ?= "" ;
+    RM          ?= delete ;
+    RUNVMS      ?= mcr ;
+    SHELLMODE   ?= (w:er) ;
+    SLASH       ?= . ;
+    STDHDRS     ?= decc$library_include ;
+    SUFEXE      ?= .exe ;
+    SUFLIB      ?= .olb ;
+    SUFOBJ      ?= .obj ;
+
+    switch $(OS) 
+    {
+    case OPENVMS : CCFLAGS  ?= /stand=vaxc ;
+    case VMS     : LINKLIBS ?= sys$library:vaxcrtl.olb/lib ;
+    }
+}
+else if $(MAC)
+{
+    local OPT ;
+    
+    CW  ?= "{CW}" ;
+
+    MACHDRS ?=
+        "$(UMACHDRS):Universal:Interfaces:CIncludes"
+        "$(CW):MSL:MSL_C:MSL_Common:Include"
+        "$(CW):MSL:MSL_C:MSL_MacOS:Include" ;
+
+    MACLIBS ?=
+        "$(CW):MacOS Support:Universal:Libraries:StubLibraries:Interfacelib"
+        "$(CW):MacOS Support:Universal:Libraries:StubLibraries:Mathlib" ;
+
+    MPWLIBS ?= 
+        "$(CW):MacOS Support:Libraries:Runtime:Runtime PPC:MSL MPWCRuntime.lib"
+        "$(CW):MSL:MSL_C:MSL_MacOS:Lib:PPC:MSL C.PPC MPW.Lib" ;
+
+    MPWNLLIBS ?= 
+        "$(CW):MacOS Support:Libraries:Runtime:Runtime PPC:MSL MPWCRuntime.lib"
+        "$(CW):MSL:MSL_C:MSL_MacOS:Lib:PPC:MSL C.PPC MPW(NL).Lib" ;
+        
+    SIOUXHDRS ?= ;
+    
+    SIOUXLIBS ?= 
+        "$(CW):MacOS Support:Libraries:Runtime:Runtime PPC:MSL RuntimePPC.lib"
+        "$(CW):MSL:MSL_C:MSL_MacOS:Lib:PPC:MSL SIOUX.PPC.Lib" 
+        "$(CW):MSL:MSL_C:MSL_MacOS:Lib:PPC:MSL C.PPC.Lib" ;
+
+    C++         ?= mwcppc ;
+    C++FLAGS    ?= -w off -nomapcr ;
+    CC          ?= mwcppc ;
+    CCFLAGS     ?= -w off -nomapcr ;
+    CP          ?= duplicate -y ;
+    DOT         ?= ":" ;
+    DOTDOT      ?= "::" ;
+    HDRS        ?= $(MACHDRS) $(MPWHDRS) ;
+    LINK        ?= mwlinkppc ;
+    LINKFLAGS   ?= -mpwtool -warn ;             
+    LINKLIBS    ?= $(MACLIBS) $(MPWLIBS) ;              
+    MKDIR       ?= newfolder ;
+    MV          ?= rename -y ;
+    NOARSCAN    ?= true ;
+    OPTIM       ?= ;
+    RM          ?= delete -y ;
+    SLASH       ?= ":" ;
+    STDHDRS     ?= ; 
+    SUFLIB      ?= .lib ;
+    SUFOBJ      ?= .o ;
+}
+else if $(OS) = BEOS && $(METROWERKS)
+{
+    AR          ?= mwld -xml -o ;
+    BINDIR      ?= /boot/apps ;
+    CC          ?= mwcc ;
+    CCFLAGS     ?= -nosyspath ;
+    C++         ?= $(CC) ;
+    C++FLAGS    ?= -nosyspath ;
+    FORTRAN     ?= "" ;
+    LIBDIR      ?= /boot/develop/libraries ;
+    LINK        ?= mwld ;
+    LINKFLAGS   ?= "" ;
+    MANDIR      ?= /boot/documentation/"Shell Tools"/HTML ;
+    NOARSCAN    ?= true ;
+    STDHDRS     ?= /boot/develop/headers/posix ;
+}
+else if $(OS) = BEOS 
+{
+    BINDIR      ?= /boot/apps ;
+    CC          ?= gcc ;
+    C++         ?= $(CC) ;
+    FORTRAN     ?= "" ;
+    LIBDIR      ?= /boot/develop/libraries ;
+    LINK        ?= gcc ;
+    LINKLIBS    ?= -lnet ;
+    NOARSCAN    ?= true ;
+    STDHDRS     ?= /boot/develop/headers/posix ;
+}
+else if $(UNIX)
+{
+    switch $(OS)
+    {
+    case AIX :
+    LINKLIBS    ?= -lbsd ;
+
+    case AMIGA :
+    CC          ?= gcc ;
+    YACC        ?= "bison -y" ;
+
+    case CYGWIN :   
+    CC          ?= gcc ;
+    CCFLAGS     += -D__cygwin__ ;
+    LEX         ?= flex ;
+    RANLIB      ?= "" ;
+    SUFEXE      ?= .exe ;
+    YACC        ?= "bison -y" ;
+
+    case DGUX :
+    RANLIB      ?= "" ;
+    RELOCATE    ?= true ;
+
+    case HPUX :
+    YACC        = ;
+    CFLAGS      += -Ae ;
+    CCFLAGS     += -Ae ;
+    RANLIB      ?= "" ;
+
+    case INTERIX :
+    CC          ?= gcc ;
+    RANLIB      ?= "" ;
+
+    case IRIX :
+    RANLIB      ?= "" ;
+
+    case MPEIX :
+    CC          ?= gcc ;
+    C++         ?= gcc ;
+    CCFLAGS     += -D_POSIX_SOURCE ;
+    HDRS        += /usr/include ;
+    RANLIB      ?= "" ; 
+    NOARSCAN    ?= true ;
+    NOARUPDATE  ?= true ;
+
+    case MVS :
+    RANLIB      ?= "" ; 
+
+    case NEXT :
+    AR          ?= libtool -o ;
+    RANLIB      ?= "" ;
+
+    case MACOSX :
+    AR          ?= libtool -o ;
+    C++         ?= c++ ;
+    MANDIR      ?= /usr/local/share/man ;
+    RANLIB      ?= "" ;
+
+    case NCR :
+    RANLIB      ?= "" ;
+
+    case PTX :
+    RANLIB      ?= "" ;
+
+    case QNX :
+    AR          ?= wlib ;
+    CC          ?= cc ;
+    CCFLAGS     ?= -Q ; # quiet
+    C++         ?= $(CC) ;
+    C++FLAGS    ?= -Q ; # quiet
+    LINK        ?= $(CC) ;
+    LINKFLAGS   ?= -Q ; # quiet
+    NOARSCAN    ?= true ;
+    RANLIB      ?= "" ;
+
+    case SCO :
+    RANLIB      ?= "" ;
+    RELOCATE    ?= true ;
+
+    case SINIX :
+    RANLIB      ?= "" ;
+
+    case SOLARIS :
+    RANLIB      ?= "" ;
+    AR          ?= "/usr/ccs/bin/ar ru" ;
+
+    case UNICOS :
+    NOARSCAN    ?= true ;
+    OPTIM       ?= -O0 ;
+
+    case UNIXWARE :
+    RANLIB      ?= "" ;
+    RELOCATE    ?= true ;
+    }
+
+    # UNIX defaults
+
+    CCFLAGS     ?= ;
+    C++FLAGS    ?= $(CCFLAGS) ;
+    CHMOD       ?= chmod ;
+    CHGRP       ?= chgrp ;
+    CHOWN       ?= chown ;
+    LEX         ?= lex ;
+    LINKFLAGS   ?= $(CCFLAGS) ;
+    LINKLIBS    ?= ;
+    OPTIM       ?= -O ;
+    RANLIB      ?= ranlib ;
+    YACC        ?= yacc ;
+    YACCFILES   ?= y.tab ;
+    YACCFLAGS   ?= -d ;
+}
+
+#
+# General defaults; a lot like UNIX
+#
+
+    AR          ?= ar ru ;
+    AS          ?= as ;
+    ASFLAGS     ?= ;
+    AWK         ?= awk ;
+    BINDIR      ?= /usr/local/bin ;
+    C++         ?= cc ;
+    C++FLAGS    ?= ;
+    CC          ?= cc ;
+    CCFLAGS     ?= ;
+    CP          ?= cp -f ;
+    CRELIB      ?= ;
+    DOT         ?= . ;
+    DOTDOT      ?= .. ;
+    EXEMODE     ?= 711 ;
+    FILEMODE    ?= 644 ;
+    FORTRAN     ?= f77 ;
+    FORTRANFLAGS ?= ;
+    HDRS        ?= ;
+    INSTALLGRIST ?= installed ;
+    JAMFILE     ?= Jamfile ;
+    JAMRULES    ?= Jamrules ;
+    LEX         ?= ;
+    LIBDIR      ?= /usr/local/lib ;
+    LINK        ?= $(CC) ;
+    LINKFLAGS   ?= ;
+    LINKLIBS    ?= ;
+    LN          ?= ln ;
+    MANDIR      ?= /usr/local/man ;
+    MKDIR       ?= mkdir ;
+    MV          ?= mv -f ;
+    OPTIM       ?= ;
+    RCP         ?= rcp ;
+    RM          ?= rm -f ;
+    RSH         ?= rsh ;
+    SED         ?= sed ;
+    SHELLHEADER ?= "#!/bin/sh" ;
+    SHELLMODE   ?= 755 ;
+    SLASH       ?= / ;
+    STDHDRS     ?= /usr/include ;
+    SUFEXE      ?= "" ;
+    SUFLIB      ?= .a ;
+    SUFOBJ      ?= .o ;
+    UNDEFFLAG   ?= "-u _" ;
+    YACC        ?= ;
+    YACCFILES   ?= ;
+    YACCFLAGS   ?= ;
+
+    HDRPATTERN = 
+            "^[     ]*#[    ]*include[  ]*[<\"]([^\">]*)[\">].*$" ;
+
+    OSFULL = $(OS)$(OSVER)$(OSPLAT) $(OS)$(OSPLAT) $(OS)$(OSVER) $(OS) ;
+
+
+#
+# Base dependencies - first for "bootstrap" kinds of rules
+#
+
+DEPENDS all : shell files lib exe obj ;
+DEPENDS all shell files lib exe obj : first ;
+NOTFILE all first shell files lib exe obj dirs clean uninstall ;
+ALWAYS clean uninstall ;
+
+#
+# Rules
+#
+
+rule As
+{
+    DEPENDS $(<) : $(>) ;
+    ASFLAGS on $(<) += $(ASFLAGS) $(SUBDIRASFLAGS) ;
+}
+
+rule Bulk
+{
+    local i ;
+
+    for i in $(>)
+    {
+        File $(i:D=$(<)) : $(i) ;
+    }
+}
+
+rule Cc
+{
+    local _h ;
+
+    DEPENDS $(<) : $(>) ;
+
+    # Just to clarify here: this sets the per-target CCFLAGS to
+    # be the current value of (global) CCFLAGS and SUBDIRCCFLAGS.
+
+    CCFLAGS on $(<) += $(CCFLAGS) $(SUBDIRCCFLAGS) ;
+
+    # If the compiler's -o flag doesn't work, relocate the .o
+
+    if $(RELOCATE)
+    {
+        CcMv $(<) : $(>) ;
+    }
+
+    _h = $(SEARCH_SOURCE) $(HDRS) $(SUBDIRHDRS) ;
+
+    if $(VMS) && $(_h)
+    {
+        SLASHINC on $(<) = "/inc=(" $(_h[1]) ,$(_h[2-]) ")" ;
+    }
+    else if $(MAC) && $(_h)
+    {
+        local _i _j ;
+        _j = $(_h[1]) ;
+        for _i in $(_h[2-])
+        {
+            _j = $(_j),$(_i) ;
+        }
+        MACINC on $(<) = \"$(_j)\" ;
+    }
+}
+
+rule C++
+{
+    local _h ;
+
+    DEPENDS $(<) : $(>) ;
+    C++FLAGS on $(<) += $(C++FLAGS) $(SUBDIRC++FLAGS) ;
+
+    if $(RELOCATE)
+    {
+        CcMv $(<) : $(>) ;
+    }
+
+    _h = $(SEARCH_SOURCE) $(HDRS) $(SUBDIRHDRS) ;
+
+    if $(VMS) && $(_h)
+    {
+        SLASHINC on $(<) = "/inc=(" $(_h[1]) ,$(_h[2-]) ")" ;
+    }
+    else if $(MAC) && $(_h)
+    {
+        local _i _j ;
+        _j = $(_h[1]) ;
+        for _i in $(_h[2-])
+        {
+            _j = $(_j),$(_i) ;
+        }
+        MACINC on $(<) = \"$(_j)\" ;
+    }
+}
+
+rule Chmod
+{
+    if $(CHMOD) { Chmod1 $(<) ; }
+}
+
+rule File
+{
+    DEPENDS files : $(<) ;
+    DEPENDS $(<) : $(>) ;
+    SEARCH on $(>) = $(SEARCH_SOURCE) ;
+    MODE on $(<) = $(FILEMODE) ;
+    Chmod $(<) ;
+}
+
+rule Fortran
+{
+    DEPENDS $(<) : $(>) ;
+}
+
+rule GenFile 
+{
+    local _t = [ FGristSourceFiles $(<) ] ;
+    local _s = [ FAppendSuffix $(>[1]) : $(SUFEXE) ] ;
+    Depends $(_t) : $(_s) $(>[2-]) ;
+    GenFile1 $(_t) : $(_s) $(>[2-]) ;
+    Clean clean : $(_t) ;
+}
+
+rule GenFile1
+{
+    MakeLocate $(<) : $(LOCATE_SOURCE) ;
+    SEARCH on $(>) = $(SEARCH_SOURCE) ;
+}
+
+rule HardLink
+{
+    DEPENDS files : $(<) ;
+    DEPENDS $(<) : $(>) ;
+    SEARCH on $(>) = $(SEARCH_SOURCE) ;
+}
+
+rule HdrMacroFile
+{
+  # HdrMacroFile file ;
+  #
+  # this rule is used to indicate that a given file contains definitions
+  # for filename macros (e.g. "#define  MYFILE_H <myfile.h>") that can
+  # later be used in #include statements in the rest of the source
+  #
+  # theses files must be parsed before any make is tried..
+  #
+  HDRMACRO $(<) ;
+}
+
+rule HdrRule
+{
+    # HdrRule source : headers ;
+
+    # N.B.  This rule is called during binding, potentially after
+    # the fate of many targets has been determined, and must be
+    # used with caution: don't add dependencies to unrelated
+    # targets, and don't set variables on $(<).
+
+    # Tell Jam that anything depending on $(<) also depends on $(>),
+    # set SEARCH so Jam can find the headers, but then say we don't
+    # care if we can't actually find the headers (they may have been
+    # within ifdefs),
+
+    local s ;
+
+    if $(HDRGRIST) 
+    { 
+        s = $(>:G=$(HDRGRIST)) ;
+    } else { 
+        s = $(>) ; 
+    }
+
+    INCLUDES $(<) : $(s) ;
+    SEARCH on $(s) = $(HDRSEARCH) ;
+    NOCARE $(s) ;
+
+    # Propagate on $(<) to $(>)
+
+    HDRSEARCH on $(s) = $(HDRSEARCH) ;
+    HDRSCAN on $(s) = $(HDRSCAN) ;
+    HDRRULE on $(s) = $(HDRRULE) ;
+    HDRGRIST on $(s) = $(HDRGRIST) ;
+}
+
+rule InstallInto
+{
+    # InstallInto dir : sources ;
+
+    local i t ;
+
+    t = $(>:G=$(INSTALLGRIST)) ;
+
+    # Arrange for jam install
+    # Arrange for jam uninstall
+    # sources are in SEARCH_SOURCE
+    # targets are in dir
+
+    Depends install : $(t) ;
+    Clean uninstall : $(t) ;
+    SEARCH on $(>) = $(SEARCH_SOURCE) ;
+    MakeLocate $(t) : $(<) ;
+
+    # For each source, make gristed target name
+    # and Install, Chmod, Chown, and Chgrp
+
+    for i in $(>)
+    {
+        local tt = $(i:G=$(INSTALLGRIST)) ;
+
+        Depends $(tt) : $(i) ;
+        Install $(tt) : $(i) ;
+        Chmod $(tt) ;
+
+        if $(OWNER) && $(CHOWN) 
+        { 
+        Chown $(tt) ;
+        OWNER on $(tt) = $(OWNER) ;
+        }
+
+        if $(GROUP) && $(CHGRP) 
+        { 
+        Chgrp $(tt) ;
+        GROUP on $(tt) = $(GROUP) ;
+        }
+    }
+}
+
+rule InstallBin
+{
+    local _t = [ FAppendSuffix $(>) : $(SUFEXE) ] ;
+
+    InstallInto $(<) : $(_t) ;
+    MODE on $(_t:G=installed) = $(EXEMODE) ;
+}
+
+rule InstallFile
+{
+    InstallInto $(<) : $(>) ;
+    MODE on $(>:G=installed) = $(FILEMODE) ;
+}
+
+rule InstallLib
+{
+    InstallInto $(<) : $(>) ;
+    MODE on $(>:G=installed) = $(FILEMODE) ;
+}
+
+rule InstallMan
+{
+    # Really this just strips the . from the suffix
+
+    local i s d ;
+
+    for i in $(>)
+    {
+        switch $(i:S)
+        {
+        case .1 : s = 1 ; case .2 : s = 2 ; case .3 : s = 3 ;
+        case .4 : s = 4 ; case .5 : s = 5 ; case .6 : s = 6 ;
+        case .7 : s = 7 ; case .8 : s = 8 ; case .l : s = l ;
+        case .n : s = n ; case .man : s = 1 ;
+        }
+
+        d = man$(s) ;
+
+        InstallInto $(d:R=$(<)) : $(i) ;
+    }
+
+    MODE on $(>:G=installed) = $(FILEMODE) ;
+}
+
+rule InstallShell
+{
+    InstallInto $(<) : $(>) ;
+    MODE on $(>:G=installed) = $(SHELLMODE) ;
+}
+
+rule Lex
+{
+    LexMv $(<) : $(>) ;
+    DEPENDS $(<) : $(>) ;
+    MakeLocate $(<) : $(LOCATE_SOURCE) ;
+    Clean clean : $(<) ;
+}
+
+rule Library
+{
+    LibraryFromObjects $(<) : $(>:S=$(SUFOBJ)) ;
+    Objects $(>) ;
+}
+
+rule LibraryFromObjects
+{
+    local _i _l _s ;
+
+    # Add grist to file names
+
+    _s = [ FGristFiles $(>) ] ;
+    _l = $(<:S=$(SUFLIB)) ;
+
+    # library depends on its member objects
+
+    if $(KEEPOBJS)
+    {
+        DEPENDS obj : $(_s) ;
+    }
+    else
+    {
+        DEPENDS lib : $(_l) ;
+    }
+
+    # Set LOCATE for the library and its contents.  The bound
+    # value shows up as $(NEEDLIBS) on the Link actions.
+    # For compatibility, we only do this if the library doesn't
+    # already have a path.
+
+    if ! $(_l:D)
+    {
+        MakeLocate $(_l) $(_l)($(_s:BS)) : $(LOCATE_TARGET) ;
+    }
+
+    if $(NOARSCAN) 
+    { 
+        # If we can't scan the library to timestamp its contents,
+        # we have to just make the library depend directly on the
+        # on-disk object files.  
+
+        DEPENDS $(_l) : $(_s) ;
+    }
+    else
+    {
+        # If we can scan the library, we make the library depend
+        # on its members and each member depend on the on-disk
+        # object file.
+
+        DEPENDS $(_l) : $(_l)($(_s:BS)) ;
+
+        for _i in $(_s)
+        {
+        DEPENDS $(_l)($(_i:BS)) : $(_i) ;
+        }
+    }
+
+    Clean clean : $(_l) ;
+
+    if $(CRELIB) { CreLib $(_l) : $(_s[1]) ; }
+
+    Archive $(_l) : $(_s) ;
+
+    if $(RANLIB) { Ranlib $(_l) ; }
+
+    # If we can't scan the library, we have to leave the .o's around.
+
+    if ! ( $(NOARSCAN) || $(KEEPOBJS) ) { RmTemps $(_l) : $(_s) ; }
+}
+
+rule Link
+{
+    MODE on $(<) = $(EXEMODE) ;
+    Chmod $(<) ;
+}
+
+rule LinkLibraries
+{
+    # make library dependencies of target
+    # set NEEDLIBS variable used by 'actions Main'
+
+    local _t = [ FAppendSuffix $(<) : $(SUFEXE) ] ;
+
+    DEPENDS $(_t) : $(>:S=$(SUFLIB)) ;
+    NEEDLIBS on $(_t) += $(>:S=$(SUFLIB)) ;
+}
+
+rule Main
+{
+    MainFromObjects $(<) : $(>:S=$(SUFOBJ)) ;
+    Objects $(>) ;
+}
+
+rule MainFromObjects
+{
+    local _s _t ;
+
+    # Add grist to file names
+    # Add suffix to exe
+
+    _s = [ FGristFiles $(>) ] ;
+    _t = [ FAppendSuffix $(<) : $(SUFEXE) ] ;
+
+    if $(_t) != $(<)
+    {
+        DEPENDS $(<) : $(_t) ;
+        NOTFILE $(<) ;
+    }
+
+    # make compiled sources a dependency of target
+
+    DEPENDS exe : $(_t) ;
+    DEPENDS $(_t) : $(_s) ;
+    MakeLocate $(_t) : $(LOCATE_TARGET) ;
+
+    Clean clean : $(_t) ;
+
+    Link $(_t) : $(_s) ;
+}
+
+rule MakeLocate
+{
+    if $(>)
+    {
+        LOCATE on $(<) = $(>) ;
+        Depends $(<) : $(>[1]) ;
+        MkDir $(>[1]) ;
+    }
+}
+
+rule MkDir
+{
+    # If dir exists, don't update it
+    # Do this even for $(DOT).
+
+    NOUPDATE $(<) ;
+
+    if $(<) != $(DOT) && ! $($(<)-mkdir) 
+    {
+        local s ;
+
+        # Cheesy gate to prevent multiple invocations on same dir
+        # MkDir1 has the actions 
+        # Arrange for jam dirs
+
+        $(<)-mkdir = true ;
+        MkDir1 $(<) ;
+        Depends dirs : $(<) ;
+
+        # Recursively make parent directories.
+        # $(<:P) = $(<)'s parent, & we recurse until root
+
+        s = $(<:P) ;
+
+        if $(NT)
+        {
+            switch $(s)
+        {
+        case *:   : s = ;
+        case *:\\ : s = ;
+        }
+        }
+
+        if $(s) && $(s) != $(<)
+        {
+        Depends $(<) : $(s) ;
+        MkDir $(s) ;
+        }
+        else if $(s)
+        {
+            NOTFILE $(s) ;
+        }
+
+    }
+}
+
+rule Object
+{
+    local h ;
+
+    # locate object and search for source, if wanted
+
+    Clean clean : $(<) ;
+
+    MakeLocate $(<) : $(LOCATE_TARGET) ;
+    SEARCH on $(>) = $(SEARCH_SOURCE) ;
+
+    # Save HDRS for -I$(HDRS) on compile.
+    # We shouldn't need -I$(SEARCH_SOURCE) as cc can find headers
+    # in the .c file's directory, but generated .c files (from
+    # yacc, lex, etc) are located in $(LOCATE_TARGET), possibly
+    # different from $(SEARCH_SOURCE).
+
+    HDRS on $(<) = $(SEARCH_SOURCE) $(HDRS) $(SUBDIRHDRS) ;
+
+    # handle #includes for source: Jam scans for headers with
+    # the regexp pattern $(HDRSCAN) and then invokes $(HDRRULE)
+    # with the scanned file as the target and the found headers
+    # as the sources.  HDRSEARCH is the value of SEARCH used for
+    # the found header files.  Finally, if jam must deal with 
+    # header files of the same name in different directories,
+    # they can be distinguished with HDRGRIST.
+
+    # $(h) is where cc first looks for #include "foo.h" files.
+    # If the source file is in a distant directory, look there.
+    # Else, look in "" (the current directory).
+
+    if $(SEARCH_SOURCE)
+    {
+        h = $(SEARCH_SOURCE) ;
+    }
+    else
+    {
+        h = "" ;
+    }
+
+    HDRRULE on $(>) = HdrRule ;
+    HDRSCAN on $(>) = $(HDRPATTERN) ;
+    HDRSEARCH on $(>) = $(HDRS) $(SUBDIRHDRS) $(h) $(STDHDRS) ;
+    HDRGRIST on $(>) = $(HDRGRIST) ;
+
+    # if source is not .c, generate .c with specific rule
+
+    switch $(>:S)
+    {
+        case .asm : As $(<) : $(>) ;
+        case .c :   Cc $(<) : $(>) ;
+        case .C :   C++ $(<) : $(>) ;
+        case .cc :  C++ $(<) : $(>) ;
+        case .cpp : C++ $(<) : $(>) ;
+        case .f :   Fortran $(<) : $(>) ;
+        case .l :   Cc $(<) : $(<:S=.c) ;
+                    Lex $(<:S=.c) : $(>) ;
+        case .s :   As $(<) : $(>) ;
+        case .y :   Cc $(<) : $(<:S=.c) ;
+                    Yacc $(<:S=.c) : $(>) ;
+        case * :    UserObject $(<) : $(>) ;
+    }
+}
+
+
+rule ObjectCcFlags
+{
+    CCFLAGS on [ FGristFiles $(<:S=$(SUFOBJ)) ] += $(>) ;
+}
+
+rule ObjectC++Flags
+{
+    C++FLAGS on [ FGristFiles $(<:S=$(SUFOBJ)) ] += $(>) ;
+}
+
+rule ObjectHdrs
+{
+    HDRS on [ FGristFiles $(<:S=$(SUFOBJ)) ] += $(>) ;
+}
+
+rule Objects
+{
+    local _i ;
+
+    for _i in [ FGristFiles $(<) ]
+    {
+        Object $(_i:S=$(SUFOBJ)) : $(_i) ;
+        DEPENDS obj : $(_i:S=$(SUFOBJ)) ;
+    }
+}
+
+rule RmTemps
+{
+    TEMPORARY $(>) ;
+}
+
+rule Setuid
+{
+    MODE on [ FAppendSuffix $(<) : $(SUFEXE) ] = 4711 ;
+}
+
+rule Shell
+{
+    DEPENDS shell : $(<) ;
+    DEPENDS $(<) : $(>) ;
+    SEARCH on $(>) = $(SEARCH_SOURCE) ;
+    MODE on $(<) = $(SHELLMODE) ;
+    Clean clean : $(<) ;
+    Chmod $(<) ;
+}
+
+rule SubDir
+{
+    local _r _s ;
+
+    #
+    # SubDir TOP d1 [ ... ]
+    #
+    # This introduces a Jamfile that is part of a project tree 
+    # rooted at $(TOP).  It (only once) includes the project-specific
+    # rules file $(TOP)/Jamrules and then sets search & locate stuff.
+    #
+    # If the variable $(TOPRULES) is set (where TOP is the first arg 
+    # to SubDir), that file is included instead of $(TOP)/Jamrules.
+    #
+    # d1 ... are the directory elements that lead to this directory 
+    # from $(TOP).  We construct the system dependent path from these
+    # directory elements in order to set search&locate stuff.
+    # 
+
+    if ! $($(<[1]))
+    {
+        if ! $(<[1])
+        {
+        EXIT SubDir syntax error ;
+        }
+
+        $(<[1]) = [ FSubDir $(<[2-]) ] ;
+    }
+
+    #
+    # If $(TOP)/Jamrules hasn't been included, do so.
+    #
+
+    if ! $($(<[1])-included)
+    {
+        # Gated entry.
+
+        $(<[1])-included = TRUE ;
+
+        # File is $(TOPRULES) or $(TOP)/Jamrules.
+
+        _r = $($(<[1])RULES) ;
+
+        if ! $(_r)
+        {
+        _r = $(JAMRULES:R=$($(<[1]))) ;
+        }
+
+        # Include it.
+
+        include $(_r) ;
+    }
+
+    # Get path to current directory from root using SubDir.
+    # Save dir tokens for other potential uses.
+
+    _s = [ FDirName $(<[2-]) ] ;
+    SUBDIR = $(_s:R=$($(<[1]))) ;
+        SUBDIR_TOKENS = $(<[2-]) ;
+
+    # Now set up SEARCH_SOURCE, LOCATE_TARGET, SOURCE_GRIST
+    # These can be reset if needed.  For example, if the source
+    # directory should not hold object files, LOCATE_TARGET can
+    # subsequently be redefined.
+
+    SEARCH_SOURCE = $(SUBDIR) ;
+    LOCATE_SOURCE = $(ALL_LOCATE_TARGET) $(SUBDIR) ;
+    LOCATE_TARGET = $(ALL_LOCATE_TARGET) $(SUBDIR) ;
+    SOURCE_GRIST = [ FGrist $(<[2-]) ] ;
+
+    # Reset per-directory ccflags, hdrs
+
+    SUBDIRCCFLAGS = ;
+    SUBDIRC++FLAGS = ;
+    SUBDIRHDRS = ;
+}
+
+rule SubDirCcFlags
+{
+    SUBDIRCCFLAGS += $(<) ;
+}
+
+rule SubDirC++Flags
+{
+    SUBDIRC++FLAGS += $(<) ;
+}
+
+rule SubDirHdrs
+{
+    SUBDIRHDRS += $(<) ;
+}
+
+rule SubInclude
+{
+    local _s ;
+
+    # That's
+    #   SubInclude TOP d1 [ d2 [ d3 [ d4 ] ] ]
+    #
+    # to include a subdirectory's Jamfile.
+
+    if ! $($(<[1]))
+    {
+        EXIT Top level of source tree has not been set with $(<[1]) ;
+    }
+
+    _s = [ FDirName $(<[2-]) ] ;
+    
+    include $(JAMFILE:D=$(_s):R=$($(<[1]))) ;
+}
+
+rule Undefines
+{
+    UNDEFS on [ FAppendSuffix $(<) : $(SUFEXE) ] += $(UNDEFFLAG)$(>) ;
+}
+
+rule UserObject
+{
+    EXIT "Unknown suffix on" $(>) "- see UserObject rule in Jamfile(5)." ;
+}
+
+rule Yacc
+{
+    local _h ;
+
+    _h = $(<:BS=.h) ;
+
+    # Some places don't have a yacc.
+
+    MakeLocate $(<) $(_h) : $(LOCATE_SOURCE) ;
+
+    if $(YACC)
+    {
+        DEPENDS $(<) $(_h) : $(>) ;
+        Yacc1 $(<) $(_h) : $(>) ;
+        YaccMv $(<) $(_h) : $(>) ;
+        Clean clean : $(<) $(_h) ;
+    }
+
+    # make sure someone includes $(_h) else it will be
+    # a deadly independent target
+
+    INCLUDES $(<) : $(_h) ;
+}
+
+#
+# Utility rules; no side effects on these
+#
+
+rule FGrist
+{
+    # Turn individual elements in $(<) into grist.
+
+    local _g _i ;
+
+    _g = $(<[1]) ;
+
+    for _i in $(<[2-])
+    {
+        _g = $(_g)!$(_i) ;
+    }
+
+    return $(_g) ;
+}
+
+rule FGristFiles 
+{
+    if ! $(SOURCE_GRIST)
+    {
+        return $(<) ;
+    }
+    else 
+    {
+        return $(<:G=$(SOURCE_GRIST)) ;
+    }
+}
+
+rule FGristSourceFiles
+{
+    # Produce source file name name with grist in it, 
+    # if SOURCE_GRIST is set.
+
+    # Leave header files alone, because they have a global
+    # visibility.
+
+    if ! $(SOURCE_GRIST)
+    {
+        return $(<) ;
+    }
+    else 
+    {
+        local _i _o ;
+
+        for _i in $(<)
+        {
+        switch $(_i)
+        {
+        case *.h :  _o += $(_i) ;
+        case * :    _o += $(_i:G=$(SOURCE_GRIST)) ;
+        }
+        }
+
+        return $(_o) ;
+    }
+}
+
+rule FConcat
+{
+    # Puts the variables together, removing spaces.
+
+    local _t _r ;
+
+    $(_r) = $(<[1]) ;
+
+    for _t in $(<[2-])
+    {
+        $(_r) = $(_r)$(_t) ;
+    }
+
+    return $(_r) ;
+}
+
+rule FSubDir
+{
+    local _i _d ;
+
+    # If $(>) is the path to the current directory, compute the
+    # path (using ../../ etc) back to that root directory.
+    # Sets result in $(<)
+
+    if ! $(<[1]) 
+    {
+        _d = $(DOT) ;
+    } 
+    else
+    {
+        _d = $(DOTDOT) ;
+
+        for _i in $(<[2-])
+        {
+        _d = $(_d:R=$(DOTDOT)) ;
+        }
+    }
+
+    return $(_d) ;
+}
+
+rule FDirName
+{
+    local _s _i ;
+
+    # Turn individual elements in $(<) into a usable path.
+
+    if ! $(<)
+    {
+        _s = $(DOT) ;
+    }
+    else if $(VMS)
+    {
+        # This handles the following cases:
+        #   a -> [.a]
+        #   a b c -> [.a.b.c]
+        #   x: -> x:
+        #   x: a -> x:[a]
+        #   x:[a] b -> x:[a.b]
+
+        switch $(<[1])
+        {
+        case *:* : _s = $(<[1]) ;
+        case \\[*\\] : _s = $(<[1]) ;
+        case * : _s = [.$(<[1])] ;
+        }
+
+        for _i in [.$(<[2-])]
+        {
+        _s = $(_i:R=$(_s)) ;
+        }
+    }
+    else if $(MAC)
+    {
+        _s = $(DOT) ;
+        
+        for _i in $(<)
+        {
+            _s = $(_i:R=$(_s)) ;
+        }
+    }
+    else
+    {
+        _s = $(<[1]) ; 
+
+        for _i in $(<[2-])
+        {
+        _s = $(_i:R=$(_s)) ;
+        }
+    }
+
+    return $(_s) ;
+}
+
+
+rule _makeCommon
+{
+    # strip common initial elements
+
+    if $($(<)[1]) && $($(<)[1]) = $($(>)[1])
+    {
+        $(<) = $($(<)[2-]) ;
+        $(>) = $($(>)[2-]) ;
+        _makeCommon $(<) : $(>) ;
+    }
+}
+
+
+rule FRelPath
+{
+    local _l _r ;
+
+    # first strip off common parts
+
+    _l = $(<) ;
+    _r = $(>) ;
+
+    _makeCommon _l : _r ;
+
+    # now make path to root and path down
+
+    _l = [ FSubDir $(_l) ] ;
+    _r = [ FDirName $(_r) ] ;
+
+    # Concatenate and save
+
+    # XXX This should be better
+
+    if $(_r) = $(DOT) {
+        return $(_l) ;
+    } else {
+        return $(_r:R=$(_l)) ;
+    }
+}
+
+rule FAppendSuffix
+{
+       # E.g., "FAppendSuffix yacc lex foo.bat : $(SUFEXE) ;"
+       # returns (yacc,lex,foo.bat) on Unix and 
+       # (yacc.exe,lex.exe,foo.bat) on NT.
+
+    if $(>)
+    {
+        local _i _o ;
+
+        for _i in $(<)
+        {
+        if $(_i:S)
+        {
+            _o += $(_i) ;
+        }
+        else
+        {
+            _o += $(_i:S=$(>)) ;
+        }
+        }
+        return $(_o) ;
+    }
+    else
+    {
+        return $(<) ;
+    }
+}
+
+rule unmakeDir
+{
+    if $(>[1]:D) && $(>[1]:D) != $(>[1]) && $(>[1]:D) != \\\\ 
+    {
+        unmakeDir $(<) : $(>[1]:D) $(>[1]:BS) $(>[2-]) ;
+    }
+    else
+    {
+        $(<) = $(>) ;
+    }
+}
+
+
+rule FConvertToSlashes
+{
+  local _d, _s, _i ;
+  
+  unmakeDir _d : $(<) ;
+  
+  _s = $(_d[1]) ; 
+  for _i in $(_d[2-])
+  {
+    _s = $(_s)/$(_i) ;
+  }
+  return $(_s) ;
+}
+
+
+#
+# Actions
+#
+
+#
+# First the defaults
+#
+
+actions updated together piecemeal Archive
+{
+    $(AR) $(<) $(>)
+}
+
+actions As
+{
+    $(AS) $(ASFLAGS) -I$(HDRS) -o $(<) $(>)
+}
+
+actions C++
+{
+    $(C++) -c $(C++FLAGS) $(OPTIM) -I$(HDRS) -o $(<) $(>)
+}
+
+actions Cc
+{
+    $(CC) -c $(CCFLAGS) $(OPTIM) -I$(HDRS) -o $(<) $(>)
+}
+
+actions Chgrp
+{
+    $(CHGRP) $(GROUP) $(<)
+}
+
+actions Chmod1
+{
+    $(CHMOD) $(MODE) $(<)
+}
+
+actions Chown
+{
+    $(CHOWN) $(OWNER) $(<)
+}
+
+actions piecemeal together existing Clean
+{
+    $(RM) $(>)
+}
+
+actions File
+{
+    $(CP) $(>) $(<)
+}
+
+actions GenFile1
+{
+    $(>[1]) $(<) $(>[2-])
+}
+
+actions Fortran
+{
+    $(FORTRAN) $(FORTRANFLAGS) -o $(<) $(>)
+}
+
+actions HardLink
+{
+    $(RM) $(<) && $(LN) $(>) $(<)
+}
+
+actions Install
+{
+    $(CP) $(>) $(<) 
+}
+
+actions Lex
+{
+    $(LEX) $(>)
+}
+
+actions LexMv
+{
+    $(MV) lex.yy.c $(<)
+}
+
+actions Link bind NEEDLIBS
+{
+    $(LINK) $(LINKFLAGS) -o $(<) $(UNDEFS) $(>) $(NEEDLIBS) $(LINKLIBS) 
+}
+
+actions MkDir1
+{
+    $(MKDIR) $(<)
+}
+
+actions together Ranlib
+{
+    $(RANLIB) $(<)
+}
+
+actions quietly updated piecemeal together RmTemps
+{
+    $(RM) $(>)
+}
+
+actions Shell
+{
+    $(AWK) '
+        NR == 1 { print "$(SHELLHEADER)" }
+        NR == 1 && /^[#:]/ { next }
+        /^##/ { next }
+        { print }
+    ' < $(>) > $(<)
+}
+
+actions Yacc1
+{
+    $(YACC) $(YACCFLAGS) $(>)
+}
+
+actions YaccMv
+{
+    $(MV) $(YACCFILES).c $(<[1])
+    $(MV) $(YACCFILES).h $(<[2])
+}
+
+#
+# RELOCATE - for compilers with broken -o flags
+#
+
+if $(RELOCATE)
+{
+    actions C++
+    {
+    $(C++) -c $(C++FLAGS) $(OPTIM) -I$(HDRS) $(>)
+    }
+
+    actions Cc
+    {
+    $(CC) -c $(CCFLAGS) $(OPTIM) -I$(HDRS) $(>)
+    }
+
+    actions ignore CcMv
+    {
+    [ $(<) != $(>:BS=$(SUFOBJ)) ] && $(MV) $(>:BS=$(SUFOBJ)) $(<)
+    }
+}
+
+#
+# NOARUPDATE - can't update an archive
+#
+
+if $(NOARUPDATE)
+{
+    actions Archive
+    {
+    $(AR) $(<) $(>)
+    }
+}
+
+#
+# NT specific actions
+#
+
+if $(NT)
+{
+  if $(TOOLSET) = VISUALC || $(TOOLSET) = VC7 || $(TOOLSET) = INTELC
+  {
+    actions updated together piecemeal Archive
+    {
+    if exist $(<) set _$(<:B)_=$(<)
+    $(AR) /out:$(<) %_$(<:B)_% $(>)
+    }
+
+    actions As
+    {
+    $(AS) /Ml /p /v /w2 $(>) $(<) ,nul,nul;
+    }
+
+    actions Cc
+    {
+    $(CC) /c $(CCFLAGS) $(OPTIM) /Fo$(<) /I$(HDRS) /I$(STDHDRS) $(>)
+    }
+
+    actions C++
+    {
+    $(C++) /c $(C++FLAGS) $(OPTIM) /Fo$(<) /I$(HDRS) /I$(STDHDRS) /Tp$(>)
+    }
+
+    actions Link bind NEEDLIBS
+    {
+    $(LINK) $(LINKFLAGS) /out:$(<) $(UNDEFS) $(>) $(NEEDLIBS) $(LINKLIBS)
+    }
+  }
+  else if $(TOOLSET) = VISUALC16
+  {
+    actions updated together piecemeal Archive
+    {
+    $(AR) $(<) -+$(>)
+    }
+
+    actions Cc
+    {
+    $(CC) /c $(CCFLAGS) $(OPTIM) /Fo$(<) /I$(HDRS) $(>)
+    }
+
+    actions C++
+    {
+    $(C++) /c $(C++FLAGS) $(OPTIM) /Fo$(<) /I$(HDRS) /Tp$(>)
+    }
+
+    actions Link bind NEEDLIBS
+    {
+    $(LINK) $(LINKFLAGS) /out:$(<) $(UNDEFS) $(>) $(NEEDLIBS) $(LINKLIBS)
+    }
+  }
+  else if $(TOOLSET) = BORLANDC
+  {
+    actions updated together piecemeal Archive
+    {
+    $(AR) $(<) -+$(>)
+    }
+
+    actions Link bind NEEDLIBS
+    {
+    $(LINK) -e$(<) $(LINKFLAGS) $(UNDEFS) -L$(LINKLIBS) $(NEEDLIBS) $(>)
+    }
+
+    actions C++
+    {
+    $(C++) -c $(C++FLAGS) $(OPTIM) -I$(HDRS) -o$(<) $(>)
+    }
+
+    actions Cc
+    {
+    $(CC) -c $(CCFLAGS) $(OPTIM) -I$(HDRS) -o$(<) $(>)
+    }
+
+  }
+  else if $(TOOLSET) = MINGW
+  {
+    actions together piecemeal Archive
+    {
+      $(AR) $(<) $(>:T)
+    }
+
+    actions Cc
+    {
+    $(CC) -c $(CCFLAGS) $(OPTIM) -I$(HDRS) -o$(<) $(>)
+    }
+
+    actions C++
+    {
+    $(C++) -c $(C++FLAGS) $(OPTIM) -I$(HDRS) -o$(<) $(>)
+    }
+  }
+  else if $(TOOLSET) = WATCOM
+  {
+    actions together piecemeal Archive
+    {
+    $(AR) $(<) +-$(>) 
+    }
+
+    actions Cc
+    {
+    $(CC) $(CCFLAGS) $(OPTIM) /Fo=$(<) /I$(HDRS) $(>)
+    }
+
+    actions C++
+    {
+    $(C++) $(C++FLAGS) $(OPTIM) /Fo=$(<) /I$(HDRS) $(>)
+    }
+
+    actions Link bind NEEDLIBS
+    {
+    $(LINK) $(LINKFLAGS) /Fe=$(<) $(UNDEFS) $(>) $(NEEDLIBS) $(LINKLIBS)
+    }
+
+    actions Shell
+    {
+    $(CP) $(>) $(<)
+    }
+  }
+  else if $(TOOLSET) = LCC
+  {
+    actions together piecemeal Archive
+    {
+    $(AR) /out:$(<) $(>) 
+    }
+
+    actions Cc
+    {
+    $(CC) $(CCFLAGS) $(OPTIM) -Fo$(<) -I$(HDRS) $(>)
+    }
+
+    actions Link bind NEEDLIBS
+    {
+    $(LINK) $(LINKFLAGS) -o $(<) $(UNDEFS) $(>) $(NEEDLIBS) $(LINKLIBS)
+    }
+
+    actions Shell
+    {
+    $(CP) $(>) $(<)
+    }
+  }
+}
+
+#
+# OS2 specific actions
+#
+
+else if $(OS2)             
+{
+  if $(TOOLSET) = WATCOM
+  {
+    actions together piecemeal Archive
+    {
+    $(AR) $(<) +-$(>) 
+    }
+
+    actions Cc
+    {
+    $(CC) $(CCFLAGS) $(OPTIM) /Fo=$(<) /I$(HDRS) $(>)
+    }
+
+    actions C++
+    {
+    $(C++) $(C++FLAGS) $(OPTIM) /Fo=$(<) /I$(HDRS) $(>)
+    }
+
+    actions Link bind NEEDLIBS
+    {
+    $(LINK) $(LINKFLAGS) /Fe=$(<) $(UNDEFS) $(>) $(NEEDLIBS) $(LINKLIBS)
+    }
+
+    actions Shell
+    {
+    $(CP) $(>) $(<)
+    }
+  }
+  else if $(TOOLSET) = EMX
+  {
+    actions together piecemeal Archive
+    {
+      $(AR) $(<) $(>:T)
+    }
+
+    actions Cc
+    {
+    $(CC) -c $(CCFLAGS) $(OPTIM) -I$(HDRS) -o$(<) $(>)
+    }
+
+    actions C++
+    {
+    $(C++) -c $(C++FLAGS) $(OPTIM) -I$(HDRS) -o$(<) $(>)
+    }
+  }
+}
+
+#
+# VMS specific actions
+#
+
+else if $(VMS)
+{
+    actions updated together piecemeal Archive 
+    {
+    lib/replace $(<) $(>[1]) ,$(>[2-])
+    }
+
+    actions Cc
+    { 
+    $(CC)/obj=$(<) $(CCFLAGS) $(OPTIM) $(SLASHINC) $(>) 
+    }
+
+    actions C++
+    { 
+    $(C++)/obj=$(<) $(C++FLAGS) $(OPTIM) $(SLASHINC) $(>) 
+    }
+
+    actions piecemeal together existing Clean
+    {
+    $(RM) $(>[1]);* ,$(>[2-]);*
+    }
+
+    actions together quietly CreLib
+    {
+    if f$search("$(<)") .eqs. "" then lib/create $(<)
+    }
+
+    actions GenFile1
+    {
+    mcr $(>[1]) $(<) $(>[2-])
+    }
+
+    actions Link bind NEEDLIBS
+    {
+    $(LINK)/exe=$(<) $(LINKFLAGS) $(>[1]) ,$(>[2-]) ,$(NEEDLIBS)/lib ,$(LINKLIBS)
+    }
+
+    actions quietly updated piecemeal together RmTemps
+    {
+    $(RM) $(>[1]);* ,$(>[2-]);*
+    }
+
+    actions Shell
+    {
+    $(CP) $(>) $(<)
+    }
+}
+
+#
+# Mac specifc actions
+#
+
+else if $(MAC)
+{
+    actions together Archive 
+    {
+    $(LINK) -library -o $(<) $(>)
+    }
+
+    actions Cc
+    {
+    set -e MWCincludes $(MACINC)
+    $(CC) -o $(<) $(CCFLAGS) $(OPTIM) $(>) 
+    }
+
+    actions C++
+    { 
+    set -e MWCincludes $(MACINC)
+    $(CC) -o $(<) $(C++FLAGS) $(OPTIM) $(>) 
+    }
+
+    actions Link bind NEEDLIBS
+    {
+    $(LINK) -o $(<) $(LINKFLAGS) $(>) $(NEEDLIBS) "$(LINKLIBS)"
+    }
+}
+
+#
+# Backwards compatibility with jam 1, where rules were uppercased.
+#
+
+rule BULK { Bulk $(<) : $(>) ; }
+rule FILE { File $(<) : $(>) ; }
+rule HDRRULE { HdrRule $(<) : $(>) ; }
+rule INSTALL { Install $(<) : $(>) ; }
+rule LIBRARY { Library $(<) : $(>) ; }
+rule LIBS { LinkLibraries $(<) : $(>) ; }
+rule LINK { Link $(<) : $(>) ; }
+rule MAIN { Main $(<) : $(>) ; }
+rule SETUID { Setuid $(<) ; }
+rule SHELL { Shell $(<) : $(>) ; }
+rule UNDEFINES { Undefines $(<) : $(>) ; }
+
+# Old INSTALL* didn't take dest directory.
+
+rule INSTALLBIN { InstallBin $(BINDIR) : $(<) ; }
+rule INSTALLLIB { InstallLib $(LIBDIR) : $(<) ; }
+rule INSTALLMAN { InstallMan $(MANDIR) : $(<) ; }
+
+# Compatibility with jam 2.2.
+
+rule addDirName { $(<) += [ FDirName $(>) ] ; }
+rule makeDirName { $(<) = [ FDirName $(>) ] ; }
+rule makeGristedName { $(<) = [ FGristSourceFiles $(>) ] ; }
+rule makeRelPath { $(<[1]) = [ FRelPath $(<[2-]) : $(>) ] ; }
+rule makeSuffixed { $(<[1]) = [ FAppendSuffix $(>) : $(<[2]) ] ; }
+
+#
+# Now include the user's Jamfile.
+#
+
+{
+    if $(JAMFILE) { include $(JAMFILE) ; }
+}
+
+}

Added: boost-jam/boost-build/branches/upstream/current/jam_src/Jambase.html
===================================================================
--- boost-jam/boost-build/branches/upstream/current/jam_src/Jambase.html	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/jam_src/Jambase.html	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,931 @@
+<HTML>
+<TITLE>
+Jambase Reference
+</TITLE>
+<BODY>
+<CENTER>
+<a href=http://www.perforce.com/jam/jam.html>
+Jam/MR
+</a>
+<H1>
+<A NAME="TOP">
+Jambase Reference
+</A>
+</H1>
+</CENTER>
+<P>
+       Jambase is a base set of Jam/MR rules which
+       provide roughly make(1)-like functionality for 
+       <a href="Jam.html"><b>jam</b></A>, the Jam/MR executable program.
+       This document, which started out as the Jambase(5) man page, 
+       is a reference guide to the 
+       <A href="#RULES">rules</A>,
+       <A href="#PSEUDOTARGETS">pseudotargets</A>,
+       and <A href="#VARS">variables</A> 
+       defined in Jambase for use in Jamfiles.
+<P>
+	For further information see:
+<UL>
+<LI>
+	<a href="Jamfile.html">Using Jamfiles and Jambase</A>
+<LI>
+	<a href="Jam.html">The Jam/MR Executable Program</A>
+</UL>
+<P>
+Jam/MR documentation and source are available from the
+<A HREF=http://public.perforce.com/public/index.html>Perforce Public Depot</a>.
+For detailed information about any of the rules summarized below,
+see the 
+<A HREF=http://public.perforce.com/public/jam/src/Jambase>Jambase</a> 
+file itself.
+<HR>
+<H2>
+<A NAME="RULES">
+Jambase Rules
+</A>
+</H2>
+<P>
+       <B>As</B> <I>obj.o</I> : <I>source.s</I> ;
+<BLOCKQUOTE>
+              Assemble the file <I>source.s.</I>  Called by  the  Object
+              rule.
+</BLOCKQUOTE>
+       <B>Bulk</B> <I>directory</I> : <I>sources</I> ;
+<BLOCKQUOTE>
+              Copies  <I>sources</I>  into  <I>directory.</I>
+</BLOCKQUOTE>
+       <B>Cc</B> <I>object</I> : <I>source</I> ;
+<BLOCKQUOTE>
+              Compile the file <I>source</I> into <I>object,</I>  using  the  C
+              compiler  $(CC), its flags $(CCFLAGS) and $(OPTIM),
+              and the header file directories $(HDRS).  Called by
+              the Object rule.
+</BLOCKQUOTE>
+       <B>C++</B> <I>obj.o</I> : <I>source.cc</I> ;
+<BLOCKQUOTE>
+              Compile  the  C++ source file <I>source.cc.</I>  Called by
+              the Object rule.
+</BLOCKQUOTE>
+	<B>Chmod</B> <I>target</I> ;
+<BLOCKQUOTE>
+		<I>(Unix and VMS only.)</I>
+		Change file permissions on <I>target</I> to
+		target-specific $(MODE) value set by Link, File,
+		Install*, and Shell rules.
+</BLOCKQUOTE>
+
+       <B>Clean</B> <I>clean</I> : <I>targets</I> ;
+<BLOCKQUOTE>
+              Removes  existing  <I>targets</I>  when  <I>clean</I>  is  built.
+              clean is not a dependency of all, and must be built
+              explicitly for targets to be removed.
+</BLOCKQUOTE>
+       <B>FDefines</B> <I>defines</I> ; <BLOCKQUOTE>
+              Expands a list of definitions into a list of compiler
+              (or preprocessor) switches (such as
+               -D<I>symbol</I>=<I>val</I> on Unix)
+              to pass the definitions.
+</BLOCKQUOTE>
+       <B>File</B> <I>target</I> : <I>source</I> ;
+<BLOCKQUOTE>
+              Copies <I>source</I> into <I>target.</I>
+</BLOCKQUOTE>
+       <B>FIncludes</B> <I>dirs</I> ; <BLOCKQUOTE>
+              Expands a list of directories into a list of compiler
+              (or preprocessor) switches (such as -I<I>dir</I> on Unix)
+              to add the directories to the header inclusion search path.
+</BLOCKQUOTE>
+       <B>Fortran</B> <I>obj.o</I> : <I>source.f</I> ;
+<BLOCKQUOTE>
+              Compile the Fortran source file  <I>source.f.</I>   Called
+              by the Object rule.
+</BLOCKQUOTE>
+       <B>FQuote</B> <I>files</I> ; <BLOCKQUOTE>
+              Returns each of <I>files</I> suitably quoted so as to hide shell
+              metacharacters (such as whitespace and filename matching wildcards)
+              from the shell.
+</BLOCKQUOTE>
+<P>
+	<B>GenFile</B> <I>target</I> : <I>image</I> <I>sources</I> ;
+<BLOCKQUOTE>
+		Runs the command "<I>image</I> <I>target</I> <I>sources</I>"
+		to create <I>target</I> from <I>sources</I> and
+		<I>image</I>. (where <I>image</I> is an
+		executable built by the Main rule.)
+</BLOCKQUOTE>
+       <B>HardLink</B> <I>target</I> : <I>source</I> ;
+<BLOCKQUOTE>
+              Makes <I>target</I> a hard link to <I>source,</I> if it isn't one
+              already. (Unix only.)
+</BLOCKQUOTE>
+       <B>HdrRule</B> <I>source</I> : <I>headers</I> ;
+<BLOCKQUOTE>
+              Arranges the  proper  dependencies  when  the  file
+              <I>source</I>  includes  the  files  <I>headers</I>  through  the
+              "#include" C preprocessor  directive.   
+	      <P>
+	      This rule is not intended to be called explicitly.
+	      It is called automatically during header scanning on
+	      sources handled by the Object rule (e.g., sources in
+	      Main or Library rules).
+</BLOCKQUOTE>
+       <B>InstallBin</B> <I>dir</I> : <I>sources</I> ; <BLOCKQUOTE>
+	      Copy <I>sources</I> into <I>dir</I> with mode
+	      $(EXEMODE).  
+</BLOCKQUOTE>
+       <B>InstallLib</B> <I>dir</I> : <I>sources</I> ; <BLOCKQUOTE>
+	      Copy  <I>sources</I>  into  <I>dir</I>  with  mode
+	      $(FILEMODE).  
+</BLOCKQUOTE>
+       <B>InstallMan</B> <I>dir</I> : <I>sources</I> ; <BLOCKQUOTE>
+	      Copy  <I>sources</I>  into the appropriate subdirectory
+	      of <I>dir</I> with mode  $(FILEMODE).   The  subdirectory
+	      is man<I>s,</I>  where  <I>s</I>  is  the suffix of
+	      each of sources.  
+</BLOCKQUOTE>
+       <B>InstallShell</B> <I>dir</I> : <I>sources</I> ; <BLOCKQUOTE>
+	      Copy  <I>sources</I>  into  <I>dir</I>  with  mode
+	      $(SHELLMODE).  
+</BLOCKQUOTE>
+       <B>Lex</B> <I>source.c</I> : <I>source.l</I> ; <BLOCKQUOTE>
+	      Process  the lex(1) source file <I>source.l</I> and
+	      rename the lex.yy.c to <I>source.c.</I>   Called  by
+	      the  Object rule.
+</BLOCKQUOTE>
+       <B>Library</B> <I>library</I> : <I>sources</I> ; <BLOCKQUOTE>
+	      Compiles  <I>sources</I>  and  archives them into
+	      <I>library.</I> The  intermediate  <I>objects</I>
+	      are   deleted.    Calls Objects and LibraryFromObjects.
+	      <P>
+	      If Library is invoked with no suffix on <I>library</I>,
+	      the $(SUFLIB) suffix is used.
+</BLOCKQUOTE>
+       <B>LibraryFromObjects</B> <I>library</I> : <I>objects</I> ; 
+<BLOCKQUOTE>
+	      Archives <I>objects</I> into  <I>library.</I>   The
+	      <I>objects</I>  are then deleted.  
+	      <P>
+	      If <I>library</I> has no suffix, the $(SUFLIB) suffix is used.
+</BLOCKQUOTE>
+	<B>Link</B> <I>image</I> : <I>objects</I> ;
+<BLOCKQUOTE>
+		Links <I>image</I> from <I>objects</I> and sets
+		permissions on <I>image</I> to $(EXEMODE). 
+		 <I>Image</I> must be actual filename; suffix is not
+		 supplied.
+		Called by Main.
+	
+</BLOCKQUOTE>
+       <B>LinkLibraries</B> <I>image</I> : <I>libraries</I> ;
+<BLOCKQUOTE>
+	      Makes  <I>image</I>  depend on <I>libraries</I> and
+	      includes them during the linking.
+	      <P>
+	      <I>Image</I> may be referenced without a suffix in this
+	      rule invocation; LinkLibraries supplies the suffix.
+</BLOCKQUOTE>
+       <B>Main</B> <I>image</I> : <I>sources</I> ; 
+<BLOCKQUOTE>
+	      Compiles <I>sources</I> and links them into <I>image.</I>
+	      Calls Objects and MainFromObjects.  
+	      <P>
+	      <I>Image</I> may be referenced without a suffix in this
+	      rule invocation; Main supplies the suffix.
+</BLOCKQUOTE>
+       <B>MainFromObjects</B> <I>image</I> : <I>objects</I> ;
+<BLOCKQUOTE>
+	      Links <I>objects</I> into <I>image.</I>  Dependency
+	      of exe. MainFromObjects supplies the suffix on <I>image</I>
+	      filename.
+</BLOCKQUOTE>
+	<B>MakeLocate</B> <I>target</I> : <I>dir</I> ;
+<BLOCKQUOTE>
+	Creates <I>dir</I> and causes <I>target</I> to be built
+	into <I>dir</I>.
+</BLOCKQUOTE>
+	<B>MkDir</B> <I>dir</I> ;
+<BLOCKQUOTE>
+	Creates <I>dir</I> and its parent directories.
+</BLOCKQUOTE>
+       <B>Object</B> <I>object</I> : <I>source</I> ; 
+<BLOCKQUOTE>
+	      Compiles  a  <I>single</I> source file source into
+	      <I>object.</I> The Main and Library rules use
+	      this rule to compile source files.
+	      <P>
+	      Causes <I>source</I> to be scanned for "#include" 
+	      directives and calls HdrRule to make all included
+	      files dependedencies of <I>object</I>.
+<P>
+	      Calls one of the following rules to do the actual
+	      compiling, depending on the suffix of source:
+<PRE>
+		     *.c:   Cc 
+		     *.cc:  C++ 
+		     *.cpp: C++
+		     *.C:   C++ 
+		     *.l:   Lex 
+		     *.y:   Yacc
+		     *.*:   UserObject
+</PRE>
+</BLOCKQUOTE>
+       <B>ObjectC++Flags</B> <I>source</I> : <I>flags</I> ; 
+       <BR>
+       <B>ObjectCcFlags</B> <I>source</I> : <I>flags</I> ; 
+<BLOCKQUOTE>
+	      Add   <I>flags</I>   to   the   source-specific
+	      value  of $(CCFLAGS) or $(C++FLAGS) when compiling <I>source.</I>
+	      Any file  suffix on <I>source</I> is ignored.
+</BLOCKQUOTE>
+       <B>ObjectDefines</B> <I>object</I> : <I>defines</I> ; <BLOCKQUOTE>
+              Adds preprocessor symbol definitions to the (gristed)
+              target-specific $(CCDEFS) for the <I>object</i>.
+</BLOCKQUOTE>              	      
+       <B>ObjectHdrs</B> <I>source</I> : <I>dirs</I> ; <BLOCKQUOTE>
+	      Add  <I>dirs</I>  to  the source-specific value of
+	      $(HDRS) when scanning and compiling <I>source.</I>
+	      Any file  suffix on <I>source</I> is ignored.
+</BLOCKQUOTE>
+       <B>Objects</B> <I>sources</I> ; <BLOCKQUOTE>
+	      For  each  source  file in <I>sources,</I> calls
+	      Object to compile the source  file  into  a  similarly
+	      named object file.
+</BLOCKQUOTE>
+       <B>RmTemps</B> <I>targets</I> : <I>sources</I> ; <BLOCKQUOTE>
+	      Marks <I>sources</I> as temporary with the TEMPORARY
+	      rule, and deletes <I>sources</I> once <I>targets</I>
+	      are  built.  Must be  the  last rule invoked on
+	      <I>targets.</I>  Used internally by LibraryFromObjects rule.
+</BLOCKQUOTE>
+       <B>Setuid</B> <I>images</I> ; <BLOCKQUOTE>
+	      Sets the setuid bit on each of <I>images</I>  after
+	      linking. (Unix only.)
+
+</BLOCKQUOTE>
+       <B>SoftLink</B> <I>target</I> : <I>source</I> ;
+<BLOCKQUOTE>
+              Makes <I>target</I> a symbolic link to <I>source,</I> if it isn't one
+              already. (Unix only.)
+</BLOCKQUOTE>
+	<B>SubDir</B> <I>VAR d1 ... dn</I> ;
+<BLOCKQUOTE>
+		Sets up housekeeping for the source files located
+		in <I><CODE>$(VAR)/d1/.../dn</CODE></I>:
+		<UL>
+		<LI>Reads in rules file associated with <I>VAR</I>,
+		    if it hasn't already been read.
+		<LI>Initializes variables for search paths, 
+		    output directories, compiler
+		    flags, and grist, using <I>d1 ... dn</I> tokens.
+		</UL>
+		<P>
+		<I>VAR</I> is the name of a variable; 
+		<I>d1</I> thru <I>dn</I> are elements
+		of a directory path.
+</BLOCKQUOTE>
+	<B>SubDirC++Flags</B> <I>flags</I> ;
+	<BR>
+	<B>SubDirCcFlags</B> <I>flags</I> ;
+<BLOCKQUOTE>
+	Adds <I>flags</I> to the compiler flags for source files
+	in SubDir's directory.
+</BLOCKQUOTE>
+	<B>SubDirHdrs</B> <I>d1 ... dn</I> ;
+<BLOCKQUOTE>
+	Adds the path <I>d1/.../dn/</I> to the header search paths for
+	source files in SubDir's directory. <I>d1</I> through <I>dn</I>
+	are elements of a directory path.
+</BLOCKQUOTE>
+	<B>SubInclude</B> <I>VAR d1 ... dn</I> ;
+<BLOCKQUOTE>
+	Reads the Jamfile in <I><CODE>$(VAR)/d1/.../dn/</CODE></I>. 
+</BLOCKQUOTE>
+       <B>Shell</B> <I>image</I> : <I>source</I> ; <BLOCKQUOTE>
+	      Copies  <I>source</I>  into  the  executable  sh(1)
+	      script <I>image.</I>  Ensures that the first line of
+	      the  script is  $(SHELLHEADER) (default #!/bin/sh).
+</BLOCKQUOTE>
+       <B>Undefines</B> <I>images</I> : <I>symbols</I> ; <BLOCKQUOTE>
+		Adds flags to mark <I>symbols</I> as undefined
+		on link command for <I>images</I>.
+		<I>Images</I> may be referenced unsuffixed; the
+		Undefines rule supplies the suffix.
+</BLOCKQUOTE>
+       <B>UserObject</B> <I>object</I> : <I>source</I> ; <BLOCKQUOTE>
+	      This rule is called by Object for source
+	      files with unknown  suffixes,  and  should  be defined
+	      in Jamrules
+	      with a user-provided rule to handle the source file
+	      types not handled by the Object rule.
+	      The Jambase UserObject rule merely issues a
+	      complaint when it encounters <I>source</I> with
+	      files suffixes it does not recognize.
+</BLOCKQUOTE>
+       <B>Yacc</B> <I>source.c</I> : <I>source.y</I> ; <BLOCKQUOTE>
+	      Process  the  yacc(1) file <I>source.y</I> and renamed
+	      the resulting y.tab.c and y.tab.h  to  <I>source.c.</I>
+	      Produces a y.tab.h and renames it to <I>source.h.</I>
+	      Called by the <B>Object</B> rule.
+</BLOCKQUOTE> 
+<P> 
+<HR>   
+<A NAME="PSEUDOTARGETS">
+<H3>
+Jambase Pseudotargets
+</H3>
+</A>
+<P>
+There are two kinds of Jam targets: file targets and pseudotargets.
+File targets are objects that can be found in the filesystem.
+Pseudotargets are symbolic, and usually represent other targets.
+Most Jambase rules that define file targets also define pseudotargets
+which are dependent on types of file targets. The Jambase pseudotargets
+are:
+<CENTER>
+<TABLE CELLPADDING=5%>
+<TR><TD>exe
+	<TD>Executables linked by the Main or MainFromObjects rules
+
+<TR><TD>lib
+	<TD>Libraries created by the Library or LibraryFromObjects rules
+
+<TR><TD>obj
+	<TD>Compiled objects used to create Main or Library targets
+
+<TR><TD>dirs
+	<TD>Directories where target files are written
+
+<TR><TD>file
+	<TD>Files copied by File and Bulk rules
+
+<TR><TD>shell
+	<TD>Files copied by Shell rule
+
+<TR><TD>clean
+	<TD>Removal of built targets (except files copied by Install* rules)
+
+<TR><TD>install
+	<TD>Files copied by Install* rules
+
+<TR><TD>uninstall
+	<TD>Removal of targets copied by Install* rules
+
+</TABLE>
+</CENTER>
+<P> 
+In addition, Jambase makes the <b>jam</b> default target "all"
+depend on "exe", "lib", "obj", "files", and "shell".
+<P> 
+
+<HR>
+<A NAME="VARS">
+<H3>
+Jambase Variables 
+</H3> 
+</A>
+<P>
+	Most of the following variables have default values for
+	each platform; refer to the Jambase file to see what those
+	defaults are.
+<P>
+	ALL_LOCATE_TARGET
+<BLOCKQUOTE>
+		Alternative location of built targets. By default,
+		Jambase rules locate built targets in the source
+		tree. By setting $(ALL_LOCATE_TARGET)
+		in Jamrules, you can cause <b>jam</b>
+		to write built targets to a location outside
+		the source tree.
+</BLOCKQUOTE>
+
+       AR
+
+<BLOCKQUOTE>
+              The archive command used to update Library
+	      and LibraryFromObjects targets.
+</BLOCKQUOTE>
+       AS
+<BLOCKQUOTE>
+              The assembler for As rule targets.
+</BLOCKQUOTE>
+
+       ASFLAGS
+
+<BLOCKQUOTE>
+              Flags handed to the assembler for As.
+</BLOCKQUOTE>
+
+       AWK
+
+<BLOCKQUOTE>
+              The  name  of  awk interpreter, used when copying a
+              shell script for the Shell rule.
+</BLOCKQUOTE>
+
+	BCCROOT
+<BLOCKQUOTE>
+		Selects Borland compile and link actions on NT.
+</BLOCKQUOTE>
+
+
+       BINDIR
+
+<BLOCKQUOTE>
+              Not longer used. 
+	      (I.e., used only for backward compatibility with the
+	      obsolete INSTALLBIN rule.)
+</BLOCKQUOTE>
+
+       CC
+
+<BLOCKQUOTE>
+              C compiler used for Cc rule targets.
+</BLOCKQUOTE>
+
+       CCFLAGS
+
+<BLOCKQUOTE>
+		Compile flags for Cc rule targets.
+		The Cc rule sets target-specific $(CCFLAGS)
+		values on its targets.
+</BLOCKQUOTE>
+
+       C++
+
+<BLOCKQUOTE>
+              C++ compiler used for C++ rule targets.
+</BLOCKQUOTE>
+
+       C++FLAGS
+
+<BLOCKQUOTE>
+		Compile flags for C++ rule targets.
+		The C++ rule sets target-specific $(C++FLAGS)
+		values on its targets.
+</BLOCKQUOTE>
+
+       CHMOD
+
+<BLOCKQUOTE>
+		Program (usually chmod(1)) used to set file
+		permissions for Chmod rule.
+</BLOCKQUOTE>
+
+       CP
+
+<BLOCKQUOTE>
+              The file copy program, used by File and Install* rules.
+</BLOCKQUOTE>
+
+       CRELIB
+
+<BLOCKQUOTE>
+	      If set, causes the Library rule to invoke the CreLib
+	      rule on the target library before attempting to archive
+	      any members, so that the library can be created if
+	      needed.
+</BLOCKQUOTE>
+
+       CW
+
+<BLOCKQUOTE>
+	      On Macintosh, the root of the Code Warrior Pro 5 directory.
+</BLOCKQUOTE>
+
+       DEFINES
+
+<BLOCKQUOTE>
+	      Preprocessor symbol definitions for Cc and C++ rule targets.
+	      The Cc and C++ rules set target-specific $(CCDEFS)
+	      values on their targets, based on $(DEFINES). (The
+	      "indirection" here is required to support compilers,
+	      like VMS, with baroque command line syntax for
+	      setting symbols).
+</BLOCKQUOTE>
+
+       DOT
+
+<BLOCKQUOTE>
+	      The operating system-specific name for the current directory.
+</BLOCKQUOTE>
+
+       DOTDOT
+
+<BLOCKQUOTE>
+	      The operating system-specific name for the parent directory.
+</BLOCKQUOTE>
+
+       EXEMODE
+
+<BLOCKQUOTE>
+              Permissions for executables linked with Link, Main,
+	      and MainFromObjects, on platforms with a Chmod action.
+</BLOCKQUOTE>
+
+       FILEMODE
+
+<BLOCKQUOTE>
+              Permissions for files copied by File or Bulk,
+	      on platforms with a Chmod action.
+</BLOCKQUOTE>
+
+       FORTRAN
+
+<BLOCKQUOTE>
+              The Fortran compiler used by Fortran rule.
+</BLOCKQUOTE>
+
+       FORTRANFLAGS
+
+<BLOCKQUOTE>
+              Fortran compiler flags for Fortran rule targets.
+</BLOCKQUOTE>
+
+       GROUP
+
+<BLOCKQUOTE>
+		<I>(Unix only.)</I>
+              The  group  owner  for Install* rule targets.
+</BLOCKQUOTE>
+
+       HDRGRIST
+
+<BLOCKQUOTE>
+	      If set, used by the HdrRule to distinguish header files
+	      with the same name in diffrent directories.
+</BLOCKQUOTE>
+
+       HDRPATTERN
+
+<BLOCKQUOTE>
+              A  regular expression  pattern that matches
+	      C preprocessor "#include" directives in source files
+	      and returns the name of the included file.
+</BLOCKQUOTE>
+
+       HDRRULE
+
+<BLOCKQUOTE>
+              Name of the rule to invoke with the results of header file
+              scanning. Default is "HdrRule".
+	      <P>
+	      This is a jam-special variable. If both HDRRULE and HDRSCAN
+	      are set on a target,
+	      that target will be scanned for lines
+	      matching $(HDRSCAN), and $(HDDRULE) will be
+	      invoked on included files found in the matching $(HDRSCAN) lines.
+</BLOCKQUOTE>
+
+       HDRS
+
+<BLOCKQUOTE>
+              Directories to be  searched  for  header  files.
+	      This is used by the Object rule to:
+	      <UL>
+	      <LI>set up search paths for finding files returned
+		  by header scans
+	      <LI>add -I flags on compile commands
+	      </UL>
+	      (See STDHDRS.)
+</BLOCKQUOTE>
+
+       HDRSCAN
+
+<BLOCKQUOTE>
+		Regular expression pattern to use for header file
+		scanning. The Object rule sets this to $(HDRPATTERN).
+              This is a jam-special variable; see HDRRULE.
+</BLOCKQUOTE>
+
+       HDRSEARCH
+
+<BLOCKQUOTE>
+		Used by the HdrRule to fix the list of directories where
+		header files can be found for a given source file.
+</BLOCKQUOTE>
+
+       INSTALLGRIST
+
+<BLOCKQUOTE>
+		Used by the Install* rules to grist paths to installed
+		files; defaults to "installed".
+</BLOCKQUOTE>
+
+       JAMFILE
+
+<BLOCKQUOTE>
+		Default is "Jamfile"; the name of the user-written
+		rules file found in each source directory.
+</BLOCKQUOTE>
+
+       JAMRULES
+
+<BLOCKQUOTE>
+		Default is "Jamrules"; the name of a rule definition
+		file to be read in at the first SubDir rule invocation.
+</BLOCKQUOTE>
+
+       KEEPOBJS
+
+<BLOCKQUOTE>
+	      If set, tells the LibraryFromObjects rule not to delete
+	      object files once they are archived.  
+</BLOCKQUOTE>
+
+       LEX
+
+<BLOCKQUOTE>
+              The lex(1) command and flags.
+</BLOCKQUOTE>
+
+       LIBDIR
+
+<BLOCKQUOTE>
+              Not longer used. 
+	      (I.e., used only for backward compatibility with the
+	      obsolete INSTALLLIB rule.)
+</BLOCKQUOTE>
+
+       LINK
+
+<BLOCKQUOTE>
+              The linker. Defaults to $(CC).
+</BLOCKQUOTE>
+
+       LINKFLAGS
+
+<BLOCKQUOTE>
+              Flags handed to the linker. Defaults to $(CCFLAGS).
+</BLOCKQUOTE>
+
+       LINKLIBS
+
+<BLOCKQUOTE>
+              List of external libraries to link with.  The target  image
+              does not depend on these libraries.
+</BLOCKQUOTE>
+       
+       LN
+
+<BLOCKQUOTE>
+              The hard link command for HardLink rule.
+</BLOCKQUOTE>
+
+	LOCATE_SOURCE
+<BLOCKQUOTE>
+		Used to set the  location of generated source files.
+		The Yacc, Lex, and GenFile rules set LOCATE on
+		their targets to $(LOCATE_SOURCE).
+		$(LOCATE_SOURCE) is initialized by the SubDir rule
+		to the source directory itself.
+		(Also, see ALL_LOCATE_TARGET.)
+</BLOCKQUOTE>
+
+       LOCATE_TARGET
+<BLOCKQUOTE>
+		Used to set the  location of built binary targets. 
+	      The Object rule, and hence the Main and Library rules,
+	      set LOCATE on their targets to $(LOCATE_TARGET).
+		$(LOCATE_TARGET) is initialized by the
+		SubDir rule to the source directory itself.
+		(See ALL_LOCATE_TARGET.)
+</BLOCKQUOTE>
+
+
+       MANDIR
+
+<BLOCKQUOTE>
+              Not longer used. 
+	      (I.e., used only for backward compatibility with the
+	      obsolete INSTALLMAN rule.)
+</BLOCKQUOTE>
+
+       MKDIR
+
+<BLOCKQUOTE>
+              The  'create directory' command used for the MkDir
+              rule.
+</BLOCKQUOTE>
+
+       MODE
+
+<BLOCKQUOTE>
+              The target-specific file mode (permissions) for targets 
+	      of the Shell, Setuid, Link, and Install* rules.
+	      Used by the Chmod action; hence relevant to NT and VMS
+	      only.
+</BLOCKQUOTE>
+	
+	MSVC
+<BLOCKQUOTE>
+		Selects Microsoft Visual C 16-bit compile & link
+		actions on NT.
+</BLOCKQUOTE>
+
+	MSVCNT
+<BLOCKQUOTE>
+		Selects Microsoft Visual C NT compile & link
+		actions on NT.
+</BLOCKQUOTE>
+
+
+       MV
+
+<BLOCKQUOTE>
+              The file rename command and options.
+</BLOCKQUOTE>
+
+       NEEDLIBS
+
+<BLOCKQUOTE>
+	      The list of libraries used when linking an executable.
+	      Used by the Link rule.
+</BLOCKQUOTE>
+
+       NOARSCAN
+
+<BLOCKQUOTE>
+	      If set, indicates that library members' timestamps can't
+	      be found, and prevents the individual objects from being
+	      deleted, so that their timestamps can be used instead.
+</BLOCKQUOTE>
+
+       NOARUPDATE
+
+<BLOCKQUOTE>
+	      If set, indicates that libraries can't be updated, but only
+	      created whole.
+</BLOCKQUOTE>
+
+       OPTIM
+
+<BLOCKQUOTE>
+              The C compiler flag for optimization, used by Cc and C++
+	      rules.
+</BLOCKQUOTE>
+
+       OSFULL
+
+<BLOCKQUOTE>
+              The concatenation of $(OS)$(OSVER)$(OSPLAT), used when jam
+	      builds itself to determine the target binary directory.
+	      $(OS) and $(OSPLAT) are determined by jam at its compile
+	      time (in jam.h).  $(OSVER) can optionally be set by the user.
+
+</BLOCKQUOTE>
+
+       OWNER
+
+<BLOCKQUOTE>
+              The owner of installed files.  Used by Install* rules.
+</BLOCKQUOTE>
+
+       RANLIB
+
+<BLOCKQUOTE>
+		The name of the ranlib command. If set, causes
+		the Ranlib action to be applied after the
+		Archive action to targets of the Library rule.
+</BLOCKQUOTE>
+
+       RELOCATE
+
+<BLOCKQUOTE>
+              If set, tells the Cc rule to move the output object
+              file to its target directory because the cc command
+              has a broken -o option.
+</BLOCKQUOTE>
+
+       RM
+
+<BLOCKQUOTE>
+              The command and options to remove a file.
+</BLOCKQUOTE>
+
+       SEARCH_SOURCE
+
+<BLOCKQUOTE>
+              The  directory  to  find  sources listed with Main,
+              Library, Object,  Bulk,  File,  Shell,  InstallBin,
+              InstallLib,  and  InstallMan  rules.  This works by
+              setting the  jam-special  variable  SEARCH  to  the
+              value  of  $(SEARCH_SOURCE)  for each of the rules'
+              sources. The SubDir rule initializes SEARCH_SOURCE
+	      for each directory.
+</BLOCKQUOTE>
+
+       SHELLHEADER
+
+<BLOCKQUOTE>
+              A string inserted to the first line of  every  file
+              created by the Shell rule.
+</BLOCKQUOTE>
+
+       SHELLMODE
+
+<BLOCKQUOTE>
+              Permissions for files installed by Shell rule.
+</BLOCKQUOTE>
+
+      SOURCE_GRIST
+              
+<BLOCKQUOTE>
+	      Set by the SubDir  to  a  value  derived  from  the
+              directory  name,  and  used  by Objects and related
+              rules as 'grist' to perturb file names.
+</BLOCKQUOTE>
+
+       STDHDRS
+
+<BLOCKQUOTE>
+              Directories where  headers  can  be  found  without
+              resorting to using the flag to the C compiler.
+	      The $(STDHDRS) directories are used to find
+	      headers during scanning, but are not passed to the
+	      compiler commands as -I paths.
+</BLOCKQUOTE>
+
+       SUBDIR
+
+<BLOCKQUOTE>
+	      The path from the current directory to the directory
+	      last named by the SubDir rule.
+</BLOCKQUOTE>
+
+       TOP
+
+<BLOCKQUOTE>
+	      The path from the current directory to the directory
+	      that has the Jamrules file.  Used by the SubDir rule.
+</BLOCKQUOTE>
+
+       SUFEXE
+
+<BLOCKQUOTE>
+              The  suffix for executable files, if none provided.
+              Used by the Main rule.
+</BLOCKQUOTE>
+
+       SUFLIB
+
+<BLOCKQUOTE>
+              The suffix for libraries.  Used by the Library  and
+              related rules.
+</BLOCKQUOTE>
+
+       SUFOBJ
+
+<BLOCKQUOTE>
+              The  suffix  for object files.  Used by the Objects
+              and related rules.
+</BLOCKQUOTE>
+
+       UNDEFFLAG
+
+<BLOCKQUOTE>
+              The flag prefixed to each symbol for the  Undefines
+              rule (i.e., the compiler flag for undefined symbols).
+</BLOCKQUOTE>
+
+	WATCOM
+<BLOCKQUOTE>
+		Selects Watcom compile and link actions on OS2.
+</BLOCKQUOTE>
+
+       YACC
+
+<BLOCKQUOTE>
+              The yacc(1) command.
+</BLOCKQUOTE>
+
+       YACCFILES
+
+<BLOCKQUOTE>
+              The base filename generated by yacc(1).
+</BLOCKQUOTE>
+
+       YACCFLAGS
+
+<BLOCKQUOTE>
+              The yacc(1) command flags.
+</BLOCKQUOTE>
+
+       YACCGEN
+
+<BLOCKQUOTE>
+              The suffix used on generated yacc(1) output.
+</BLOCKQUOTE>
+
+<P>
+<HR>
+<A HREF="#TOP">Back to top.</A>
+<P>
+	Copyright 1993-2002 Christopher Seiwald and Perforce Software, Inc.
+	<BR>
+	Comments to <A HREF="mailto:info at perforce.com">info at perforce.com</A>
+	<BR>
+	Last updated: Dec 31, 2000
+	<BR>
+	$Id: Jambase.html,v 1.4 2002/04/07 00:22:45 david_abrahams Exp $
+</BODY>
+</HTML>

Added: boost-jam/boost-build/branches/upstream/current/jam_src/Jamfile.html
===================================================================
--- boost-jam/boost-build/branches/upstream/current/jam_src/Jamfile.html	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/jam_src/Jamfile.html	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,1450 @@
+<HTML>
+<TITLE>
+Jamfiles and Jambase
+</TITLE>
+<BODY>
+<CENTER>
+<A HREF=http://www.perforce.com/jam/jam.html>
+Jam/MR
+</a>
+<A NAME="TOP">
+<H2>
+Using Jamfiles and Jambase
+</H2>
+</A>
+</CENTER>
+<P>
+This document describes how to write Jamfiles using the Jam/MR Jambase 
+rules to build software products. 
+Related documents of interest are:
+<UL>
+<LI>
+	<a href="Jam.html">The Jam/MR Executable Program</A>,
+	which describes using the <b>jam</b> command and the 
+	langauge used in Jambase
+<LI>
+	<A href="Jambase.html">Jambase Reference</A>,
+	which summarizes the Jambase rules and variables
+</UL>
+<P>
+Jam/MR documentation and source are available from the
+<A HREF=http://public.perforce.com/public/index.html>Perforce Public Depot</a>.
+<HR>
+<P>
+<H2>
+Overview
+</H2>
+<P>
+        <B>jam,</B> the Jam executable program,
+       recursively  builds  target files  from source files
+       using dependency and build specifications defined
+       in Jam rules files.
+        <B>jam</B> parses the rules files to identify targets
+        and sources,
+        examines the filesystem to determine which
+        targets need updating, and issues OS commands to update
+        targets.
+<P>
+        A base rules file called "Jambase" is provided with the 
+	Jam distribution. 
+	The Jambase file defines rules and variables which support
+	standard software build operations, like compiling, linking,
+	etc.
+<P>
+	When the Jambase rules are used,
+	<B>jam</B> reads Jambase, then reads a file called
+	"Jamfile" in the current directory.
+	The Jamfile describes what to do with the source files in 
+	its directory. It may also cause
+	Jamfiles in other directories to be read. 
+	<P>
+	Under certain circumstances, the first Jamfile read
+	also causes a site-specific "Jamrules" file to be read.
+	The Jamrules file is an optional set of rule and variable
+	definitions used to define site-specific processing.
+<P>
+<H4>
+The Basic Jamfile
+</H4>
+<P>
+Jamfiles contain rule invocations, which usually look like:
+<PRE>
+	<I>RuleName</I> <I>targets</I> : <I>targets</I> ;
+</PRE>
+The target(s) to the left of the colon usually indicate
+what gets built, and the target(s) to the right of the
+colon usually indicate what it is built from.
+<P>
+<P>
+A Jamfile can be as simple as this:
+<PRE>
+	Main myprog : main.c util.c ;
+</PRE>
+This specifies that there is a main.c and util.c file in the same
+directory as the Jamfile, and that those source files should be
+compiled and linked into an executable called myprog.
+If you cd to the directory where this Jamfile lives,
+you can see the exactly how <b>jam</b> would 
+build myprog with:
+<PRE>
+	jam -n
+</PRE>
+Or, you can actually build myprog with the command:
+<PRE>
+	jam
+</PRE>
+
+<P>
+<H4>
+Whitespace
+</H4>
+Jamfile elements are delimited by whitespace (blanks, tabs, or
+newlines). Elements to be delimited include rule names, targets,
+colons, and semicolons. A common mistake users make is to forget the
+whitespace, e.g.,
+<PRE>
+	Main myprog: main.c util.c ; #<I>WRONG!</I>
+</PRE>
+Jam doesn't distinguish between a typo and a target called "myprog:", 
+so if you get strange results, the first thing
+you should check for in your Jamfile is missing whitespace.
+<P>
+<H4>
+Filenames, Target Identifiers, and Buildable Targets
+</H4>
+<P>
+Consider this Jamfile:
+<PRE>
+	Main myprog : main.c util.c ;                   
+	LinkLibraries myprog : libtree ;     
+	Library libtree : treemake.c treetrav.c ;    
+</PRE>
+<P>
+The Main rule specifies that an executable called myprog will be built.
+The compiled main.c and util.c objects will be linked to produce
+myprog. 
+The LinkLibraries rule specifies that libtree will
+be linked into myprog as well.
+The Library rule specifies which source files will be compiled and
+archived into the libtree library.
+<P>
+The Jamfile above refers to targets like "myprog" and "libtree". 
+However, depending on the platform you're building on, the actual
+filenames of those targets could be "myprog.exe" and "libtree.lib".
+Most Jambase rules supply the actual filenames of targets,
+so that Jamfiles themselves need not make any
+platform-specific filename references.
+<P>
+The <b>jam</b> program builds up a list of unique target identifiers.
+Unless you are using the SubDir rules (described later),
+the default identifier for a file target is its filename. In the above
+example, the target identifiers are the filenames: myprog.exe,
+libtree.lib, main.obj, etc.
+<P>
+While all Jambase rules refer to "targets",
+not all targets are buildable.
+There are two kinds of buildable targets: 
+file targets and pseudotargets.
+File targets are objects that can be found in the filesystem.
+Pseudotargets are symbolic, and represent other targets.
+<P>
+You can use any buildable target on the <b>jam</b> command line to
+build a subset of defined targets. For example:
+<PRE>
+        jam libtree.a 
+</PRE>
+on Unix builds the libtree library and all the compiled objects
+that go in it.
+<P>
+<H4>
+Pseudotargets
+</H4>
+<P>
+Most Jambase rules that define file targets also define pseudotargets
+which are dependent on types of file targets.
+For example, Jambase defines a pseudotarget called "lib", which 
+is dependent on file targets created by the Library rule. So 
+the command:  
+<PRE>
+        jam lib
+</PRE> 
+used with the above example would cause the libtree library to be built.
+Also, there is one pseudotarget built into <b>jam</b> itself, called
+"all". Jambase sets "all" dependent on (almost) all other targets.
+<P>
+In the unfortunate case where you have a buildable target whose name
+is the same as one of the Jambase pseudotargets, you'll have problems
+with the conflicting target name.
+Your workaround choices are:
+<P>
+<ol>
+<lI>Change the name of your buildable file or directory that conflicts.
+<p>
+<li>Modify your Jambase and change the name of the conflicting pseudotarget.
+(Pseudotargets are defined in Jambase using the NOTFILE rule.)
+<p>
+<li>Use grist on the conflicting target name in your Jamfile. E.g., instead
+    of
+    <PRE>
+    File lib : libfoo.a ;
+    </PRE>
+    try
+    <PRE>
+    File &lt;dir&gt;lib : libfoo.a ;
+    </PRE>
+</ol>
+<P>
+
+<H4>
+Dependencies
+</H4>
+<P>
+Jambase rules set dependencies on targets, so that if you update a
+source file, all the file targets that depend on that source
+file, and only the ones that depend on that source file, 
+will be updated (rebuilt) the next time you run <b>jam</b>. 
+<P>
+Here are some of the dependencies 
+that get set when <b>jam</b> runs on NT using the example Jamfile above:
+<CENTER>
+<TABLE> 
+<TR><TD><B>Target</B><TD>&nbsp;&nbsp;&nbsp;<TD><B>Depends on</B></TD>
+<TR><TD>myprog.exe<TD><TD>main.obj, util.obj, libtree.lib
+<TR><TD>libtree.lib<TD><TD>treemake.obj, treetrav.obj
+<TR><TD>treetrav.obj<TD><TD>treetrav.c
+</TABLE>
+</CENTER>
+<P>
+Furthermore, the Main and Library rules set up recursive
+header scanning on their source targets.
+So after <b>jam</b> has finished parsing the Jamfile and
+setting the rule-driven dependencies, it scans the source 
+files for "#include" lines. All #include files found during
+this scan become dependencies of the compiled object.
+E.g., all header files used to compile treetrav.c would
+be made dependencies of treetrav.obj.
+<P>
+As a result, when you run <b>jam</b>, it will rebuild targets
+if either the source files change or the 
+header files change. You can't tell by looking at a Jamfile
+which header files are dependencies, but you can easily
+display those dependencies with:
+<PRE>
+	jam -nd+3
+</PRE>
+<H4>
+Rule Ordering
+</H4>
+<P>
+Rules which specify dependencies, like the Main, Library, and
+LinkLibrary rules, can be invoked in any order. <b>jam</b>
+figures out the order in which targets are built from 
+their dependencies.
+<P>
+Some rules, however, set variables which are used by subsequent
+rule invocations, and their ordering is important. 
+For example, the SubDir* rules (discussed
+later) must be invoked in a particular order.
+
+<P>
+<H4>
+Detailed Jambase Specifications
+</H4>
+<P>
+This document describes how to use various Jambase rules
+from a functional point of view.
+You can see the summary of available Jambase rules in the
+<a href="Jambase.html">Jambase Reference</A>.
+The detailed specifications for any Jambase rule
+can be found by reading the rule definition itself
+in the Jambase file.
+<P>
+
+<HR>
+<H2>
+Handling Directory Trees
+</H2>
+       The SubDir* rules are used to
+       define source code directory hierarchies.
+       With SubDir and SubInclude, you can use <b>jam</b>
+       to build software from source files and Jamfiles spread
+       across many directories, as is typical for large projects.
+       The SubDir* rules unify an entire
+       source code tree so that <b>jam</b> can read in
+       all the Jamfiles in one pass and 
+       compute dependencies across the entire project.
+<P>
+	To use the SubDir* rules, you must:
+<P>
+<OL>
+       <LI>     Preface the Jamfile in each directory with an invocation 
+       of the SubDir rule.
+<P>
+       <LI>     Place  at  the  root  of the tree a file named Jamrules.  
+	      This file could be empty,  but  in
+              practice  it contains user-provided rules and variable 
+	      definitions that  are  shared  throughout  the
+              tree.   Examples  of  such  definitions are library
+              names,  header  directories,  install  directories,
+              compiler  flags,  etc.  This file is good candidate
+              for automatic customizing with autoconf(GNU).
+<P>
+	<LI> 	Optionally, set an environment variable pointing
+		to the root directory of the srouce tree. The
+		variable's name is left up to you, but in these
+		examples, we use TOP.
+</OL>
+<P>
+<H4>
+   SubDir Rule
+</H4>
+<P>
+       The  SubDir  rule  must  be  invoked before any rules that
+       refer to the contents of the directory - it is best to put
+       it at the top of each Jamfile.  For example:
+<PRE>
+	# Jamfile in $(TOP)/src/util directory.
+
+	SubDir TOP src util ;
+
+	Main myprog : main.c util.c ;                   
+	LinkLibraries myprog : libtree ;     
+	Library libtree : treemake.c treetrav.c ;    
+</PRE>
+       This  compiles  four  files  in  $(TOP)/src/util, archives
+       two of the objects into libtree, and links  the  whole
+       thing into myprog. 
+       Outputs are placed in the $(TOP)/src/util
+       directory. 
+       <P>
+       This doesn't appear to be any different from 
+       the previous example that didn't have a SubDir rule,
+       but two things are happening behind the scenes:
+       <OL>
+       <LI>The SubDir rule causes <b>jam</b> to read
+	   in the $(TOP)/Jamrules file. 
+           (The Jamrules file can alternately be named by  the
+              variable  $(xxxRULES), where xxx is the name of the
+              root variable, e.g., $(TOPRULES)).  
+	      <P>
+	   The Jamrules file can contain variable definitions
+	   and rule definitions specific to your codeline.
+	   It allows you to completely customize your build 
+	   environment without having to rewrite Jambase.
+	   Jamrules is only read
+	   in once, at the first SubDir invocation.
+	   <P>
+	<LI>
+	   The SubDir rule initializes a set of variables
+	   that are used by Main and other rules to 
+	   uniquely identify the source files in this
+	   directory and assign locations to the targets
+	   built from files in this directory.
+	   <P>
+	   When you have set a root variable, e.g., $(TOP),
+	   SubDir constructs path names rooted with $(TOP),
+	   e.g., $(TOP)/src/util.
+	   Otherwise, SubDir constructs relative pathnames
+	   to the root directory, computed from the number
+	   of arguments to the first SubDir rule, e.g.,
+	   ../../src/util. In either case, the SubDir
+	   rule constructs the path names that locate source
+	   files.
+	   You'll see how this is useful later.
+	<P>
+       </UL>
+
+<P>
+       The SubDir rule takes  as  its  first  argument  the  root
+       variable's  name  and  takes  as  subsequent arguments the
+       directory names leading from the root to the directory  of
+       the  current Jamfile.  Note that the name of the subdirectory 
+       is given as individual  elements:   the  SubDir  rule
+       does not use system-specific directory name syntax.
+<P>
+<P>
+<H4>
+   SubInclude Rule
+</H4>
+	The SubInclude rule is used in a Jamfile to cause another
+	Jamfile to be read in.
+       Its arguments are in  the  same  format  as
+       SubDir's.
+<P>
+       The  recommended  practice is only to include one level of
+       subdirectories at a time, and let the Jamfile in each subdirectory  
+       include  its own subdirectories.  This allows a
+       user to sit in any arbitrary directory of the source  tree
+       and build that subtree.  For example:
+<PRE>
+       # This is $(TOP)/Jamfile, top level Jamfile for mondo project.
+
+       SubInclude TOP src ;
+       SubInclude TOP man ;
+       SubInclude TOP misc ;
+       SubInclude TOP util ;
+</PRE>
+       If  a directory has both subdirectories of its own as well
+       as files that need building,  the  SubIncludes  should  be
+       either before the SubDir rule or be at the end of the Jamfile 
+       - not between the SubDir and other rule  invocations.
+       For example:
+<PRE>
+	# This is $(TOP)/src/Jamfile:
+
+	SubDir TOP src ;
+
+	Main mondo : mondo.c ;
+	LinkLibraries mondo : libmisc libutil ;
+	
+	SubInclude TOP src misc ;
+	SubInclude TOP src util ;
+</PRE>
+<P>
+	(<b>jam</b> processes all the Jamfiles it reads as if
+	it were reading one single, large Jamfile. 
+	Build rules like Main and LinkLibraries rely on the
+	preceding SubDir rule to set up source file and
+	output file locations, and SubIncludes rules read in
+	Jamfiles that contain SubDir rules. So if you put
+	a SubIncludes rule between a SubDir and a Main
+	rule, <b>jam</b> will try to find the source files
+	for the Main rule in the wrong directory.)
+<P>
+<H4>
+   Variables Used to Handle Directory Trees
+</H4>
+       The  following  variables are set by the SubDir rule
+       and used by the Jambase rules that define file targets:
+<P>
+<CENTER>
+<TABLE>
+<TR><TD VALIGN=TOP>
+              SEARCH_SOURCE
+	      <TD><TD>The SubDir targets (e.g., "TOP src util")
+	      are used to construct a pathname (e.g., $(TOP)/src/util),
+	      and that pathname is assigned to $(SEARCH_SOURCE). 
+	      Rules like Main and Library use $(SEARCH_SOURCE)
+	      to set search paths on source files.
+<TR><TD VALIGN=TOP>
+              LOCATE_SOURCE
+	      <TD><TD>Initialized by the SubDir rule to the same
+	      value as $(SEARCH_SOURCE), unless ALL_LOCATE_TARGET
+	      is set.
+	      $(LOCATE_SOURCE) is used by rules that build
+	      generated source files (e.g., Yacc and Lex) to
+	      set location of output files.
+	      Thus the default location of built source files
+	      is the directory of the Jamfile that defines them.
+<TR><TD VALIGN=TOP>
+              LOCATE_TARGET
+	      <TD><TD>Initalized by the SubDir rule to the same
+	      value as $(SEARCH_SOURCE), unless ALL_LOCATE_TARGET
+	      is set.
+	      $(LOCATE_TARGET) is used by rules that build
+	      binary objects (e.g., Main and Library) to
+	      set location of output files.
+	      Thus the default location of built binaray files
+	      is the directory of the Jamfile that defines them.
+<TR><TD VALIGN=TOP>
+              ALL_LOCATE_TARGET
+	      <TD><TD>
+	      If $(ALL_LOCATE_TARGET) is set, LOCATE_SOURCE
+	      and and LOCATE_TARGET are set to  $(ALL_LOCATE_TARGET)
+	      instead of to $(SEARCH_SOURCE). This can be used to
+	      direct built files to be written to a location outside
+	      of the source tree, and enables building from read-only
+	      source trees.
+<TR><TD VALIGN=TOP>
+              SOURCE_GRIST
+	      <TD><TD>The SubDir targets are formed into a string
+	      like "src!util" and that string is assigned to 
+	      SOURCE_GRIST. Rules that define file targets
+	      use $(SOURCE_GRIST) to set the "grist" attribute
+	      on targets. This is used to assure uniqueness 
+	      of target identifiers where filenames themselves
+	      are not unique.
+	      For example, the target identifiers of 
+	      $(TOP)/src/client/main.c and $(TOP)/src/server/main.c
+	      would be &lt;src!client&gt;main.c and &lt;src!server&gt;main.c.
+</TABLE>
+</CENTER>
+<P>
+       The $(LOCATE_TARGET) and  $(SEARCH_SOURCE)  variables are used
+       extensively by rules in Jambase: most rules that  generate
+       targets  (like  Main,  Object,  etc.)  set $(LOCATE) to 
+       $(LOCATE_TARGET) for the targets they generate, and  rules
+       that  use  sources  (most all of them) set $(SEARCH) to be
+       $(SEARCH_SOURCE) for the sources they use.
+<P>
+       $(LOCATE) and $(SEARCH) are better  explained  in  
+       <A HREF="Jam.html">The Jam Executable Program</A>
+       but in brief they tell <B>jam</B> where to create new targets and
+       where to find existing ones, respectively.
+<P>
+       Note that you can reset these variables
+       after SubDir sets them. For example, this Jamfile builds
+       a program called gensrc, then runs it to create a source file
+       called new.c: 
+       <PRE>
+       SubDir TOP src util ;
+       Main gensrc : gensrc.c ;
+       LOCATE_SOURCE = $(NEWSRC) ;
+       GenFile new.c : gensrc ;
+       </PRE>
+       By default, new.c would be written into the
+       $(TOP)/src/util directory, but resetting LOCATE_SOURCE causes
+       it to be written to the $(NEWSRC) directory. ($(NEWSRC) is assumed
+       to have been set elsewhere, e.g., in Jamrules.)
+<P>
+<H4>
+   VMS Notes
+</H4>
+       On VMS, the logical name table is not imported as  is  the
+       environment on UNIX.  To use the SubDir and related rules,
+       you must set the value of the variable that names the root
+       directory.  For example:
+<PRE>
+              TOP = USR_DISK:[JONES.SRC] ;
+
+              SubInclude TOP util ;
+</PRE>
+       The variable must have a value that looks like a directory
+       or device.  If you choose, you can use a  concealed  logical.  
+       For example:
+<PRE>
+              TOP = TOP: ;
+
+              SubInclude TOP util ;
+</PRE>
+       The  :  at  the  end of TOP makes the value of $(TOP) look
+       like a device name, which jam respects as a directory name
+       and  will  use when trying to access files.  TOP must then
+       be defined from DCL:
+<PRE>
+              $ define/job/translation=concealed TOP DK100:[USERS.JONES.SRC.]
+</PRE>
+       Note three things: the concealed  translation  allows  the
+       logical  to  be  used as a device name; the device name in
+       the logical (here DK100) cannot itself be concealed  logical  
+       (VMS  rules, man); and the directory component of the
+       definition must end in a period (more VMS rules).
+<P>
+<H2>
+Building Executables and Libraries
+</H2>
+<P>
+The rules that build executables and libraries are: Main, Library,
+and LinkLibraries.
+<H4>
+   Main Rule
+</H4>
+       The Main rule compiles source files and links the  resulting 
+       objects into an executable.  For example:
+<PRE>
+              Main myprog : main.c util.c ;
+</PRE>
+       This  compiles  main.c  and  util.c  and  links main.o and
+       util.o into myprog. The object files and resulting 
+       executable are named appropriately for the platform.
+<P>
+	Main can also be used to build shared libraries and/or
+	dynamic link libraries, since those are also linked
+	objects. E.g.:
+	<PRE>
+		Main driver$(SUFSHR) : driver.c ;
+	</PRE>
+	Normally, Main uses $(SUFEXE) to determine the suffix on
+	the filename of the built target. To override it,
+	you can supply a suffix explicity.
+	In this case,
+	$(SUFSHR) is assumed to be the OS-specific shared library
+	suffix, defined in Jamrules with something
+	like:
+	<PRE>
+		if $(UNIX)      { SUFSHR = .so ; }
+		else if $(NT)   { SUFSHR = .dll ; }
+	</PRE>
+	<P>
+	Main uses the Objects rule to compile source targets. 
+
+<H4>
+   Library Rule
+</H4>
+       The Library  rule  compiles  source  files,  archives  the
+       resulting  object  files  into a library, and then deletes
+       the object files.  For example:
+<PRE>
+              Library libstring : strcmp.c strcpy.c strlen.c ;
+              Library libtree : treemake.c treetrav.c ;
+</PRE>
+       This compiles five source files,  archives  three  of  the
+       object  files into libstring and the other two into libtree.  
+       Actual library filenames are formed with the $(SUFLIB) suffix.
+       Once the objects are safely in the libraries, the
+       objects are deleted.
+       <P>
+       Library uses the Objects rule to compile source files.
+<P>
+<H4>
+   LinkLibraries Rule
+</H4>
+       To link executables with built libraries, use
+       the LinkLibraries rule.  For example:
+<PRE>
+              Main myprog : main.c util.c ;
+              LinkLibraries myprog : libstring libtree ;
+</PRE>
+       The LinkLibraries rule  does  two  things:  it  makes  the
+       libraries dependencies of the executable, so that they get
+       built first; and it makes the libraries  show  up  on  the
+       command  line  that links the executable.  The ordering of
+       the lines above is not important, because <b>jam</b> builds  targets 
+       in the order that they are needed.
+<P>
+       You  can  put multiple libraries on a single invocation of
+       the LinkLibraries rule, or you can provide them in  multiple  
+       invocations.   In both cases, the libraries appear on
+       the link command line in the  order  in  which  they  were
+       encountered.  You can also provide multiple executables to
+       the LinkLibraries rule, if they need the same libraries,
+       e.g.:
+       <PRE>
+		LinkLibraries prog1 prog2 prog3 : libstring libtree ;
+       </PRE>
+<P>
+<H4>
+   Variables Used in Building Executables and Libraries
+</H4>
+<CENTER>
+<TABLE>
+<TR><TD>
+              AR           
+	      <TD><TD>Archive command, used for Library targets.
+<TR><TD>
+              SUFEXE         
+	      <TD>*<TD>Suffix on filenames of executables referenced
+		by Main and LinkLibraries.
+<TR><TD>
+              LINK           
+	      <TD><TD>Link command, used for Main targets.
+<TR><TD>
+              LINKFLAGS       
+	      <TD><TD>Linker flags.
+<TR><TD>
+              LINKLIBS        
+	      <TD><TD>Link libraries that aren't dependencies. (See note
+		below.)
+<TR><TD>
+              EXEMODE         
+	      <TD>*<TD>File permissions on Main targets.
+<TR><TD>
+              MODE            
+	      <TD><TD>Target-specific file permissions on Main targets
+		(set from $(EXEMODE))
+<TR><TD>
+              RANLIB          
+	      <TD><TD>Name of ranlib program, if any.
+</TABLE>
+</CENTER>
+
+<P>
+	Variables above marked with "*" are used by the Main,
+	Library, and LinkLibraries rules. Their values at the 
+	time the rules are invoked are used to set target-specific
+	variables.
+	<P>
+	All other variables listed above are globally defined,
+	and are used in actions that update Main and Library
+	targets. This means that the global values of those
+	variables are used, uness target-specific values have
+	been set. 
+	(For instance, a target-specific MODE value is set by 
+	the Main rule.)
+	The target-specific values always override
+	global values.
+<P>
+	Note that there are two ways to specify link libraries for
+	executables: 
+	<UL>
+	<LI>Use the LinkLibraries rule 
+	to specify built libraries; i.e., libraries
+	that are built by Library rules. This assures that
+	these libraries are built first, and that Main targets are 
+	rebuilt when the libraries are updated.
+	<P>
+	<LI>Use the LINKLIBS variable to specify external
+	 libraries; e.g., system libraries or third-party libraries.
+	 The LINKLIBS variable must be set to the the actual
+	 link command flag that specifies the libraries.
+	 <P>
+	 </UL>
+	 <P>
+	 For example:
+<PRE>
+	<I>#In Jamrules:</I>
+              if $(UNIX) { X11LINKLIBS = -lXext -lX11 ; }
+              if $(NT)   { X11LINKLIBS = libext.lib libX11.lib ; }
+
+	<I>#In Jamfile:</I>
+              Main xprog : xprog.c ;
+              LINKLIBS on xprog$(SUFEXE) = $(X11LINKLIBS) ;
+              LinkLibraries xprog : libxutil ;
+              Library libxutil : xtop.c xbottom.c xutil.c ;
+</PRE>
+       This  example  uses the Jam syntax "variable on target" to
+       set a target-specific variable.  In this way,  only  xprog
+       will  be linked with this special $(X11LINKLIBS), 
+       even if other executables were going to  be  built
+       by  the  same Jamfile. Note that when you set a variable
+       on a target, you have to specify the target identifer
+       exactly, which in this case is the suffixed filename of
+       the executable.
+       The actual link command line on Unix, for example, would
+       look something like this:
+<PRE>
+              cc -o xprog xprog.o libxutil.a -lXext -lX11
+</PRE>
+<H2>
+Compiling
+</H2>
+       Compiling of source files occurs normally as  a  byproduct
+       of  the Main or Library rules, which call the rules 
+       described here. These rules may also be called explicitly
+       if the Main and Library behavior doesn't satisfy your
+       requirements.
+<P>
+<H4>
+   Objects Rule
+</H4>
+       The Main and Library rules call the Objects rule on source files.
+       Compiled object files built by
+       the Objects rule are a dependency of the <I>obj</i>
+       pseudotarget, so "jam obj" will build object files used in 
+       Main and Library rules.
+       <P>
+       Target identifiers created by the Objects rule have grist
+       set to $(SOURCE_GRIST). So given this Jamfile:
+       <PRE>
+		SubDir TOP src lock ;
+		Main locker : lock.c ;
+       </PRE>
+       the object file created is lock.o (or lock.obj) and
+       its target identifier is &lt;src!lock&gt;lock.o 
+       (or &lt;src!lock&gt;lock.obj).
+
+       <P>
+       You can also call  Objects  directly.  For example:
+<PRE>
+              Objects a.c b.c c.c ;
+</PRE>
+       This compiles a.c into a.o, b.c into b.o, etc. The object
+       file suffix is supplied by the Objects rule.
+<P>
+<H4>
+   Object Rule
+</H4>
+       Objects  gets  its work done by calling the Object rule on
+       each of the source files.
+       You could use the Object rule directly.
+       For example, on Unix, you could use:
+<PRE>
+              Object foo.o : foo.c ;
+</PRE>
+	However, the Object rule does not provide suffixes, and
+	it does not provide the grist needed to construct target
+	identifiers if you are using the SubDir* rules.
+	A portable and robust Jamfile would need to invoke Object thus:
+	<PRE>
+	      Object &lt;src!util&gt;foo$(SUFOBJ) : &lt;src!util&gt;foo.c ;
+	</PRE>
+	which is inelegant and clearly shows why using Objects
+	is better than using Object.
+	<P>
+	If there's any advantage to the Object rule, it's
+       that it doesn't require that the object name bear
+       any relationship to the source.  It is  thus  possible  to
+       compile  the  same file into different objects.  For example:
+
+<PRE>
+              Object a.o : foo.c ;
+              Object b.o : foo.c ;
+              Object c.o : foo.c ;
+</PRE>
+       This compiles foo.c (three times) into a.o, b.o, and  c.o.
+       Later examples show how this is useful.
+<P>
+       The Object rule looks at the suffix of the source file and
+       calls the appropriate rules to do  the  actual  preprocessing
+       (if any) and compiling needed to produce the output object file.
+       The Object rule is
+       capable of the generating of an object file from  any
+       type of source.  For example:
+<PRE>
+              Object grammar$(SUFOBJ) : grammar.y ;
+              Object scanner$(SUFOBJ) : scanner.l ;
+              Object fastf$(SUFOBJ) : fastf.f ;
+              Object util$(SUFOBJ) : util.c ;
+</PRE>
+	An even more elegant way to get the same result is to let the
+	Objects rule call Object:
+	<PRE>
+              Objects grammar.y scanner.l fastf.f util.c ;
+	</PRE>
+	<P>
+       In  addition to calling the compile rules, Object sets up
+       a bunch of variables specific to  the  source  and  target
+       files.  (See Variables Used in Compiling, below.)
+<P>
+<H4>
+   Cc, C++, Yacc, Lex, Fortran, As, etc. Rules
+</H4>
+<P>
+       The Object rule calls compile rules specific to the suffix of
+       the source file.  (You can see which suffixes are supported
+       by looking at the Object rule definition in Jambase.)
+       Because  the  extra  work  done  by  the
+       Object rule, it is not always useful to call the compile
+       rules directly.  But the adventurous  user  might  attempt
+       it.  For example:
+<PRE>
+              Yacc grammar.c : grammar.y ;
+              Lex scan.c : scan.l ;
+              Cc prog.o : prog.c ;
+</PRE>
+       These examples individually run yacc(1), lex(1), and the C
+       compiler on their sources.
+<P>
+<H4>
+   UserObject Rule
+</H4>
+       Any files with suffixes not understood by the Object  rule
+       are passed to the UserObject rule.  The default definition
+       of UserObject simply emits a warning that  the  suffix  is
+       not  understood.   This  Jambase rule definition is intended to be
+       overridden in Jamrules with one that recognizes the project-specific
+       source file suffixes. For  example:
+
+<PRE>
+	#In Jamrules:
+
+              rule UserObject
+              {
+                  switch $(&gt;)
+                  {
+                  case *.rc   : ResourceCompiler $(&lt;) : $(&gt;) ;
+                  case *      : ECHO "unknown suffix on" $(&gt;) ;
+                  }
+              }
+
+              rule ResourceCompiler
+              {
+                  DEPENDS $(&lt;) : $(&gt;) ;
+		  Clean clean : $(<) ;
+              }
+
+              actions ResourceCompiler
+              {
+                  rc /fo $(&lt;) $(RCFLAGS) $(&gt;)
+              }
+
+
+	#In Jamfile:
+
+              Library liblock : lockmgr.c ;
+	      if $(NT) { Library liblock : lock.rc ; }
+</PRE>
+<P>
+	In this example, the UserObject definition in Jamrules
+	allows *.rc files to be handle as regular Main and Library
+	sources. The lock.rc file is compiled into lock.obj
+	by the "rc" command, and lock.obj is archived into a library
+	with other compiled objects.
+<H4>
+   LibraryFromObjects Rule
+</H4>
+       Sometimes the Library rule's straightforward compiling  of
+       source  into  object modules to be archived isn't flexible
+       enough.  The LibraryFromObjects rule  does  the  archiving
+       (and  deleting)  job of the Library rule, but not the compiling.  
+       The user can make use of the  Objects  or  Object
+       rule for that.  For example:
+<PRE>
+              LibraryFromObjects libfoo.a : max.o min.o ;
+              Object max.o : maxmin.c ;
+              Object min.o : maxmin.c ;
+              ObjectCcFlags max.o : -DUSEMAX ;
+              ObjectCcFlags min.o : -DUSEMIN ;
+</PRE>
+       This  Unix-specific example compiles  the  same  source  file into 
+       two different
+       objects, with different compile flags, and archives  them.
+       (The ObjectCcFlags rule is described shortly.)
+       Unfortunately, the portable and robust implementation of the
+       above example is not as pleasant to read:
+       <PRE>
+	      SubDir TOP foo bar ;
+              LibraryFromObjects libfoo$(SUFLIB) : &lt;foo!bar&gt;max$(SUFOBJ) 
+			                           &lt;foo!bar&gt;min$(SUFOBJ) ;
+              Object &lt;foo!bar&gt;min$(SUFOBJ) : &lt;foo!bar&gt;maxmin.c ;
+              Object &lt;foo!bar&gt;max$(SUFOBJ) : &lt;foo!bar&gt;maxmin.c ;
+	      ObjectCcFlags &lt;foo!bar&gt;min$(SUFOBJ) : -DUSEMIN ;
+	      ObjectCcFlags &lt;foo!bar&gt;max$(SUFOBJ) : -DUSEMAX ;
+       </PRE>
+       Note that, among other things, you must supply the library
+       file suffix when using the LibraryFromObjects rule.
+<P>
+<H4>
+   MainFromObjects Rule
+</H4>
+       Similar  to  LibraryFromObjects,  MainFromObjects does the
+       linking part of the Main rule, but not the compiling.
+       MainFromObjects  can be used when  there  are no
+       objects at all,  and  everything  is  to  be  loaded  from
+       libraries.  For example:
+<PRE>
+              MainFromObjects testprog ;
+              LinkLibraries testprog : libprog ;
+              Library libprog : main.c util.c ;
+</PRE>
+       On Unix, say, this generates a link command that looks like:
+<PRE>
+              cc -o testprog libprog.a
+</PRE>
+       Linking  purely  from  libraries is something that doesn't
+       work everywhere: it depends on  the  symbol  "main"  being
+       undefined when the linker encounters the library that contains 
+       the definition of "main".
+<P>
+<H4>
+   Variables Used in Compiling
+</H4>
+       The following variables control the  compiling  of  source
+       files:
+<P>
+<CENTER>
+<TABLE>
+<TR><TD VALIGN=TOP>
+              C++              
+	      <TD><TD>The C++ compiler command
+<TR><TD VALIGN=TOP>
+              CC               
+	      <TD><TD>The C compiler command
+<TR><TD VALIGN=TOP>
+              C++FLAGS       
+	      <BR>
+              CCFLAGS        
+	      <TD VALIGN=TOP><TD VALIGN=TOP>Compile flags, used to
+		 create or update compiled objects
+<TR><TD>
+              SUBDIRC++FLAGS 
+	      <BR>
+              SUBDIRCCFLAGS  
+	      <TD VALIGN=TOP><TD VALIGN=TOP>Additonal compile flags
+		for source files in this directory.
+<TR><TD VALIGN=TOP>
+              OPTIM            
+	      <TD><TD>Compiler optimization flag. The Cc and C++ 
+		actions use this as well as C++FLAGS or CCFLAGS.
+<TR><TD VALIGN=TOP>
+              HDRS           
+	      <TD VALIGN=TOP><TD>Non-standard header directories; i.e.,
+		the directories the compiler will not look in 
+		by default and which therefore must be supplied
+		to the compile command. These directories are
+		also used by <b>jam</b> to scan for include files.
+<TR><TD VALIGN=TOP>
+              STDHDRS        
+	      <TD VALIGN=TOP><TD>Standard header directories, i.e., the
+		directories the compiler searches automatically.
+		These are not passed to the compiler, but they
+		are used by <b>jam</b> to scan for include files.
+<TR><TD>
+              SUBDIRHDRS     
+	      <TD><TD>Additional paths to add to HDRS for source files
+		in this directory.
+<TR><TD>
+              LEX              
+	      <TD><TD>The lex(1) command 
+<TR><TD>
+              YACC             
+	      <TD><TD>The yacc(1) command 
+</TABLE>
+</CENTER>
+<P>
+       The  Cc rule sets a target-specific $(CCFLAGS) to the current 
+       value of $(CCFLAGS) and $(SUBDIRCCFLAGS).   Similarly
+       for  the C++ rule.  The Object rule sets a target-specific
+       $(HDRS) to  the  current  value  of  $(HDRS)  and  $(SUBDDIRHDRS).
+
+<P>
+       $(CC),  $(C++),  $(CCFLAGS),  $(C++FLAGS),  $(OPTIM),  and
+       $(HDRS) all affect the  compiling  of  C  and  C++  files.
+       $(OPTIM)  is  separate  from $(CCFLAGS) and $(C++FLAGS) so
+       they can be set independently.
+<P>
+       $(HDRS) lists the directories to search for header  files,
+       and  it  is used in two ways: first, it is passed to the C
+       compiler (with the flag -I prepended); second, it is  used
+       by  HdrRule  to  locate  the header files whose names were
+       found when scanning source files.   $(STDHDRS)  lists  the
+       header  directories  that  the  C  compiler  already knows
+       about.  It does not need passing to the C compiler, but is
+       used by HdrRule.
+<P>
+       Note that these variables, if set as target-specific variables, 
+       must be set on the target,  not  the  source  file.
+       The target file in this case is the object file to be generated.  
+       For example:
+<PRE>
+              Library libximage : xtiff.c xjpeg.c xgif.c ;
+
+              HDRS on xjpeg$(SUFOBJ) = /usr/local/src/jpeg ;
+              CCFLAGS on xtiff$(SUFOBJ) = -DHAVE_TIFF ;
+</PRE>
+       This can be done more easily with the rules that follow.
+<P>
+<H4>
+   ObjectCcFlags, ObjectC++Flags, ObjectHdrs Rules
+</H4>
+       $(CCFLAGS), $(C++FLAGS) and  $(HDRS)  can  be  set on object file
+       targets
+       directly, but  there are rules that allow these variables
+       to be set by referring to the original source  file  name,
+       rather  than  to  the  derived object file name.  ObjectCcFlags 
+       adds object-specific flags to the $(CCFLAGS)  variable,  
+       ObjectC++Flags  adds  object-specific  flags to the
+       $(C++FLAGS) variable, and ObjectHdrs  add  object-specific
+       directories to the $(HDRS) variable.  For example:
+<PRE>
+	#In Jamrules:
+		if $(NT) { CCFLAGS_X = /DXVERSION ;	
+			   HDRS_X = \\\\SPARKY\\X11\\INCLUDE\\X11 ;
+		         }
+
+	#In Jamfile:
+              Main xviewer : viewer.c ;
+              ObjectCcFlags viewer.c : $(CCFLAGS_X) ;
+              ObjectHdrs viewer.c : $(HDRS_X) ;
+</PRE>
+	The ObjectCcFlags and ObjectHdrs rules take .c files
+	as targets, but actually set $(CCFLAGS) and $(HDRS) values
+	on the .obj (or .o) files. As a result, the action
+	that updates the target .obj file uses the target-specific
+	values of $(CCFLAGS) and $(HDRS).
+<P>
+<H4>
+   SubDirCcFlags, SubDirC++Flags, SubDirHdrs Rules
+</H4>
+       These rules set the  values  of  $(SUBDIRCCFLAGS),  $(SUBDIRC++FLAGS)  
+       and $(SUBDIRHDRS), which are used by the Cc,
+       C++, and Object rules  when  setting  the  target-specific
+       values  for $(CCFLAGS), $(C++FLAGS) and $(HDRS).  The SubDir 
+       rule clears these variables out, and thus they provide
+       directory-specific  values of $(CCFLAGS), $(C++FLAGS)  and
+       $(HDRS).  For example:
+<PRE>
+	#In Jamrules:
+              GZHDRS = $(TOP)/src/gz/include ;
+	      GZFLAG = -DGZ ;
+		
+	#In Jamfile:
+              SubDir TOP src gz utils ;
+
+              SubDirHdrs $(GZHDRS) ;
+              SubDirCcFlags $(GZFLAG) ;
+
+	      Library libgz : gizmo.c ;
+	      Main gizmo : main.c ;
+	      LinkLibraries gizmo : libgz ;
+</PRE>
+	All .c files in this directory files will be compiled with
+	$(GZFLAG) as well as the default $(CCFLAG), and the include
+	paths used on the compile command will be $(GZHDRS) as well
+	as the default $(HDRS).
+<H2>
+Header File Processing
+</H2>
+       One of the functions of the Object rule is set up 
+       scanning of source
+       files  for (C style) header file inclusions.  To do so, it
+       sets the special variables $(HDRSCAN)  and  $(HDRRULE)
+       as  target-specific  variables  on  the source file.  The
+       presence of these variables triggers a  special  mechanism
+       in  <B>jam</B> for scanning a file for header file inclusions and
+       invoking a  rule  with  the  results  of  the  scan.   The
+       $(HDRSCAN)  variable  is  set  to an egrep(1) pattern that
+       matches "#include" statements in C source files,  and  the
+       $(HDRRULE)  variable  is  set to the name of the rule that
+       gets invoked as such:
+<PRE>
+              $(HDRRULE) source-file : included-files ;
+</PRE>
+       This rule is supposed to set up the  dependencies  between
+       the  source  file and the included files.  The Object rule
+       uses HdrRule  to  do  the  job.   HdrRule  itself  expects
+       another  variable,  $(HDRSEARCH), to be set to the list of
+       directories where the included files can be found.  Object
+       does  this  as  well,  setting $(HDRSEARCH) to $(HDRS) and
+       $(STDHDRS).
+<P>
+       The header file scanning occurs during the "file  binding"
+       phase   of  <b>jam</b>,  which  means  that  the  target-specific
+       variables (for the source file) are in effect.  To accomodate 
+       nested includes, one of the HdrRule's jobs is to pass
+       the target-specific values of $(HDRRULE), $(HDRSCAN),  and
+       $(HDRSEARCH) onto the included files, so that they will be
+       scanned as well.
+<P>
+<H4>
+   HdrRule Rule
+</H4>
+	Normally, HdrRule is not invoked directly; the Object rule
+	(called by Main and Library) invokes it.
+	<P>
+	If there are special dependencies that need to be set,
+	and which are not set by HdrRule itself, you can define
+	another rule and let it invoke HdrRule.  For example:
+
+<PRE>
+	#In Jamrules:
+              rule BuiltHeaders
+              {
+                      DEPENDS $(&gt;) : mkhdr$(SUFEXE) ;
+                      HdrRule $(&lt;) : $(&gt;) ;
+              }
+
+	#In Jamfile:
+              Main mkhdr : mkhdr.c ;
+              Main ugly : ugly.c ;
+
+              HDRRULE on ugly.c = BuiltHeaders ;
+
+</PRE>
+       This example just says that the files included by "ugly.c"
+       are  generated  by the program "mkhdr", which can be built
+       from "mkhdr.c".  During the binding phase, <b>jam</b> will
+       scan ugly.c, and if it finds an include file, ughdr.h,
+       for example, it will automatically invoke the rule:
+       <PRE>
+              BuiltHeaders ugly.c : ughdr.h ;
+       </PRE>
+       By calling HdrRule at the end  of  BuiltHeaders,  
+       all  the gadgetry of HdrRule takes effect and it
+       doesn't need to be duplicated.
+<P>
+<H4>
+   Variables Used for Header Scanning
+</H4>
+<CENTER>
+<TABLE>
+<TR><TD VALIGN=TOP>
+              HDRPATTERN    
+	      <TD><TD>Default scan pattern for "include" lines.
+<TR><TD VALIGN=TOP>
+              HDRSCAN         
+	      <TD><TD>Scan pattern to use. 
+		This is a special variable: during binding, if
+		both HDRSCAN and HDRRULE are set, scanning is activated
+		on the target being bound.
+		The HdrRule and Object rules sets this
+		to $(HDRPATTERN) on their source targets.
+<TR><TD VALIGN=TOP>
+              HDRRULE         
+	      <TD><TD>Name of rule to invoked on files found in header
+		scan. The HdrRule and Object rules set this to "HdrRule"
+		on their source targets. This is also a special variable;
+		it's the only <b>jam</b> variable that can hold the
+		name of a rule to be invoked.
+<TR><TD VALIGN=TOP>
+              HDRSEARCH       
+	      <TD><TD>Search paths for files found during header scanning.
+		This is set from $(HDRS) and $(STDHDRS), which are 
+		described in the Compiling section.
+		<b>jam</b> will search $(HDRSEARCH) directories for
+		the files found by header scans. 
+</TABLE>
+</CENTER>
+<P>
+       The  Object rule sets HDRRULE and HDRSCAN specifically for
+       the source files to be scanned, rather than globally.   If
+       they  were  set  globally,  jam  would attempt to scan all
+       files, even library archives and executables,  for  header
+       file  inclusions.   That  would  be  slow and probably not
+       yield desirable results.
+<P>
+<H2>
+Copying Files
+</H2>
+<H4>
+   File Rule
+</H4>
+       The File rule copies one file to another.  The target name
+       needn't  be the same as the source name.  For
+       example:
+<PRE>
+	switch $(OS)
+	{
+           case NT*  : File config.h : confignt.h ;
+	   case *    : File config.h : configunix.h ;
+	}
+	LOCATE on config.h = $(LOCATE_SOURCE) ;
+</PRE>
+	This creates a config.h file from either confignt.h or
+	configunix.h, depending on the current build platform.
+<P>
+	The File rule does not
+	use the LOCATE_SOURCE variable set by the
+	SubDir rule (although it does use SEARCH_SOURCE), which
+	means you have to set the copied file's output directory
+	yourself. That's done by setting the special
+	LOCATE variable on the target, as shown above,
+	or with the MakeLocate rule described below.
+<H4>
+   Bulk Rule
+</H4>
+       The Bulk rule is a shorthand for many invocations  of  the
+       File  rule when all files are going to the same directory.
+       For example:
+<PRE>
+	#In Jamrules:
+              DISTRIB_GROB = d:\\distrib\\grob ;
+
+	#In Jamfile:
+              Bulk $(DISTRIB_GROB) : grobvals.txt grobvars.txt ;
+</PRE>
+	This causes gobvals.txt and grobvars.txt to be copied
+	into the $(DISTRIB_GROB) directory.
+<H4>
+   HardLink Rule
+</H4>
+       The Unix-only HardLink rule makes a hard link (using ln(1)) from the
+       source  to  the  target,  if there isn't one already.  For
+       example:
+<PRE>
+              HardLink config.h : configunix.h ;
+</PRE>
+<H4>
+   Shell Rule
+</H4>
+       The Shell rule is like the File rule, except that on Unix it makes
+       sure  the first line of the target is "#!/bin/sh" and sets
+       the permission to make the file executable.  For example:
+<PRE>
+              Shell /usr/local/bin/add : add.sh ;
+</PRE>
+<P>
+	You can also use $(SHELLHEADER) to dictate
+	what the first line of the copied file will be.
+       For
+       example:
+<PRE>
+              Shell /usr/local/bin/add : add.awk ;
+              SHELLHEADER on /usr/local/bin/add = "#!/bin/awk -f" ;
+</PRE>
+       This installs an awk(1) script.
+<P>
+<H4>
+   Variables Used When Copying Files
+</H4>
+<CENTER>
+<TABLE>
+<TR><TD VALIGN=TOP>
+              FILEMODE      
+	      <TD><TD>Default file permissions for copied files
+<TR><TD VALIGN=TOP>
+              SHELLMODE     
+	      <TD><TD>Default file permissions for Shell rule targets
+<TR><TD VALIGN=TOP>
+              MODE            
+	      <TD><TD>File permissions set on files copied by
+		File, Bulk, and Shell rules. 
+       		File and Shell sets a target-specific MODE to the  current
+       		value  of  $(FILEMODE) or $(SHELLMODE), respectively.  
+<TR><TD VALIGN=TOP>
+              SHELLHEADER     
+	      <TD><TD>String to write in first line of Shell targets 
+	      (default is #!/bin/sh).
+
+</TABLE>
+</CENTER>
+<P>
+
+<H2>
+Installing Files
+</H2>
+Jambase provides a set of Install* rules to copy files
+into an destination directory and set permissions on them.
+On Unix, the install(1) program is used.
+If the destination directory does not exist, <b>jam</b>
+creates it first.
+<P>
+All files copied with the Install* rules are dependencies
+of the <i>install</i> pseudotarget, which means that the
+command "jam install" will cause the installed copies to
+be updated. Also, "jam uninstall" will cause the installed
+copies to be removed.
+<P>
+The Install* rules are:
+<CENTER>
+<TABLE>
+<TR><TD VALIGN=TOP><B>InstallBin</B>
+    <TD VALIGN=TOP>Copies file and sets its permission to $(EXEMODE).
+		   You must specify the suffixed executable name. E.g.:
+    <PRE>InstallBin $(BINDIR) : thing$(SUFEXE) ;
+		   </PRE>
+
+<TR><TD VALIGN=TOP><B>InstallFile</B>
+    <TD VALIGN=TOP>Copies file and sets its permission to $(FILEMODE). E.g.:
+    <PRE>InstallFile $(DESTDIR) : readme.txt ;
+		   </PRE>
+
+<TR><TD VALIGN=TOP><B>InstallLib</B>
+    <TD VALIGN=TOP>Copies file and sets its permission to $(FILEMODE).
+		   You must specify the suffixed library name. E.g.:
+    <PRE>InstallLib $(LIBDIR) : libzoo$(SUFLIB) ;
+		   </PRE>
+
+<TR><TD VALIGN=TOP><B>InstallMan</B>
+    <TD VALIGN=TOP>Copies file into the man<i>n</i>
+		   subdirectory of the target directory
+		   and sets its permission to $(FILEMODE). E.g.,
+		   this copies foo.5 into the $(DESTDIR)/man5 directory:
+    <PRE>InstallMan $(DESTDIR) : foo.5 ;
+		   </PRE>
+
+<TR><TD VALIGN=TOP><B>InstallShell</B>
+    <TD VALIGN=TOP>Copies file and sets its permission to $(SHELLMODE). E.g.:
+    <PRE>InstallShell $(DESTDIR) : startup ;
+		   </PRE>
+
+</TABLE>
+</CENTER>
+<P>
+<P>
+<H4>
+   Variables
+</H4>
+       The following variables control the installation rules:
+<P>
+<CENTER>
+<TABLE>
+<TR><TD>
+              INSTALL        
+	      <TD><TD>The install program (Unix only)
+<TR><TD>
+              FILEMODE     
+	      <TD><TD>Default file permissions on readable files. 
+<TR><TD>
+              EXEMODE      
+	      <TD><TD>Default file permission executable files.
+<TR><TD>
+              SHELLMODE    
+	      <TD><TD>Default file permission on shell script files.
+<TR><TD>
+              MODE           
+	      <TD><TD>Target-specific file permissions
+</TABLE>
+</CENTER>
+<P>
+<P>
+       The  Install  rules set a target-specific MODE to the current 
+       value of $(FILEMODE),  $(EXEMODE),  or  $(SHELLMODE),
+       depending on which Install rule was invoked.
+<P>
+       The  directory variables are just defined for convenience:
+       they must be passed  as  the  target  to  the  appropriate
+       Install  rule.   The $(INSTALL) and mode variables must be
+       set (globally) before calling the Install rules  in  order
+       to take effect.
+<P>
+<H2>
+Miscellaneous Rules
+</H2>
+<H4>
+Clean Rule
+</H4>
+<P>
+The Clean rule defines files to be removed when you run "jam clean".
+Any site-specific build rules defined in your Jamrules should invoke
+Clean so that outputs can be removed. E.g.,
+<PRE>
+	rule ResourceCompiler
+	{
+	   DEPENDS $(<) : $(>) ;
+	   Clean clean : $(<) ;
+	}
+</PRE>
+<P>
+<P>
+Most Jambase rules invoke the Clean rule on their built targets,
+so "jam clean" will remove all compiled objects, libraries,
+executables, etc.
+<P>
+<H4>
+MakeLocate Rule
+</H4>
+      MakeLocate is a single convenient rule that creates a directory,
+      sets LOCATE on a target to that directory, and makes the directory
+      a dependency of the target. It is used by many Jambase rules,
+      and can be invoked directly, e.g.:
+      <PRE>
+		GenFile data.tbl : hxtract data.h ;
+		MakeLocate data.tbl : $(TABLEDIR) ;
+      </PRE>
+      In this example, the File rule creates data.tbl from data.h.
+      The MakeLocate causes data.tbl to be written into the $(TABLEDIR)
+      directory; and if the directory doesn't exist, it is created first.
+      <P>
+      The MakeLocate rule invokes another Jambase rule, MkDir,
+      to (recursively) create
+      directories. MkDir uses the $(MKDIR) variable to determine the
+      platform-specific command that creates directories.
+<P>
+<H4>
+RmTemps Rule
+</H4>
+	Some intermediate files are meant to be temporary. 
+	The RmTemps rule can be used to cause 
+	<b>jam</b> to delete them after they are used. 
+	<P>
+	RmTemps must be:
+	<UL>
+	<LI>
+	the last rule 
+	invoked on the permanent file that uses
+	the temporary file(s) 
+	<LI>
+	invoked with the permanent file as the output
+	target and the temporary file(s) as the input target
+	<LI>
+	invoked with the exact target identifiers of
+	the permanent file and the temporary file(s)
+	</UL>
+	For
+	example: 
+	<PRE>
+		SubDir TOP src big ;
+		GenFile big.y : joinfiles part1.y part2.y part3.y ;
+		Main bigworld : main.c big.y ;
+		RmTemps bigworld$(SUFEXE) : &lt;src!big&gt;big.y ;
+	</PRE>
+	This causes big.y to be deleted after it has been used to create
+	the bigworld executable. 
+	The exact target identifier of big.y is  &lt;src!big&gt;big.y
+	(the GenFile and Main rules tack on the grist automatically);
+	the exact target identifier of the bigworld executable
+	is bigworld$(SUFEXE).
+<P>
+<HR>   
+<A HREF="#TOP">Back to top.</A>
+<P>
+        Copyright 1997, 2000 Perforce Software, Inc.
+        <BR>
+        Comments to <A HREF="mailto:info at perforce.com">info at perforce.com</A>
+        <BR>
+        Last updated: Dec 31, 2000
+	<BR>
+	$Id: Jamfile.html,v 1.4 2002/04/07 00:22:45 david_abrahams Exp $
+</BODY> 
+</HTML>

Added: boost-jam/boost-build/branches/upstream/current/jam_src/Porting
===================================================================
--- boost-jam/boost-build/branches/upstream/current/jam_src/Porting	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/jam_src/Porting	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,68 @@
+Notes on porting Jam - revised 12/31/2000
+
+1) Working out system dependencies in the Jam code.
+
+    Jam's OS footprint is fairly small.  For OS independent work Jam
+    liberally uses standard libc functions like stdio, malloc, and
+    string.  The OS dependent interfaces are:
+
+	From filesys.h:
+
+	    file_parse() - split a file name into dir/base/suffix/member
+	    file_build() - build a filename given dir/base/suffix/member
+	    file_dirscan() - scan a directory for files
+	    file_archscan() - scan an archive for files
+	    file_time() - get the timestamp of a file, if not already 
+			  done by file_dirscan().
+
+	From execcmd.h:
+
+	    execcmd() - execute a shell script
+	    execwait() - wait for any outstanding execcmd()'s.
+
+    The current implementations are:
+
+	    filemac.c - mac MPW 
+	    filent.c - NT 
+	    fileos2.c - OS/2 
+	    fileunix.c - all UNIX
+	    filevms.c - VMS
+
+	    execmac.c - mac MPW
+	    execunix.c - UNIX, OS/2, NT
+	    execvms.c - VMS
+
+2) Defining OSMAJOR, OSMINOR in jam.h
+
+    So that the Jambase and Jamfile know their host, Jam defines $(OS)
+    to be something useful for each platform.  Make sure that there is
+    code in jam.h to generate a useful value for $(OS), and key it off 
+    the platform specific C-preprocessor symbol.   If the C-preprocessor 
+    doesn't itself defines such a symbol, add a define to the Makefile.
+
+    In addition to $(OS), you can also set $(OSPLAT) if the OS runs on
+    multiple platforms (like Linux or NT).
+
+3) Working out system dependencies in the Jambase
+
+    With the value of $(OS) available, the Jambase can be extended to
+    support special variables or rules for new platforms.   See the
+    current support for VMS, NT, and Mac.
+
+4) Yacc troubles
+
+    The generated files jamgram.h and jamgram.c are distributed for the 
+    poor souls without yacc.
+
+5) Known problematic systems:
+
+    - Pyramid has no malloc.h, memory.h
+
+    - Encore has no stdlib.h
+
+    - Bull DPX has sys/file.h problems
+
+6) Send the results back.
+
+    If you do porting work, the result can be integrated into future
+    releases if you send it back to the author's address in the README.

Added: boost-jam/boost-build/branches/upstream/current/jam_src/README
===================================================================
--- boost-jam/boost-build/branches/upstream/current/jam_src/README	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/jam_src/README	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,149 @@
+Jam/MR (aka "jam - make(1) redux") 
+
+    /+\
+    +\	Copyright 1993-2002 Christopher Seiwald and Perforce Software, Inc.
+    \+/
+
+    This is Release 2.4 of Jam/MR, a make-like program.
+
+    License is hereby granted to use this software and distribute it
+    freely, as long as this copyright notice is retained and modifications 
+    are clearly marked.
+
+    ALL WARRANTIES ARE HEREBY DISCLAIMED.
+
+FEATURES
+
+   ->	Jam is a make(1) replacement that makes building simple things
+	simple and building complicated things manageable.
+
+   ->	Jam's language is expressive, making Jamfiles (c.f. Makefiles) 
+	compact.  Here's a sample:
+
+	    Main smail : main.c map.c resolve.c deliver.c
+			 misc.c parser.y alias.c pw.c headers.c
+			 scanner.l getpath.c str.c ;
+
+	This builds "smail" from a dozen source files.  Jam handles 
+	header file dependencies automatically and on-the-fly.
+
+   ->	Jam is very portable: it runs on UNIX, VMS, Mac, and NT.  
+	Most Jamfiles themselves are portable, like the sample above.
+
+   ->   Jam is unintrusive: it is small, it has negligible CPU 
+	overhead, and it doesn't create any of its own funny files
+	(c.f. Odin, nmake, SunOS make).
+
+   ->	Jam can build large projects spread across many directories
+	in one pass, without recursing, tracking the relationships
+	among all files. Jam can do this with multiple, concurrent 
+	processes.
+
+   ->   Jam isn't under the blinkin GNU copyright, so you can 
+	incorporate it into commercial products.
+
+
+INFORMATION GUIDE
+
+    Jam.html		jam and language reference.
+
+    Jambase.html	Reference for the Jambase boilerplate file.
+
+    Jamfile.html	Easy reading on creating a Jamfile and using jam.
+
+    RELNOTES		Release 2.3 release notes.
+
+    Porting		Notes on porting jam to wildcat platforms.
+
+    README		This file.  Includes installation instructions.
+
+    jam.c		Contains the jam command's main() as well as an 
+			introduction to the code, for serious hackers.
+
+
+INSTALLING
+
+    The Makefile (UNIX, NT), build.com (VMS), Build.mpw (Mac MPW) are 
+    for bootstrapping.  Once jam is built, it can rebuild itself.
+
+    UNIX
+
+	Build jam with make(1) on:
+
+	    Platform		$(OS) 
+	    -------------------------
+	    AIX			AIX		*	
+	    BSD/386 1.0		BSDI
+	    COHERENT/386	COHERENT
+	    DGUX 5.4		DGUX
+	    FreeBSD		FREEBSD
+	    HPUX 9.0		HPUX
+	    IRIX 5.0		IRIX
+	    Linux		LINUX
+	    NEXTSTEP 3.2	NEXT
+	    OSF/1		OSF
+	    PTX V2.1.0		PTX
+	    Solaris 2		SOLARIS		*
+	    SunOS4.1		SUNOS
+	    Ultrix 4.2		ULTRIX
+	    BeOS		BEOS		*
+
+	    * requires editing Makefile
+
+    Windows
+
+	Build jam with nmake on:
+
+	    Platform		$(OS)
+	    -------------------------
+	    NT			NT		*
+	    OS/2		OS2		*
+
+	The NT MAXLINE (command line length) is still set in jam.h to
+	996, which was apparently the NT 3.5 limit. On 4.0, the limit 
+	is somewhere around 10K. For now, you can increase MAXLINE in 
+	jam.h so that a jam running on 4.0 will use the full command
+	line length, but that jam.exe will fail miserably on the older OS.
+
+	On NT, a variable must be set before invoking jam to tell
+	it where the C compiler lives.  The name of this variable
+	depends on which compiler you are using:
+
+	    BCCROOT:	The Borland C compiler
+	    MSVCNT:	The Microsoft Compiler 5.0 (for NT)
+	    MSVC:	The Microsoft Compiler 1.5 (for Windows)
+
+	Only MSVCNT has really been tested and is known to work.
+
+    Macintosh
+
+	Build jam with Build.mpw on:
+
+	    Platform		$(OS)
+	    -------------------------
+	    Macintosh		MAC		
+
+	You'll need to edit Build.mpw to set CW.  
+
+    VMS
+
+    	Build jam with @build.com on:
+
+	    Platform		$(OS)
+	    -------------------------
+	    VMS 5.4		VMS
+	    OPENVMS		OPENVMS
+
+Comments to the author!
+
+November, 1993 - release 1.0
+March, 1995 - release 2.0 
+February, 1996 - release 2.1
+November, 1997 - release 2.2
+December, 2000 - release 2.3
+March, 2002 - release 2.4
+
+
+Christopher Seiwald
+
+seiwald at perforce.com

Added: boost-jam/boost-build/branches/upstream/current/jam_src/RELNOTES
===================================================================
--- boost-jam/boost-build/branches/upstream/current/jam_src/RELNOTES	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/jam_src/RELNOTES	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,941 @@
+Release notes for Jam/MR 2.4
+(aka Jam - make(1) redux)
+
+0.  Changes between 2.4rc1 and 2.4rc2:
+
+    THESE NOTES WILL BE REMOVED WITH THE FINAL 2.4 RELEASE, SINCE THEY
+    REFER EXCLUSIVELY TO ADJUSTMENTS IN BEHAVIORS NEW BETWEEN 2.3 and
+    2.4:
+
+	Make MATCH generate empty strings for () subexpressions that
+	match nothing, rather than generating nothing at all.
+	Thanks to David Abrahams.
+
+	GLOB now applies the pattern to the directory-less filename,
+	rather than the whole path. Thanks to Niklaus Giger.
+
+	Make Match rule do productized results, rather than
+	using just $(1[1]) as pattern and $(2[1]) as the string.
+
+1.  Release info:
+
+	Jam/MR 2.4
+	March, 21, 2002
+	VERSION 2.4
+
+2.  Compatibility
+
+	Jam 2.4 is upward compatible with Jam 2.3
+
+	The Jam 2.4 language is a superset of the 2.3 language;
+	Jamfiles, Jambase, and other rulesets used in 2.3 can be used
+	with the 2.4 language support.
+
+3.  Changes since 2.3.
+
+3.1.  Changes to Jam Language
+
+	The mechanism for calling rules that return values - "[ rule
+	args ...]", (and 'return' in the rule body), is now a
+	documented part of the language.
+
+	Add "on <target> <rulename> <field1> ..." syntax, to invoke a
+	rule under the influence of a target's specific variables.
+
+        Add "[ on targ rule ... ]" to call a rule returning a value,
+        under the influence of a target's specific variables.
+
+	New 'Glob' builtin that returns a list of files in a list of
+	directories, given a list of patterns.
+
+	New 'while expr { block }' construct.
+
+	New :E=value modifier provides default value if variable unset.
+
+	New :J=joinval modifier concatenates list elements into single
+		element, separated by joinval.
+
+	\ can now be used to escape a space (or any single whitespace
+	character), so that you don't have to resort to quotes. 
+
+	New 'Match regexp : string' rule matches regexp against string
+	and returns list of results.
+
+	Rules can now be invoked indirectly, through variable names.
+	If the variable expands to an empty list, no rule is run.
+	If the variable expands to multiple entries, each rule is
+	run with the same arguments.  The result of the rule invocation
+	is the concatenation of the results of the rules invoked.
+
+	'Echo' and 'Exit' now have aliases 'echo' and 'exit', since it
+	is really hard to tell that these are built-in rules and not
+	part of the language, like 'include'.  Real rules continue to
+	start with a capital.
+
+3.2.  Jambase Changes
+
+	Support for YACCGEN, the suffix used on generated yacc output.
+
+        Fix ups to have jam and p4 build with borland C 5.5,
+        and minor win98 jam support for jam clean
+
+	SubDirHdrs now takes directory names in the same format as
+	SubInclude : one directory element per word.
+
+	More portable support for specifying includes and #defines:
+	New ASHDRS, CCHDRS, CCDEFS, DEFINES, ObjectDefines, FQuote,
+	FIncludes, FDefines.  Ordering of cc and c++ flags grossly
+	rearranged.
+
+	Jambase has been compacted by applying the new E: and J:
+	expansion modifiers.
+
+	New SoftLink rule, courtesy of David Lindes.  It currently
+	assumes you can pass a -s flag to $(LN).
+
+3.3   'jam' Changes (See Jam.html)
+
+	Added '-q' (quit quick) option; jam will exit promptly (as if it
+	received an interrupt), as soon as any target fails.
+
+	Added experimental '-g' (build newest sources first) option:
+	all things being equal, normally targets are simply built in
+	the order they appear in the Jamfiles.  With this flag, targets
+	with the newest sources are built first.   From an idea by Arnt
+	Gulbrandsen.  Undocumented (outside this note).
+
+3.4.  Jam internal code changes
+
+	jamgram.yy now defines YYMAXDEPTH to 10000, what it is on 
+	FreeBSD, for older yaccs that left it at 150 or so.  This is
+	needed for the right-recursion now used in the grammar.
+
+	Optimize rule compilation, with right-recursion instead of left.
+
+        Split jam's built-in rules out to builtins.c from compile.c,
+        so that compile.c only deals with the language.
+
+        Split jam's pathsys.h from filesys.h, since they are really
+        two different pieces.
+
+	evaluate_if(), which evaluated the condition tree for 'if' and
+	returned an int, has been replaced with compile_eval(), which does
+	essentially the same but returns a LIST.
+
+4.  Fixed bugs
+
+	Missing TEMPORARY targets with multiple parents no longer spoil one
+	parent's time with another.  The parents' time is used for comparison
+	with dependents, but no longer taken on as the target's own time.
+
+	'actions updated', not 'actions together', now protects targets
+	from being deleted on failed/interrupted updates.
+
+	Fixed broken $(v[1-]), which always returned an empty expansion.
+	Thanks to Ian Godin <ian at sgrail.com>.
+
+	Defining a rule within another rule, and invoking the enclosing
+	rule more than once, would result in giving the first rule a
+	null definition.  Fixed.
+
+	$(d:P) now works properly on the mac, climbing up directories.
+	Thanks to Miklos Fazekas <boga at mac.com>.
+
+        No longer (sometimes) treat \ as a directory separator on
+        UNIX.  It isn't supposed to be, but was due to bungled ifdefs.
+        
+        Applying just :U or :D (or :E, :J) mods no longer causes the
+        variable value to be treated as a filename (parsed and rebuilt
+        using the OS specific pathsys routines). Previously, if _any_
+        mods were present then the value was parsed and rebuilt as if
+        a filename, and that could in certain cases munge the value.
+        Only the file modifiers (:GDBSM) treat the value as a
+        filename.
+
+	Four rules makeCommon, makeGrist, makeString, makeSubDir from
+	jam 2.2 missing in 2.3 have been re-added, with apologies to
+	dtb at cisco.com.
+
+	Return status more likely to be correct when using -d0, now that 
+	targets are could as being built even with no debugging output.
+	Thanks to Miklos Fazekas <boga at mac.com>.
+
+	yyacc now suffixes all terminals it defines with _t, so that they
+	don't conflict with other symbols (like RULE with the typedef
+	in rules.h).  Thanks to Michael Allard.
+
+	InstallInto now handles multiple sources properly, rather than
+	acting as if each installed target depended on all sources to
+	be installed.  $(INSTALLGRIST) is now the default grist for
+	installed targets, rather than the hardcoded 'installed'.  Thanks
+	to Stephen Goodson.
+
+5.  Porting
+
+	[MACINTOSH] Paths are now downshifted (internally) so as to
+	handle its case insensitivity.  Thanks to Miklos Fazekas
+	<boga at mac.com>.
+
+        [NT] MS changed the macro for the IA64 Windows NT 64bit
+        compiler.
+
+	[CYGWIN] Cygwin jam porting: dance around bison and yyacc.
+	Use bison's -y flag to use yacc's output file naming
+	conventions, and don't use yyacc on systems whose SUFEXE is
+	set.
+
+	[VMS] The Jambase itself was not formatting the CCHDRS and
+        CCDEFS properly: on VMS they can't be appended to, because
+        multiple /define or /include directives don't work.  Instead
+        now CCHDRS and CCDEFS is reformatted from HDRS and DEFINES
+        anytime those latter two change.  This requires the recent
+        change to jam to allow access to target-specific variables
+        when setting other variables.
+
+        [VMS] Remove exception call when file_dirscan() can't, for
+        some reason, scan a directory.  Use a better set of #ifdefs to
+        determine if we're on a vax, rather than relying on the C
+        compiler being a specific version: we're able to build with
+        the C++ compiler now.
+
+	[VMS] Port new jam to run with just cxx compiler.
+        (The C compiler being a extra-cost item).
+
+        [NT] Add entry for DevStudio when the settings are already in the
+        system environment.
+
+        [NT] default $(MV) to "move /y" in Jambase.
+
+	[MINGW] Mingw port by Max Blagai.
+
+===============================================================================
+===============================================================================
+
+
+======= end
+Release notes for Jam/MR 2.3
+(aka Jam - make(1) redux)
+
+0.  Bugs fixed since 2.3.1
+
+	PATCHLEVEL 2 - 3/12/2001
+
+	NOCARE changed back: it once again does not applies to targets
+	with sources and/or actions.  In 2.3 it was changed to apply to
+	such targets, but that broke header file builds: files that are
+	#included get marked with NOCARE, but if they have source or
+	actions, they still should get built.
+
+1.  Release info:
+
+	Jam/MR 2.3
+	November 16, 2000
+	VERSION 2.3
+	PATCHLEVEL 1
+
+2.  Compatibility
+
+	Jam 2.3 is upward compatible with Jam 2.2.
+
+	The Jam 2.3 language is a superset of the 2.2 language;
+	Jamfiles, Jambase, and other rulesets used in 2.2 can be used
+	with the 2.3 language support.
+
+3.  Changes since 2.2
+
+3.1.  Changes to Jam Language
+
+	Rules now can have values, which can expanded into a list with
+	the new "[ rule args ... ]" syntax.  A rule's value is the value
+	of its last statement, though only the following statements have
+	values: if (value of the leg chosen), switch (ditto), set (value
+	of the resulting variable), return (its arguments).  Note that
+	'return' doesn't actually return.  This support is EXPERIEMENTAL
+	and otherwise undocumented.  (2.3.1)
+
+	Because of the new way lists are processed, if a rule has no
+	targets a warning message is no longer issued.
+
+	NOCARE now applies to targets with sources and/or actions,
+	rather than just those without.
+
+3.2.  Jambase Changes
+
+	The HDRPATTERN variable now allows for leading blanks before
+	the #include, to keep up with ANSI.  By john at nanaon-sha.co.jp
+	(John Belmonte) (2.2.3).
+
+	HDRPATTERN has been adjusted to avoid mistaking cases like:
+
+		# include <time.h> /* could be <sys/time.h> */
+
+	MkDir now NOUPDATE's $(DOT), so that there are no dependencies
+	on the current directory's timestamp.  By john at nanaon-sha.co.jp
+	(John Belmonte).
+
+	The old mock functions like makeDirName, which assigned their
+	results to the variable named as their first argument, have
+	been replaced with real functions using the new [] synxtax.
+	E.g. "makeDirName foo : bar ola" is now "foo = [ fDirName bar ]"
+
+	Install now always does a cp/chmod/etc, rather than using
+	the system's install(1), which invariably seems broken.
+
+3.3.  Jam internal code changes
+
+	$JAMUNAME is set on UNIX.  (2.2.4).
+
+	Jam ANSI-fied (2.3.0).
+
+	jam.h now defines a bunch of symbols used by the other source
+	files, so as minimize compiler- and platform-specific ifdefs.
+
+	OSVER is no longer set by jam.h (it was only set for AIX).
+	Jam does not depend on this variable at all, except to set
+	$(OSFULL), which is used to determine jam's build directory.
+	If the user needs to distinguish between various revs of 
+	OSs, he must set OSVER in the environment.
+
+4.  Fixed bugs
+
+	Redefining a rule while it was executing could cause jam to
+	crash.  Reference counts are now used to prevent that, thanks
+	to Matt Armstrong.
+
+	Logic for computing chunk size when executing PIECEMEAL rules
+	has been reworked to be a little more accurate, without danger
+	of overflow, at the cost of being a little more compute intensive.
+	Instead of computing an estimate chunksize in the (now gone)
+	make1chunk(), make1cmds() now just goes full bore and tries to
+	use all args.  When that fails, it backs off by 10% of the source
+	args until the command fits.  It takes a little bit more compute
+	time compared to the old logic, but when you're executing actions
+	to build all of Shinola it's still pretty small in the scheme
+	of things.
+
+	The NT handle leak in execunix.c has been fixed, thanks to
+	Gurusamy Sarathy.  (2.2.1).
+
+5.  Porting
+
+	Platforms newly supported or updated:
+
+	    AmigaOS (with gcc), courtesy of Alain Penders (2.2.2).
+
+	    Beos
+
+	    CYGWIN 1.1.4, courtesy of John Belmonte <john at nanaon-sha.co.jp>.
+
+	    IBM AS400 via Visual Age on NT (primitive)
+
+	    IBM OS/390 Unix System Services
+
+	    Linux SuSE on OS390
+
+	    Linux Mips, ARM
+
+	    Lynx
+
+	    HPUX 11, IA64
+
+	    Mac OS X Server, courtesy of Jeff_Sickel at sickel.com (2.2.5).
+
+	    Mac Rhapsody
+
+	    MPE IX 6.0
+
+	    NetBSD
+
+	    QNX RTP (QNX 6.0)
+
+	    Siemens Sinix
+
+	    UNICOS
+
+	    VMS 6.2, 7.1
+
+	    Windows NT IA64
+
+5.1.  NT Porting Notes
+
+	Always create tmp .bat file for actions if JAMSHELL is set.
+	That way, if JAMSHELL is a .bat file itself, it can handle
+	single-command actions with more than 9 cmd line args.
+
+	COMSPEC is no longer examined: cmd.exe is always used
+	instead.  Only cmd.exe can execute the Jambase rules anyhow.
+
+	Jam can be built with Borland C++ 5.5.
+
+	OS2 fixes: InstallBin now works.  Filenames are now downshifted,
+	so mixed case works better there, too.  file_dirscan() can now scan 
+	the root ("c:\" or "\") directory, which it couldn't handle before.
+
+	var_defines now ignores OS=Windows_NT, because it conflicts
+	with Jam's setting of OS (to NT).
+
+5.2. Mac OS 8/9 Notes
+
+	The support for Mac is curious at best.  It runs under MPW.
+
+	It requires CodeWarrior Pro 5, but no longer requires GUSI.
+
+	Use Build.mpw to bootstrap the build.
+
+	The Mac specific definitions in the Jambase are not intended
+	to be of general purpose, but are sufficient to have Jam build
+	itself.
+
+===============================================================================
+===============================================================================
+
+
+Release Notes for Jam 2.2
+
+1.  Release info:
+
+	Jam 2.2
+	October 22, 1997
+	VERSION 2.2
+	PATCHLEVEL 1
+
+2. Compatibility
+
+	Jam 2.2 is a roll-up of 'Jam - make(1) redux' release 2.1+.
+	Most of the changes described below were available before this,
+	in the jam.2.1.plus.tar ball.
+
+	The Jam 2.2 language is a superset of the 2.1 language;
+	Jamfiles, Jambase, and other rulesets used in 2.1 can be used
+	with the 2.2 language support.
+
+	See 'Jambase Changes', below, to see if your Jamfiles need any
+	changes to work with the 2.2 Jambase.
+
+
+3. Changes Since 2.1
+
+	New product name: Jam. (Executable program is still named 'jam'.)
+
+	Documentation rewritten; HTML versions supplied.
+
+
+3.1 Changes to Jam Language 
+
+	Rules may now have more fields than just $(<) and $(>).
+
+	Local variables are now supported.
+
+	The expression 'if $(A) in $(B)' is now supported.
+
+	New variable modifiers :U and :L result in uppercased or lowercased
+	values.
+
+	New variable modifier :P reliably results in parent directory
+	of either a file or directory. (Previously, :D was used, but on VMS
+	:D of a directory name is just the directory name.)
+
+	The :S variable modifier now results in the _last_ suffix if a 
+	filename has more than one dot (.) in it.
+
+	New predefined $(JAMDATE) variable is initialized at runtime for 
+	simple date stamping.
+
+	New predefined variables $(OSVER) and $(OSPLAT) are used to 
+	distinguish among operating system versions and hardware platforms,
+	when possible.
+
+	New 'bind' qualifier on action definitions allows variables
+	other than $(<) and $(>) to be bound with SEARCH and LOCATE paths.
+
+	Action buffer size is no longer limited by MAXCMD. Instead, each 
+	line in an action is limited by MAXLINE, defined for each OS, and 
+	the entire action size is limited by CMDBUF.
+
+
+3.2 Jambase Changes (See Jamfile.html)
+
+	Jambase has been reworked to incorporate new language features.
+
+	A handful of new utility rules has been added: makeString,
+	makeDirName, etc.
+
+	New HDRGRIST variable in Jambase allows for headers with the same
+	name to be distinguished.
+
+	LOCATE_TARGET now has a new flavor, LOCATE_SOURCE, that is used by
+	rules that generate source files (e.g., Yacc and Lex).
+
+	Header file includes now happen in the proper order. The limit of
+	10 include files has been eliminated.
+
+	The old "Install" rule is no longer available.  Use InstallBin, 
+	InstallFile, InstallLib, InstallMan, or InstallShell instead.
+
+
+3.3 'jam' Changes (See Jam.html)
+
+	'jam' can now be built as a stand-alone program, with Jambase 
+	compiled into the executable. An external or alternate Jambase can 
+	still be referenced explicitly with -f.
+
+	On command failure, 'jam' now emits the text of the command that 
+	failed.  This is a compromise between the normal -d1 behavior (where 
+	commands were never seen) and -d2 (where commands are always seen).
+
+	'jam' now exits non-zero if it doesn't have a total success.  A parse
+	error, sources that can't be found, and targets that can't be built
+	all generate non-zero exit status.
+	
+	The debugging levels (-d flags) have been slightly redefined.
+
+	The supplied Jamfile now builds 'jam' into a platform specific 
+	subdirectory. This lets you use the same source directory to
+	build 'jam' for more than one platform.
+
+	The supplied Jamfile does not rebuild generated source files by 
+	default. (They are supplied with the distribution.) See Jamfile
+	for more information.
+
+
+4.  Fixed Bugs
+
+	The 'include' bug has finally been fixed, so that include
+	statements take effect exactly when they are executed,
+	rather than after the current statement block.  This also
+	corrects the problem where an 'include' within an 'if'
+	block would wind up including the file one token after the
+	'if' block's closing brace.  Credit goes to Thomas Woods
+	for suggesting that the parse tree generation and parse
+	tree execution be paired in their own loop, rather than
+	having the parser execute the tree directly.
+
+	The setting and extracting of grist has been regularized:
+	normally, if you set a component of a filename (using the
+	:DBSMG= modifiers), you are supposed to include the delimiters
+	that set off the component:  that is, you say "$(x:S=.suffix)",
+	including the ".".  But with grist it was inconsistent
+	between setting and getting: setting grist required no
+	<>'s, while getting grist included them.   Getting grist
+	continues to return the <>'s, but now setting grist can
+	either include them (the new way) or not (the old way).
+
+	'actions together' now suppresses duplicate sources from
+	showing up in $(>).
+
+	Accessing variables whose names contained ['s (as happens with
+	MkDir on VMS) wasn't working, because it treated the [ as an
+	array subscript. Now [ and ] are, like :, handled specially so 
+	that they can appear in variable values.
+
+	The 'if' statement now compares all elements in expressions;
+	previously, it only compared the first element of each list.
+
+	If a command line in an action is longer than MAXLINE (formerly
+	MAXCMD), 'jam' now issues an error and exits rather than dumping 
+	core.
+
+	If a Jamfile ended without a trailing newline, jam dumped core.
+	This has been fixed.
+
+
+5.  Porting
+
+	See jam.h for the definitive list of supported platforms.
+	Since 2.1, support has been added for:
+
+	    Macintosh MPW
+	    Alpha VMS
+	    Alpha NT
+	    NT PowerPC
+	    BeOS
+	    MVS OE
+	    UNIXWARE
+	    QNX
+	    SINIX (Nixdorf)
+	    OS/2
+	    Interactive UNIX (ISC), courtesy of Matthew Newhook
+
+
+5.1 NT Support Fixes
+
+	The NT command executor now handles multiple line actions, by writing
+	multi-line actions to a batch file and executing that.
+	
+	Targets are universally lowercased on NT. (Matthew Newhook)
+
+	Concurrent process support is fully enabled for NT.
+	(Gurusamy Sarathy <gsar at engin.umich.edu>)
+	
+	Path handling: Jam now knows that the directory component of "D:\"
+	is "D:\", just as on unix it knows that the directory component of
+	"/" is "/".  It also now successfully gets the timestamp for "D:\"
+	or just plain "\".
+
+
+5.2 VMS Support Fixes
+
+	VMS support is much, much better now.  The path name manipulation
+	routines (in pathvms.c) were more or less rewritten, and they now
+	handle the vagaries of combining directory and file names properly.
+
+	Targets are universally lowercased on VMS.
+
+	Multi-line command blocks on VMS are now executed in a single system()
+	call rather than separate ones for each line, so that actions can
+	be DCL scripts.
+
+===============================================================================
+===============================================================================
+
+
+Release notes for Jam 2.1.
+
+1.  Release info:
+	Jam 2.1
+	February 1, 1996
+	VERSION 2.1
+	PATCHLEVEL 0
+
+2.  Porting
+
+	Linux is now supported.
+
+	FREEBSD is now supported.
+
+	SCO ("M_XENIX") now supported.
+
+	NCR now supported.
+
+	NEXT support from karthy at dannug.dk (Karsten Thygesen)
+
+	DECC support from zinser at axp614.gsi.de (Martin P.J. Zinser)
+
+	I have changes for OS/2, but no way to test them.  Volunteers?
+	I have VMS multiprocess support, but no way to test it.  Volunteers?
+
+2.1.  NT Support fixes.
+
+	The NT support is considerably more real than it was in 2.0.
+	Filent.c had its syntax error corrected, it no longer skips the
+	first entry when scanning directories, and it handles string
+	tables in archives (for long object file names).
+
+	The Jambase was changed a bit to support the various C/C++
+	compilers on NT, although it has only been thorougly tested
+	with MSVC20.
+
+	You still need to set MSVCNT or BCCROOT to the root of the 
+	the compiler's directory tree, and you'll get an error if you
+	don't set it (rather than getting a pile of mysterious errors).
+
+2.2.  Other porting fixes.
+
+	SPLITPATH now set up for UNIX (:), NT (;), VMS (,)
+
+	Jambase support for Solaris works better now: the location of
+	AR is hardwired to /usr/ccs/bin/ar and it knowns "install"
+	doesn't take -c.  Solaris -- how the mighty have fallen.
+
+	To handle Linux's wacko yacc, jamgram.h is now included after
+	scan.h so that YYSTYPE is define.
+
+3.  Jambase Changes (see Jamfile.html)
+
+	SubDir now computes the root directory for the source tree, if
+	the variable naming the root directory isn't set in the environment.
+	It counts the number of directory elements leading from the root
+	to the current directory (as passed to SubDir) and uses that many
+	"../"'s to identify the root.  This means that to use SubDir you
+	no longer have to have anything special set in the environment.
+
+	InstallFile is now an alias for InstallLib.
+
+	'first' is now dependency of all pseudo-targets (all, files, 
+	exe, lib, shell), so that jamming any of these pseudo-targets
+	also builds any dependencies of 'first'.
+
+	The File rule definition in the Jambase was missing an &.
+
+	The File rule now calls the Clean rule, so that installed files
+	get cleaned.
+
+4.  Jam changes (see Jam.html)
+
+	Variables may now be set on the command line with -svar=value.
+
+	Targets marked with NOUPDATE are now immune to the -a (anyhow) 
+	flag.  Previously, the MkDir rule would try to recreate directories
+	that already exist when jam was invoked with -a.
+
+	A new variable, $(JAMVERSION), joins the small list of built-in 
+	variables.  It it set to the release of jam, currently "2.1".
+
+	If an actions fails, jam now deletes the target(s).  It won't
+	delete libraries or other targets that are composites.  This is
+	now consistent with jam's behavior on interrupts (it deletes the
+	targets).
+
+	Jam had a nasty bug when setting multiple variables to the same
+	value:  if the first two variable names were the same, the variable
+	value got trashed.  This also affected "on target" variables if
+	the first two targets were the same.  For example:
+
+		FOO on bar.c bar.c foo.c = a b c ;
+
+	This would mangle the value of FOO for bar.c and foo.c.  This has
+	been fixed.
+
+	Jam would generate bogus numbers when reporting the number of
+	targets updated after an interrupt.  It now is more careful about
+	counting.
+
+	The debugging flag -d has been extended.  In addition to supporting
+	-dx (turn on debugging for all levels up to x) there is also now
+	-d+x (turn on debugging at only level x).  The default output
+	level is -d1 (-or d2 if -n is given); this can be turned off with
+	-d0.   The debug levels are listed in jam.1 and jam.h.
+
+	The parsing debug output now uses indenting to indicate when
+	one rule invokes another.
+
+===============================================================================
+===============================================================================
+
+
+Release notes for Jam 2.0.
+
+1.  Release info:
+	Jam 2.0 
+	March 10, 1994
+	VERSION 2.0
+	PATCHLEVEL 5
+
+2.  Porting
+
+	Windows/NT is now (crudely) supported, courtesy of Brett Taylor
+	and Laura Wingerd.  
+
+	COHERENT/386 is now supported, courtesy of Fred Smith.
+
+	Solaris archive string table for long archive names is now
+	supported, thanks to Mike Matrigali.
+
+3.  Compatibility
+
+	Jam 2.0 syntax is a superset of Jam 1.0 syntax, and thus it can
+	interpret a Jam 1.0 Jambase.
+
+	The Jam 2.0 Jambase is a superset of the Jam 1.0 Jambase, and
+	thus it can include a Jamfile written for Jam 1.0.
+
+4.  Changes from Jam 1.0 to Jam 2.0
+
+4.1.  Documentation changes
+
+	New Jamfile.5 manual page, with lots of examples and easy
+	reading.  It replaces both the old "Examples" file as well as
+	the old Jambase.5 manual page.
+
+	jam.1 edited by Stephen W. Liddle and Diane Holt.
+
+4.2.  Jambase Changes (see Jamfile.5)
+
+4.2.1.  New rules:
+
+	There are new rules to make handling subdirectories easier:
+	SubDir, SubInclude, SubDirCcFlags, SubDirHdrs.
+
+	There are new rules to handle file-specific CCFLAGS and HDRS:
+	ObjectCcFlags and ObjectHdrs.
+
+	Misc new rules: HardLink, InstallShell, MkDir.
+
+	New rule "clean" that deletes exactly what jam has built, and
+	"uninstall" that deletes exactly what was installed.
+
+	New rules for handling suffixes .s, .f, .cc, .cpp, .C.
+
+4.2.2.  Old rules:
+
+	The InstallBin, Lib, Man, and the new Shell rules now take the
+	destination directory as the target and the files to be copied
+	as sources.  These rules formerly took the files to be copied
+	as targets, and used built-in destination directories of
+	$(BINDIR), $(LIBDIR), $(MANDIR), and $(BINDIR).
+
+	The InstallBin, Lib, Man, and Shell rules use the install(1)
+	program now, instead of doing their own copying.
+
+	The Cc rule now uses -o when possible, rather than moving the
+	result.  Some platforms (Pyramid?) have a broken -o.
+
+	Jambase rules taking libraries, objects, and executables now
+	all ignore the suffixes provided and use the one defined in the
+	Jambase for the platform.
+
+	Stupid yyacc support moved out of Jambase, as jam is its only
+	likely user.
+
+	Jambase now purturbs library sources with a "grist" of
+	SOURCE_GRIST.
+
+4.2.3.  Misc:
+
+	The names of the default rules defined in Jambase have been
+	lowercased and un-abbreviated, to be more imake(1) like.
+
+	The Jambase has been reorganized and sorted, with VMS and NT
+	support moved in from their own files.
+
+	The Jambase has been relocated on UNIX from /usr/local/lib/jam
+	to /usr/local/lib.
+
+4.3.  Jam changes (see jam.1)
+
+4.3.1.   Flags:
+
+	New -a (anyhow) flag: means build everything.
+
+	New -j<x> flag: run jobs in parallel.
+
+	Old -t now rebuilds the touched target, rather that just the
+	target's parents.
+
+	-n now implies -d2, so that you see what's happening.  The
+	debug level can be subsequently overridden.
+
+	New -v to dump version.
+
+4.3.2.  Rules:
+
+	New ALWAYS rule behaves like -t: always builds target.
+
+	New EXIT rule makes it possible to raise a fatal error.
+
+	New LEAVES rule which say target depends only on the update
+	times of the leaf sources.
+
+	New NOUPDATE rule says built targets only if they don't exist.
+
+	NOTIME has been renamed NOTFILE, to more accurately reflect its
+	meaning (it says a target is not to be bound to a file).
+
+4.3.3.  Variables:
+
+	New special variable JAMSHELL: argv template for command execution 
+	shell.
+
+	Variables, both normal and target-specific, can have their
+	value appended with the syntax "var += value" or "var on target
+	+= value".
+
+	"?=" is now synonymous with "default =".
+
+	Imported enviroment variable values are now split at blanks
+	(:'s if the variable name ends in PATH), so that they become
+	proper list values.
+
+4.3.4.  Misc:
+
+	Files to be sourced with "include" are now bound first, so
+	$(SEARCH) and $(LOCATE) affect them.  They still can't be
+	built, though.
+
+	New modifier on "actions": "existing" causes $(>) to expand
+	only those files that currently exist.
+
+4.3.5.  Bug fixes:
+
+	When scanning tokens known to be argument lists (such as the
+	arguments to rule invocations and variable assignment), the
+	parser now tells the scanner to ignore alphabetic keywords, as
+	all such lists terminate with punctuation keywords (like : or
+	;).  This way, alphabetic keywords don't need to be quoted when
+	they appear as arguments.
+
+	The scanner has been fixed to handle oversized tokens,
+	unterminated quotes, unterminated action blocks, and tokens
+	abutting EOF (i.e. a token with no white space before EOF).
+
+	The progress report "...on xth target..." used to count all
+	targets, rather than just those with updating actions.  Since
+	the original pronouncement of targets to be udpated included
+	only those with updating actions, the progress report has been
+	changed to match.
+
+	'If' conditionals now must be single arguments.  Previously,
+	they could be zero or more arguments, which didn't make much
+	sense, and made things like 'foo == bar' true.  The comparison
+	operator is '=', and '==' just looked like the second of three
+	arguments in the unary "non-empty argument list" conditional.
+
+	Header files indirectly including themselves were mistakenly
+	reported as being dependent on themselves.  Recursing through
+	header file dependencies is now done after determining the fate
+	of the target.
+
+	The variable expansion support was expanding $(X)$(UNDEF) as if
+	it were $(X).  It now expands to an empty list, like it
+	should.
+
+	The UNIX version of file_build() didn't handle "dir/.suffix"
+	right.  Now it does.
+
+	The VMS command buffer was assumed to be as large as 1024 bytes,
+	which isn't the case everywhere as it is related to some weird
+	quota.  It has been lowered to 256.
+
+	$(>) and $(<) wouldn't expand in action blocks if the targets
+	were marked with NOTIME.  Now they expand properly.
+
+	Malloc() return values are now checked.
+
+	The variable expansion routine var_expand() is now a little
+	faster, by taking a few often needed shortcuts.
+
+	The VMS version of file_build() used the wrong length when
+	re-rooting file names that already had directory compoents.
+	This was fixed.
+
+	Various tracing adjustments were made.
+
+5.  Limitations/Known Bugs
+
+	The new Windows/NT support has only been marginally tested.  It
+	is dependent on certain variables being set depending on which
+	compiler you are using.  You'll need to look in the file
+	Jambase and see what variables are expected to be set.
+
+	The VMS support has been tested, courtesy of the DEC guest
+	machine, but has not been hammered fully in release 2.0.  It
+	was used quite a bit in Jam 1.0.
+
+	Jam clean when there is nothing to clean claims it is updating
+	a target.
+
+	Because the include statement works by pushing a new file in
+	the input stream of the scanner rather than recursively
+	invoking the parser on the new file, multiple include
+	statements in a rule's procedure causes the files to be
+	included in reverse order.
+
+	If the include statement appears inside an if block, the
+	parser's attempt to find the else will cause the text of the
+	included file to appear after the first token following the
+	statement block.  This is rarely what is intended.
+
+	In a rule's actions, only $(<) and $(>) refer to the bound file
+	names:  all other variable references get the unbound names.
+	This is a pain for $(NEEDLIBS), because it means that library
+	path can't be bound using $(SEARCH) and $(LOCATE).
+
+	With the -j flag, errors from failed commands can get
+	staggeringly mixed up.  Also, because targets tend to get built
+	in a quickest-first ordering, dependency information must be
+	quite exact.  Finally, beware of parallelizing commands that
+	drop fixed-named files into the current directory, like yacc(1)
+	does.
+
+	A poorly set $(JAMSHELL) is likely to result in silent
+	failure.

Added: boost-jam/boost-build/branches/upstream/current/jam_src/boost-jam.spec
===================================================================
--- boost-jam/boost-build/branches/upstream/current/jam_src/boost-jam.spec	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/jam_src/boost-jam.spec	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,64 @@
+Name: boost-jam
+Version: 3.1.10
+Summary: Build tool
+Release: 1
+Source: %{name}-%{version}.tgz
+
+License: Boost Software License, Version 1.0
+Group: Development/Tools
+URL: http://www.boost.org
+Packager: Rene Rivera <grafik at redshift-software.com>
+BuildRoot: /var/tmp/%{name}-%{version}.root
+
+%description
+Boost Jam is a build tool based on FTJam, which in turn is based on 
+Perforce Jam. It contains significant improvements made to facilitate
+its use in the Boost Build System, but should be backward compatible 
+with Perforce Jam.
+
+Authors:
+    Perforce Jam : Cristopher Seiwald
+    FT Jam : David Turner
+    Boost Jam : David Abrahams
+
+Copyright:
+    /+\
+    +\  Copyright 1993-2002 Christopher Seiwald and Perforce Software, Inc.
+    \+/
+    License is hereby granted to use this software and distribute it
+    freely, as long as this copyright notice is retained and modifications 
+    are clearly marked.
+    ALL WARRANTIES ARE HEREBY DISCLAIMED.
+
+Also:
+    Copyright 2001-2004 David Abrahams.
+    Copyright 2002-2004 Rene Rivera.
+    
+    Distributed under the Boost Software License, Version 1.0.
+    (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+
+%prep
+%setup -n %{name}-%{version}
+
+%build
+LOCATE_TARGET=bin ./build.sh $BOOST_JAM_TOOLSET
+
+%install
+rm -rf $RPM_BUILD_ROOT
+mkdir -p $RPM_BUILD_ROOT%{_bindir}
+mkdir -p $RPM_BUILD_ROOT%{_docdir}/%{name}-%{version}
+install -m 755 bin/bjam $RPM_BUILD_ROOT%{_bindir}/bjam-%{version}
+ln -sf bjam-%{version} $RPM_BUILD_ROOT%{_bindir}/bjam
+ln -sf bjam-%{version} $RPM_BUILD_ROOT%{_bindir}/jam
+install -m 644 *.html *.txt Porting $RPM_BUILD_ROOT%{_docdir}/%{name}-%{version}
+
+find $RPM_BUILD_ROOT -name CVS -type d -depth -exec rm -r {} \;
+
+%files
+%defattr(-,root,root)
+%attr(755,root,root) /usr/bin/*
+%doc %{_docdir}/%{name}-%{version}
+
+
+%clean
+rm -rf $RPM_BUILD_ROOT

Added: boost-jam/boost-build/branches/upstream/current/jam_src/build.bat
===================================================================
--- boost-jam/boost-build/branches/upstream/current/jam_src/build.bat	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/jam_src/build.bat	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,364 @@
+ at ECHO OFF
+
+REM ~ Copyright 2002-2003 Rene Rivera.
+REM ~ Distributed under the Boost Software License, Version 1.0.
+REM ~ (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+
+setlocal
+goto Start
+
+REM NOTE: The "setlocal & endlocal" construct is used to reset the errorlevel to 0.
+REM NOTE: The "set _error_=" construct is used to set the errorlevel to 1
+
+:Error_Print
+REM Output an error message and set the errorlevel to indicate failure.
+setlocal
+ECHO ###
+ECHO ### %1
+ECHO ###
+ECHO ### You can specify the toolset as the argument, i.e.:
+ECHO ###     .\build.bat msvc
+ECHO ###
+ECHO ### Toolsets supported by this script are: borland, como, gcc, gcc-nocygwin, intel-win32, metrowerks, mingw, msvc, vc7
+ECHO ###
+set _error_=
+endlocal
+goto :eof
+
+:Test_Path
+REM Tests for the given file(executable) presence in the directories in the PATH
+REM environment variable. Additionaly sets FOUND_PATH to the path of the
+REM found file.
+setlocal & endlocal
+setlocal
+set test=%~$PATH:1
+endlocal
+if not errorlevel 1 set FOUND_PATH=%~dp$PATH:1
+goto :eof
+
+:Test_Option
+REM Tests wether the given string is in the form of an option: "-*"
+setlocal & endlocal
+setlocal
+set test=%1
+if not "-" == "%test:~0,1%" set _error_=
+endlocal
+goto :eof
+
+:Guess_Toolset
+REM Try and guess the toolset to bootstrap the build with...
+REM Sets BOOST_JAM_TOOLSET to the first found toolset.
+REM May also set BOOST_JAM_TOOLSET_ROOT to the
+REM location of the found toolset.
+setlocal & endlocal
+if NOT "_%CWFolder%_" == "__" (
+    set BOOST_JAM_TOOLSET=metrowerks
+    set BOOST_JAM_TOOLSET_ROOT=%CWFolder%\
+    goto :eof )
+setlocal & endlocal
+call :Test_Path mwcc.exe
+if not errorlevel 1 (
+    set BOOST_JAM_TOOLSET=metrowerks
+    set BOOST_JAM_TOOLSET_ROOT=%FOUND_PATH%..\..\
+    goto :eof)
+setlocal & endlocal
+if NOT "_%VS71COMNTOOLS%_" == "__" (
+    set BOOST_JAM_TOOLSET=vc7
+    set BOOST_JAM_TOOLSET_ROOT=%VS71COMNTOOLS%\..\..\VC7\
+    goto :eof)
+setlocal & endlocal
+if NOT "_%VCINSTALLDIR%_" == "__" (
+    set BOOST_JAM_TOOLSET=vc7
+    set BOOST_JAM_TOOLSET_ROOT=%VCINSTALLDIR%\VC7\
+    goto :eof)
+setlocal & endlocal
+if EXIST "%ProgramFiles%\Microsoft Visual Studio .NET 2003\VC7\bin\VCVARS32.BAT" (
+    set BOOST_JAM_TOOLSET=vc7
+    set BOOST_JAM_TOOLSET_ROOT=%ProgramFiles%\Microsoft Visual Studio .NET 2003\VC7\
+    goto :eof)
+setlocal & endlocal
+if EXIST "C:\Program Files\Microsoft Visual Studio .NET 2003\VC7\bin\VCVARS32.BAT" (
+    set BOOST_JAM_TOOLSET=vc7
+    set BOOST_JAM_TOOLSET_ROOT=C:\Program Files\Microsoft Visual Studio .NET 2003\VC7\
+    goto :eof)
+setlocal & endlocal
+if EXIST "%ProgramFiles%\Microsoft Visual Studio .NET\VC7\bin\VCVARS32.BAT" (
+    set BOOST_JAM_TOOLSET=vc7
+    set BOOST_JAM_TOOLSET_ROOT=%ProgramFiles%\Microsoft Visual Studio .NET\VC7\
+    goto :eof)
+setlocal & endlocal
+if EXIST "C:\Program Files\Microsoft Visual Studio .NET\VC7\bin\VCVARS32.BAT" (
+    set BOOST_JAM_TOOLSET=vc7
+    set BOOST_JAM_TOOLSET_ROOT=C:\Program Files\Microsoft Visual Studio .NET\VC7\
+    goto :eof)
+setlocal & endlocal
+if NOT "_%MSVCDir%_" == "__" (
+    set BOOST_JAM_TOOLSET=msvc
+    set BOOST_JAM_TOOLSET_ROOT=%MSVCDir%\
+    goto :eof)
+setlocal & endlocal
+if EXIST "%ProgramFiles%\Microsoft Visual Studio\VC98\bin\VCVARS32.BAT" (
+    set BOOST_JAM_TOOLSET=msvc
+    set BOOST_JAM_TOOLSET_ROOT=%ProgramFiles%\Microsoft Visual Studio\VC98\
+    goto :eof)
+setlocal & endlocal
+if EXIST "C:\Program Files\Microsoft Visual Studio\VC98\bin\VCVARS32.BAT" (
+    set BOOST_JAM_TOOLSET=msvc
+    set BOOST_JAM_TOOLSET_ROOT=C:\Program Files\Microsoft Visual Studio\VC98\
+    goto :eof)
+setlocal & endlocal
+if EXIST "%ProgramFiles%\Microsoft Visual C++\VC98\bin\VCVARS32.BAT" (
+    set BOOST_JAM_TOOLSET=msvc
+    set BOOST_JAM_TOOLSET_ROOT=%ProgramFiles%\Microsoft Visual C++\VC98\
+    goto :eof)
+setlocal & endlocal
+if EXIST "C:\Program Files\Microsoft Visual C++\VC98\bin\VCVARS32.BAT" (
+    set BOOST_JAM_TOOLSET=msvc
+    set BOOST_JAM_TOOLSET_ROOT=C:\Program Files\Microsoft Visual C++\VC98\
+    goto :eof)
+setlocal & endlocal
+call :Test_Path cl.exe
+if not errorlevel 1 (
+    set BOOST_JAM_TOOLSET=msvc
+    set BOOST_JAM_TOOLSET_ROOT=%FOUND_PATH%..\
+    goto :eof)
+setlocal & endlocal
+call :Test_Path vcvars32.bat
+if not errorlevel 1 (
+    set BOOST_JAM_TOOLSET=msvc
+    call "%FOUND_PATH%VCVARS32.BAT"
+    set BOOST_JAM_TOOLSET_ROOT=%MSVCDir%\
+    goto :eof)
+setlocal & endlocal
+if EXIST "C:\Borland\BCC55\Bin\bcc32.exe" (
+    set BOOST_JAM_TOOLSET=borland
+    set BOOST_JAM_TOOLSET_ROOT=C:\Borland\BCC55\
+    goto :eof)
+setlocal & endlocal
+call :Test_Path bcc32.exe
+if not errorlevel 1 (
+    set BOOST_JAM_TOOLSET=borland
+    set BOOST_JAM_TOOLSET_ROOT=%FOUND_PATH%..\
+    goto :eof)
+setlocal & endlocal
+call :Test_Path icl.exe
+if not errorlevel 1 (
+    set BOOST_JAM_TOOLSET=intel-win32
+    set BOOST_JAM_TOOLSET_ROOT=%FOUND_PATH%..\
+    goto :eof)
+setlocal & endlocal
+if EXIST "C:\MinGW\bin\gcc.exe" (
+    set BOOST_JAM_TOOLSET=mingw
+    set BOOST_JAM_TOOLSET_ROOT=C:\MinGW\
+    goto :eof)
+setlocal & endlocal
+call :Error_Print "Could not find a suitable toolset."
+goto :eof
+
+:Guess_Yacc
+REM Tries to find bison or yacc in common places so we can build the grammar.
+setlocal & endlocal
+call :Test_Path yacc.exe
+if not errorlevel 1 (
+    set YACC=yacc -d
+    goto :eof)
+setlocal & endlocal
+call :Test_Path bison.exe
+if not errorlevel 1 (
+    set YACC=bison -d --yacc
+    goto :eof)
+setlocal & endlocal
+if EXIST "C:\Program Files\GnuWin32\bin\bison.exe" (
+    set YACC="C:\Program Files\GnuWin32\bin\bison.exe" -d --yacc
+    goto :eof)
+setlocal & endlocal
+call :Error_Print "Could not find Yacc to build the Jam grammar."
+goto :eof
+
+:Start
+set BOOST_JAM_TOOLSET=
+
+REM If no arguments guess the toolset;
+REM or if first argument is an option guess the toolset;
+REM otherwise the argument is the toolset to use.
+if "_%1_" == "__" (
+    call :Guess_Toolset
+    if not errorlevel 1 goto Setup_Toolset
+) else (
+    call :Test_Option %1
+    if not errorlevel 1 (
+        call :Guess_Toolset
+        if not errorlevel 1 goto Setup_Toolset
+    ) else (
+        setlocal & endlocal
+        set BOOST_JAM_TOOLSET=%1
+        shift
+        goto Setup_Toolset
+    )
+)
+if errorlevel 1 goto Finish
+
+:Setup_Toolset
+REM Setup the toolset command and options. This bit of code
+REM needs to be flexible enough to handle both when
+REM the toolset was guessed at and found, or when the toolset
+REM was indicated in the command arguments.
+REM NOTE: The strange multiple "if ?? == _toolset_" tests are that way
+REM because in BAT variables are subsituted only once during a single
+REM command. A complete "if ... ( commands ) else ( commands )"
+REM is a single command, even though it's in multiple lines here.
+if "_%BOOST_JAM_TOOLSET%_" == "_metrowerks_" (
+    if NOT "_%CWFolder%_" == "__" (
+        set BOOST_JAM_TOOLSET_ROOT=%CWFolder%\) )
+if "_%BOOST_JAM_TOOLSET%_" == "_metrowerks_" (
+    if not "_%BOOST_JAM_TOOLSET_ROOT%_" == "__" (
+        set PATH=%BOOST_JAM_TOOLSET_ROOT%Other Metrowerks Tools\Command Line Tools;%PATH%)
+    set BOOST_JAM_CC=mwcc -runtime ss -cwd include -DNT -ladvapi32.lib
+    set BOOST_JAM_OPT_JAM=-o bootstrap.%BOOST_JAM_TOOLSET%\jam0.exe
+    set BOOST_JAM_OPT_MKJAMBASE=-o bootstrap.%BOOST_JAM_TOOLSET%\mkjambase0.exe
+    set BOOST_JAM_OPT_YYACC=-o bootstrap.%BOOST_JAM_TOOLSET%\yyacc0.exe
+    set _known_=1
+)
+if "_%BOOST_JAM_TOOLSET%_" == "_msvc_" (
+    if NOT "_%MSVCDir%_" == "__" (
+        set BOOST_JAM_TOOLSET_ROOT=%MSVCDir%\) )
+if "_%BOOST_JAM_TOOLSET%_" == "_msvc_" (
+    if EXIST "%BOOST_JAM_TOOLSET_ROOT%bin\VCVARS32.BAT" (
+        call "%BOOST_JAM_TOOLSET_ROOT%bin\VCVARS32.BAT" ) )
+if "_%BOOST_JAM_TOOLSET%_" == "_msvc_" (
+    if not "_%BOOST_JAM_TOOLSET_ROOT%_" == "__" (
+        set PATH=%BOOST_JAM_TOOLSET_ROOT%bin;%PATH%)
+    set BOOST_JAM_CC=cl /nologo /GZ /Zi /MLd -DNT -DYYDEBUG kernel32.lib advapi32.lib
+    set BOOST_JAM_OPT_JAM=/Febootstrap.%BOOST_JAM_TOOLSET%\jam0
+    set BOOST_JAM_OPT_MKJAMBASE=/Febootstrap.%BOOST_JAM_TOOLSET%\mkjambase0
+    set BOOST_JAM_OPT_YYACC=/Febootstrap.%BOOST_JAM_TOOLSET%\yyacc0
+    set _known_=1
+)
+if "_%BOOST_JAM_TOOLSET%_" == "_vc7_" (
+    if NOT "_%MSVCDir%_" == "__" (
+        set BOOST_JAM_TOOLSET_ROOT=%MSVCDir%\) )
+if "_%BOOST_JAM_TOOLSET%_" == "_vc7_" (
+    if EXIST "%BOOST_JAM_TOOLSET_ROOT%bin\VCVARS32.BAT" (
+        call "%BOOST_JAM_TOOLSET_ROOT%bin\VCVARS32.BAT" ) )
+if "_%BOOST_JAM_TOOLSET%_" == "_vc7_" (
+    if not "_%BOOST_JAM_TOOLSET_ROOT%_" == "__" (
+        set PATH=%BOOST_JAM_TOOLSET_ROOT%bin;%PATH%)
+    set BOOST_JAM_CC=cl /nologo /GZ /Zi /MLd -DNT -DYYDEBUG kernel32.lib advapi32.lib
+    set BOOST_JAM_OPT_JAM=/Febootstrap.%BOOST_JAM_TOOLSET%\jam0
+    set BOOST_JAM_OPT_MKJAMBASE=/Febootstrap.%BOOST_JAM_TOOLSET%\mkjambase0
+    set BOOST_JAM_OPT_YYACC=/Febootstrap.%BOOST_JAM_TOOLSET%\yyacc0
+    set _known_=1
+)
+if "_%BOOST_JAM_TOOLSET%_" == "_borland_" (
+    if "_%BOOST_JAM_TOOLSET_ROOT%_" == "__" (
+        call :Test_Path bcc32.exe ) )
+if "_%BOOST_JAM_TOOLSET%_" == "_borland_" (
+    if "_%BOOST_JAM_TOOLSET_ROOT%_" == "__" (
+        if not errorlevel 1 (
+            set BOOST_JAM_TOOLSET_ROOT=%FOUND_PATH%..\) ) )
+if "_%BOOST_JAM_TOOLSET%_" == "_borland_" (
+    if not "_%BOOST_JAM_TOOLSET_ROOT%_" == "__" (set PATH=%BOOST_JAM_TOOLSET_ROOT%Bin;%PATH%)
+    set BOOST_JAM_CC=bcc32 -WC -w- -q "-I%BOOST_JAM_TOOLSET_ROOT%Include" "-L%BOOST_JAM_TOOLSET_ROOT%Lib" /DNT -nbootstrap.%BOOST_JAM_TOOLSET%
+    set BOOST_JAM_OPT_JAM=-ejam0
+    set BOOST_JAM_OPT_MKJAMBASE=-emkjambasejam0
+    set BOOST_JAM_OPT_YYACC=-eyyacc0
+    set _known_=1
+)
+if "_%BOOST_JAM_TOOLSET%_" == "_como_" (
+    set BOOST_JAM_CC=como -DNT
+    set BOOST_JAM_OPT_JAM=-o bootstrap.%BOOST_JAM_TOOLSET%\jam0.exe
+    set BOOST_JAM_OPT_MKJAMBASE=-o bootstrap.%BOOST_JAM_TOOLSET%\mkjambase0.exe
+    set BOOST_JAM_OPT_YYACC=-o bootstrap.%BOOST_JAM_TOOLSET%\yyacc0.exe
+    set _known_=1
+)
+if "_%BOOST_JAM_TOOLSET%_" == "_gcc_" (
+    set BOOST_JAM_CC=gcc -DNT
+    set BOOST_JAM_OPT_JAM=-o bootstrap.%BOOST_JAM_TOOLSET%\jam0.exe
+    set BOOST_JAM_OPT_MKJAMBASE=-o bootstrap.%BOOST_JAM_TOOLSET%\mkjambase0.exe
+    set BOOST_JAM_OPT_YYACC=-o bootstrap.%BOOST_JAM_TOOLSET%\yyacc0.exe
+    set _known_=1
+)
+if "_%BOOST_JAM_TOOLSET%_" == "_gcc-nocygwin_" (
+    set BOOST_JAM_CC=gcc -DNT -mno-cygwin
+    set BOOST_JAM_OPT_JAM=-o bootstrap.%BOOST_JAM_TOOLSET%\jam0.exe
+    set BOOST_JAM_OPT_MKJAMBASE=-o bootstrap.%BOOST_JAM_TOOLSET%\mkjambase0.exe
+    set BOOST_JAM_OPT_YYACC=-o bootstrap.%BOOST_JAM_TOOLSET%\yyacc0.exe
+    set _known_=1
+)
+if "_%BOOST_JAM_TOOLSET%_" == "_intel-win32_" (
+    set BOOST_JAM_CC=icl -DNT /nologo
+    set BOOST_JAM_OPT_JAM=/Febootstrap.%BOOST_JAM_TOOLSET%\jam0
+    set BOOST_JAM_OPT_MKJAMBASE=/Febootstrap.%BOOST_JAM_TOOLSET%\mkjambase0
+    set BOOST_JAM_OPT_YYACC=/Febootstrap.%BOOST_JAM_TOOLSET%\yyacc0
+    set _known_=1
+)
+if "_%BOOST_JAM_TOOLSET%_" == "_mingw_" (
+    if not "_%BOOST_JAM_TOOLSET_ROOT%_" == "__" (set PATH=%BOOST_JAM_TOOLSET_ROOT%bin;%PATH%)
+    set BOOST_JAM_CC=gcc -DNT
+    set BOOST_JAM_OPT_JAM=-o bootstrap.%BOOST_JAM_TOOLSET%\jam0.exe
+    set BOOST_JAM_OPT_MKJAMBASE=-o bootstrap.%BOOST_JAM_TOOLSET%\mkjambase0.exe
+    set BOOST_JAM_OPT_YYACC=-o bootstrap.%BOOST_JAM_TOOLSET%\yyacc0.exe
+    set _known_=1
+)
+if "_%_known_%_" == "__" (
+    call :Error_Print "Unknown toolset: %BOOST_JAM_TOOLSET%"
+)
+if errorlevel 1 goto Finish
+
+echo ###
+echo ### Using '%BOOST_JAM_TOOLSET%' toolset.
+echo ###
+
+set YYACC_SOURCES=yyacc.c
+set MKJAMBASE_SOURCES=mkjambase.c
+set BJAM_SOURCES=
+set BJAM_SOURCES=%BJAM_SOURCES% command.c compile.c execnt.c execunix.c execvms.c expand.c
+set BJAM_SOURCES=%BJAM_SOURCES% filent.c fileos2.c fileunix.c filevms.c glob.c hash.c
+set BJAM_SOURCES=%BJAM_SOURCES% hdrmacro.c headers.c jam.c jambase.c jamgram.c lists.c make.c make1.c
+set BJAM_SOURCES=%BJAM_SOURCES% newstr.c option.c parse.c pathunix.c pathvms.c regexp.c
+set BJAM_SOURCES=%BJAM_SOURCES% rules.c scan.c search.c subst.c timestamp.c variable.c modules.c
+set BJAM_SOURCES=%BJAM_SOURCES% strings.c filesys.c builtins.c pwd.c class.c w32_getreg.c native.c
+set BJAM_SOURCES=%BJAM_SOURCES% modules/set.c modules/path.c modules/regex.c 
+set BJAM_SOURCES=%BJAM_SOURCES% modules/property-set.c modules/sequence.c modules/order.c
+
+ at echo ON
+rd /S /Q bootstrap.%BOOST_JAM_TOOLSET%
+md bootstrap.%BOOST_JAM_TOOLSET%
+ at if not exist jamgram.y goto Bootstrap_GrammarPrep
+ at if not exist jamgramtab.h goto Bootstrap_GrammarPrep
+ at goto Skip_GrammarPrep
+:Bootstrap_GrammarPrep
+%BOOST_JAM_CC% %BOOST_JAM_OPT_YYACC% %YYACC_SOURCES%
+ at if not exist ".\bootstrap.%BOOST_JAM_TOOLSET%\yyacc0.exe" goto Skip_GrammarPrep
+.\bootstrap.%BOOST_JAM_TOOLSET%\yyacc0 jamgram.y jamgramtab.h jamgram.yy
+:Skip_GrammarPrep
+ at if not exist jamgram.c goto Bootstrap_GrammarBuild
+ at if not exist jamgram.h goto Bootstrap_GrammarBuild
+ at goto Skip_GrammarBuild
+:Bootstrap_GrammarBuild
+ at echo OFF
+if "_%YACC%_" == "__" (
+    call :Guess_Yacc
+)
+if errorlevel 1 goto Finish
+ at echo ON
+%YACC% jamgram.y
+ at if errorlevel 1 goto Finish
+del /f jamgram.c
+rename y.tab.c jamgram.c
+del /f jamgram.h
+rename y.tab.h jamgram.h
+:Skip_GrammarBuild
+ at echo ON
+ at if exist jambase.c goto Skip_Jambase
+%BOOST_JAM_CC% %BOOST_JAM_OPT_MKJAMBASE% %MKJAMBASE_SOURCES%
+ at if not exist ".\bootstrap.%BOOST_JAM_TOOLSET%\mkjambase0.exe" goto Skip_Jambase
+.\bootstrap.%BOOST_JAM_TOOLSET%\mkjambase0 jambase.c Jambase
+:Skip_Jambase
+%BOOST_JAM_CC% %BOOST_JAM_OPT_JAM% %BJAM_SOURCES%
+ at if not exist ".\bootstrap.%BOOST_JAM_TOOLSET%\jam0.exe" goto Skip_Jam
+.\bootstrap.%BOOST_JAM_TOOLSET%\jam0 -f build.jam --toolset=%BOOST_JAM_TOOLSET% "--toolset-root=%BOOST_JAM_TOOLSET_ROOT% " clean
+.\bootstrap.%BOOST_JAM_TOOLSET%\jam0 -f build.jam --toolset=%BOOST_JAM_TOOLSET% "--toolset-root=%BOOST_JAM_TOOLSET_ROOT% " %1 %2 %3 %4 %5 %6 %7 %8 %9
+:Skip_Jam
+
+:Finish


Property changes on: boost-jam/boost-build/branches/upstream/current/jam_src/build.bat
___________________________________________________________________
Name: svn:executable
   + 

Added: boost-jam/boost-build/branches/upstream/current/jam_src/build.jam
===================================================================
--- boost-jam/boost-build/branches/upstream/current/jam_src/build.jam	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/jam_src/build.jam	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,758 @@
+#~ Copyright 2002-2004 Rene Rivera.
+#~ Distributed under the Boost Software License, Version 1.0.
+#~ (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+
+# Platform related specifics.
+if $(NT) { rule .path { return "$(<:J=\\)" ; } }
+else if $(OS2) { rule .path { return "$(<:J=\\)" ; } }
+else if $(VMS) { rule .path { return "[.$(<:J=/)]" ; } }
+else if $(MAC) { rule .path { return ":$(<:J=\:)" ; } }
+else { rule .path { return "$(<:J=/)" ; } }
+if $(VMS) { . = "_" ; }
+else { . = "." ; }
+
+# Info about what we are building.
+NAME = boost-jam ;
+VERSION = 3$(.)1$(.)10 ;
+RELEASE = 1 ;
+LICENSE = 1_0 ;
+
+# Generate development debug binaries?
+if --debug in $(ARGV)
+{
+    debug = true ;
+}
+
+# Attempt to generate and/or build the grammar?
+if --grammar in $(ARGV)
+{
+    grammar = true ;
+}
+
+# Do we need to add a default build type argument?
+if ! ( --release in $(ARGV) ) &&
+   ! ( --debug in $(ARGV) )
+{
+    ARGV += --release ;
+}
+
+# An explicit root for the toolset? (trim spaces)
+toolset-root = [ MATCH --toolset-root=(.*) : $(ARGV) ] ;
+{
+    local t = [ MATCH "[ ]*(.*)" : $(toolset-root:J=" ") ] ;
+    toolset-root = ;
+    while $(t)
+    {
+        t = [ MATCH "([^ ]+)([ ]*)(.*)" : $(t) ] ;
+        toolset-root += $(t[1]) ;
+        if $(t[3]) { toolset-root += $(t[2]) ; }
+        t = $(t[3]) ;
+    }
+    toolset-root = $(toolset-root:J="") ;
+}
+
+# Configure the implemented toolsets. These are minimal
+# commands and options to compile the full Jam. When
+# adding new toolsets make sure to add them to the
+# "known" list also.
+rule toolset ( name command .type ? : opt.out + : opt.define * : flags * : linklibs * )
+{
+    .type ?= "" ;
+    tool.$(name)$(.type).cc ?= $(command) ;
+    tool.$(name)$(.type).opt.out ?= $(opt.out) ;
+    tool.$(name)$(.type).opt.define ?= $(opt.define) ;
+    tool.$(name)$(.type).flags ?= $(flags) ;
+    tool.$(name)$(.type).linklibs ?= $(linklibs) ;
+    if ! $(name) in $(toolsets) { toolsets += $(name) ; }
+}
+rule opt ( type : yes-opt * : no-opt * ) { if $(type) in $(ARGV) { return $(yes-opt) ; } else { return $(no-opt) ; } }
+## HP-UX aCC compiler
+toolset acc cc : "-o " : -D
+    : -Ae
+    [ opt --release : -s -O3 ]
+    [ opt --debug : -g -pg ] ;
+## Borland C++ 5.5.x
+toolset borland bcc32 : -e -n : /D
+    : -WC -w- -q "-I$(toolset-root)Include" "-L$(toolset-root)Lib"
+    [ opt --release : -O2 -vi -w-inl ]
+    [ opt --debug : -v -Od -vi- ] ;
+## Generic Unix cc
+if ! $(CC) { CC = cc ; }
+toolset cc $(CC) : "-o " : -D
+    : $(CFLAGS)
+    [ opt --release : -s -O ]
+    [ opt --debug : -g ]
+    : $(LIBS) ;
+## Comeau C/C++ 4.x
+toolset como como : "-o " : -D
+    : --c
+    [ opt --release : --inlining ]
+    [ opt --debug : --no_inlining ] ;
+## MacOSX Darwin, using GCC 2.9.x, 3.x
+toolset darwin cc :  "-o " : -D
+    :
+    [ opt --release : -Wl,-x -O3 -finline-functions ]
+    [ opt --debug : -g -O0 -fno-inline -pg ] ;
+## GCC 2.x, 3.x
+toolset gcc gcc : "-o " : -D
+    : -pedantic
+    [ opt --release : [ opt --symbols : -g : -s ] -O3 -finline-functions ]
+    [ opt --debug : -g -O0 -fno-inline ] ;
+## GCC 2.x, 3.x on CYGWIN but without cygwin1.dll
+toolset gcc-nocygwin gcc : "-o " : -D
+    : -s -O3 -mno-cygwin
+    [ opt --release : -finline-functions ]
+    [ opt --debug : -s -O3 -fno-inline -pg ] ;
+## Intel C/C++ for Linux
+toolset intel-linux icc : "-o " : -D
+    :
+    [ opt --release : -Xlinker -s -O3 ]
+    [ opt --debug : -g -O0 -p ] ;
+## Intel C/C++ for Win32
+toolset intel-win32 icl : /Fe : -D
+    : /nologo
+    [ opt --release : /ML /O2 /Ob2 /Gy /GF /GA /GB ]
+    [ opt --debug : /MLd /DEBUG /Z7 /Od /Ob0 ] ;
+## KCC ?
+toolset kcc KCC : "-o " : -D
+    :
+    [ opt --release : -s +K2 ]
+    [ opt --debug : -g +K0 ] ;
+## Borland Kylix
+toolset kylix bc++ : -o : -D
+    : -tC -q
+    [ opt --release : -O2 -vi -w-inl ]
+    [ opt --debug : -v -Od -vi- ] ;
+## Metrowerks CodeWarrior 8.x
+{
+    local mwcc = ; if $(NT) { mwcc = mwcc ; } else { mwcc = mwc$(OSPLAT:L) ; }
+    mwcc ?= mwcc ;
+    toolset metrowerks $(mwcc) : "-o " : -D
+        : -subsystem console -cwd include -ladvapi32.lib
+        [ opt --release : -runtime ss -opt full -inline auto -inline level=8 ]
+        [ opt --debug : -runtime ssd -O0 -inline off ] ;
+}
+## MINGW GCC
+toolset mingw gcc : "-o " : -D
+    :
+    [ opt --release : -s -O3 -finline-functions ]
+    [ opt --debug : -g -O0 -fno-inline -pg ] ;
+## MIPS Pro
+toolset mipspro cc : "-o " : -D
+    :
+    [ opt --release : -s -O3 -g0 -INLINE:none ]
+    [ opt --debug : -g -O0 -INLINE ] ;
+## Microsoft Visual Studio C++ 6.x
+toolset msvc cl : /Fe : -D
+    : /nologo
+    [ opt --release : /ML /O2 /Ob2 /Gy /GF /GA /GB ]
+    [ opt --debug : /MLd /DEBUG /Z7 /Od /Ob0 ]
+    : kernel32.lib advapi32.lib ;
+## Sun Workshop 6 C++
+toolset sunpro cc : "-o " : -D
+    :
+    [ opt --release : -s -fast -xO4 ]
+    [ opt --debug : -g ] ;
+## Compaq Alpha CXX
+toolset tru64cxx cc : "-o " : -D
+    :
+    [ opt --release : -s -O5 -inline speed ]
+    [ opt --debug : -g -O0 -pg ] ;
+## IBM VisualAge C++
+toolset vacpp xlc : "-o " : -D
+    :
+    [ opt --release : -s -O3 -qstrict -qinline ]
+    [ opt --debug : -g -qNOOPTimize -qnoinline -pg ] ;
+## Microsoft Visual C++ .NET 7.x
+toolset vc7 cl : /Fe : -D
+    : /nologo
+    [ opt --release : /ML /O2 /Ob2 /Gy /GF /GA /GB ]
+    [ opt --debug : /MLd /DEBUG /Z7 /Od /Ob0 ]
+    : kernel32.lib advapi32.lib ;
+## VMS/OpenVMS DEC C
+toolset vmsdecc cc : /OBJECT= : "/DEFINES=(" "," ")"
+    : /STANDARD=VAXC /PREFIX_LIBRARY_ENTRIES=ALL_ENTRIES
+    [ opt --release : /OPTIMIZE /NODEBUG ]
+    [ opt --debug : /NOOPTIMIZE /DEBUG ]
+    ;
+toolset vmsdecc link .link : /EXECUTABLE= :
+    : /NOMAP
+    [ opt --release : /NODEBUG ]
+    [ opt --debug : /DEBUG ]
+    ;
+
+# First set the build commands and options according to the
+# preset toolset.
+toolset = [ MATCH --toolset=(.*) : $(ARGV) ] ;
+if ! $(toolset)
+{
+    # For some reason, the following test does not catch 
+    # empty toolset.
+    ECHO "###" ;
+    ECHO "###" No toolset specified. Please use --toolset option. ;
+    ECHO "###" ;
+    ECHO "###" Known toolsets are: $(toolsets:J=", ") ;
+    EXIT "###" ;    
+}
+if ! $(toolset) in $(toolsets)
+{
+    ECHO "###" ;
+    ECHO "###" Unknown toolset: $(toolset) ;
+    ECHO "###" ;
+    ECHO "###" Known toolsets are: $(toolsets:J=", ") ;
+    EXIT "###" ;
+}
+--cc = $(tool.$(toolset).cc) ;
+if $(tool.$(toolset).opt.out[2])
+{
+    --bin = $(tool.$(toolset).opt.out[1]) ;
+    --dir = $(tool.$(toolset).opt.out[2]) ;
+}
+else
+{
+    --out = $(tool.$(toolset).opt.out) ;
+}
+--def = $(tool.$(toolset).opt.define) ;
+--flags = $(tool.$(toolset).flags) ;
+--defs = $(tool.$(toolset).defines) ;
+--libs = $(tool.$(toolset).linklibs) ;
+if $(tool.$(toolset).link.cc)
+{
+    --link = $(tool.$(toolset).link.cc) ;
+    if $(tool.$(toolset).link.opt.out[2])
+    {
+        --link-bin = $(tool.$(toolset).link.opt.out[1]) ;
+        --link-dir = $(tool.$(toolset).link.opt.out[2]) ;
+    }
+    else
+    {
+        --link-out = $(tool.$(toolset).link.opt.out) ;
+    }
+    --link-def = $(tool.$(toolset).link.opt.define) ;
+    --link-flags = $(tool.$(toolset).link.flags) ;
+    --link-defs = $(tool.$(toolset).link.defines) ;
+    --link-libs = $(tool.$(toolset).link.linklibs) ;
+}
+
+# Put executables in platform-specific subdirectory.
+locate-target = $(LOCATE_TARGET) ;
+if $(VMS)
+{
+    locate-target ?= bin$(.)vms ;
+    platform = vms ;
+}
+else if $(MAC)
+{
+    locate-target ?= bin$(.)$(OS:L)$(OSPLAT:L) ;
+    platform = $(OS:L)$(OSPLAT:L) ;
+}
+else if $(OSPLAT)
+{
+    locate-target ?= bin$(.)$(OS:L)$(OSPLAT:L) ;
+    platform = $(OS:L)$(OSPLAT:L) ;
+}
+else
+{
+    locate-target ?= bin$(.)$(OS:L) ;
+    platform = $(OS:L) ;
+}
+if $(debug)
+{
+    locate-target = [ .path $(locate-target)$(.)debug ] ;
+}
+else
+{
+    locate-target = [ .path $(locate-target) ] ;
+}
+
+# We have some different files for UNIX, VMS, and NT.
+jam.source =
+    command.c compile.c expand.c glob.c
+    hash.c hcache.c headers.c hdrmacro.c
+    jam.c jambase.c jamgram.c
+    lists.c make.c make1.c newstr.c
+    option.c parse.c regexp.c rules.c
+    scan.c search.c subst.c
+    timestamp.c variable.c modules.c strings.c filesys.c 
+    builtins.c pwd.c class.c native.c modules/set.c 
+    modules/path.c modules/regex.c modules/property-set.c
+    modules/sequence.c modules/order.c
+    ;
+if $(NT)
+{
+    jam.source += execnt.c filent.c pathunix.c w32_getreg.c ;
+}
+else if $(OS2)
+{
+    jam.source += execunix.c fileos2.c pathunix.c ;
+} 
+else if $(VMS)
+{
+    jam.source += execvms.c filevms.c pathvms.c ;
+}
+else if $(MAC)
+{
+    jam.source += execmac.c filemac.c pathmac.c ;
+}
+else
+{
+    jam.source += execunix.c fileunix.c pathunix.c ;
+}
+
+# Debug assertions, or not.
+if ! $(debug) || --noassert in $(ARGV)
+{
+    --defs += NDEBUG ;
+}
+
+# Enable some optional features.
+--defs += OPT_HEADER_CACHE_EXT ;
+--defs += OPT_GRAPH_DEBUG_EXT ;
+--defs += OPT_SEMAPHORE ;
+
+# Bug fixes
+--defs += OPT_FIX_TARGET_VARIABLES_EXT ;
+
+# Improvements
+--defs += OPT_IMPROVED_PATIENCE_EXT ;
+
+if ( $(OS) = NT || $(NT) ) && ! NT in $(--defs)
+{
+    --defs += NT ;
+}
+if $(VMS)
+{
+    --defs += VMS ;
+}
+--defs += YYSTACKSIZE=5000 ;
+
+# The basic symbolic targets...
+NOTFILE all clean dist ;
+ALWAYS clean ;
+
+# Utility rules and actions...
+rule .clean
+{
+    .rm. clean : $(<) ;
+}
+if $(NT) { actions piecemeal together existing .rm. {
+    del /F /Q $(>)
+} }
+if $(UNIX) { actions piecemeal together existing .rm. {
+    rm -f $(>)
+} }
+if $(VMS) { actions piecemeal together existing .rm. {
+    DELETE $(>[--2]:J=";*, ") $(>[-1]);*
+} }
+if $(NT) {
+    --chmod+w = "attrib -r " ;
+}
+if $(UNIX) {
+    --chmod+w = "chmod +w " ;
+}
+if $(VMS) {
+    --chmod+w = "SET FILE/PROT=(S:RWED) " ;
+}
+
+rule .mkdir
+{
+    NOUPDATE $(<) ;
+    if $(<:P) { DEPENDS $(<) : $(<:P) ; .mkdir $(<:P) ; }
+    if ! $(md<$(<)>) { .mkdir. $(<) ; md<$(<)> = - ; }
+}
+if $(NT) { actions .mkdir. {
+    md $(<)
+} }
+if $(UNIX) { actions .mkdir. {
+    mkdir $(<)
+} }
+if $(VMS) { actions .mkdir. {
+    CREATE/DIR $(<J=", ")
+} }
+
+rule .exe
+{
+    local exe = $(<) ;
+    if $(NT) || ( $(UNIX) && $(OS) = CYGWIN ) || $(VMS) { exe = $(exe:S=.exe) ; }
+    LOCATE on $(exe) = $(locate-target) ;
+    DEPENDS all : $(exe) ;
+    .mkdir $(locate-target) ;
+    if $(--link)
+    {
+        for local s in $(>)
+        {
+            local o = $(s:S=.o) ;
+            LOCATE on $(o) = $(locate-target) ;
+            DEPENDS $(exe) : $(o) ;
+            DEPENDS $(o) : $(s) ;
+            DEPENDS $(o) : $(locate-target) ;
+            .cc. $(o) : $(s) ;
+            .clean $(o) ;
+        }
+        DEPENDS $(exe) : $(>:S=.o) ;
+        DEPENDS $(exe) : $(locate-target) ;
+        .ld. $(exe) : $(>:S=.o) ;
+        .clean $(exe) ;
+    }
+    else
+    {
+        DEPENDS $(exe) : $(>) ;
+        DEPENDS $(exe) : $(locate-target) ;
+        .cc. $(exe) : $(>) ;
+        .clean $(exe) ;
+    }
+    return $(exe) ;
+}
+if ! $(--def[2]) { actions .cc. {
+    "$(--cc)" $(--bin)$(<:D=) $(--dir)$(<:D) $(--out)$(<) $(--def)$(--defs) $(--flags) "$(--libs)" $(>)
+} }
+else { actions .cc. {
+    "$(--cc)" $(--bin)$(<:D=) $(--dir)$(<:D) $(--out)$(<) $(--def[1])$(--defs:J=$(--def[2]))$(--def[3]) $(--flags) "$(--libs)" $(>)
+} }
+if $(VMS) { actions .ld. {
+    "$(--link)" $(--link-bin)$(<:D=) $(--link-dir)$(<:D) $(--link-out)$(<) $(--link-def)$(--link-defs) $(--link-flags) "$(--link-libs)" $(>J=", ")
+} }
+else { actions .ld. {
+    "$(--link)" $(--link-bin)$(<:D=) $(--link-dir)$(<:D) $(--link-out)$(<) $(--link-def)$(--link-defs) $(--link-flags) "$(--link-libs)" $(>)
+} }
+
+rule .link
+{
+    DEPENDS all : $(<) ;
+    DEPENDS $(<) : $(>) ;
+    .link. $(<) : $(>) ;
+    .clean $(<) ;
+}
+if $(NT) { actions .link. {
+    copy $(>) $(<)
+} }
+if $(UNIX) { actions .link. {
+    ln -f $(>) $(<)
+} }
+if $(VMS) { actions .link. {
+    COPY/REPLACE $(>) $(<)
+} }
+
+rule .move
+{
+    DEPENDS $(<) : $(>) ;
+    .move. $(<) : $(>) ;
+}
+if $(NT) { actions .move. {
+    del /f $(<)
+    rename $(>) $(<)
+} }
+if $(UNIX) { actions .move. {
+    mv -f $(>) $(<)
+} }
+if $(VMS) { actions .move. {
+    RENAME $(>) $(<)
+} }
+
+# Generate the grammar tokens table, and the real yacc grammar.
+rule .yyacc
+{
+    local exe = [ .exe yyacc : yyacc.c ] ;
+    NOUPDATE $(exe) ;
+    DEPENDS $(<) : $(exe) $(>) ;
+    LEAVES $(<) ;
+    yyacc.exe on $(<) = $(exe:R=$(locate-target)) ;
+    .yyacc. $(<) : $(>) ;
+}
+actions .yyacc. {
+    $(--chmod+w)$(<[1])
+    $(--chmod+w)$(<[2])
+    "$(yyacc.exe)" $(<) $(>)
+}
+if $(grammar)
+{
+    .yyacc jamgram.y jamgramtab.h : jamgram.yy ;
+}
+else
+{
+    .exe yyacc : yyacc.c ;
+}
+
+# How to build the grammar.
+if $(NT)
+{
+    SUFEXE = .exe ;
+    # try some other likely spellings...
+    PATH ?= $(Path) ;
+    PATH ?= $(path) ;
+}
+SUFEXE ?= "" ;
+
+yacc ?= [ GLOB $(PATH) : yacc$(SUFEXE) ] ;
+yacc ?= [ GLOB $(PATH) : bison$(SUFEXE) ] ;
+yacc ?= [ GLOB "$(ProgramFiles:J= )\\GnuWin32\\bin" "C:\\Program Files\\GnuWin32\\bin" : bison$(SUFEXE) ] ;
+yacc = $(yacc[1]) ;
+switch $(yacc:D=:S=)
+{
+    case bison : yacc += -d --yacc ;
+    case yacc  : yacc += -d ;
+}
+if $(debug) && $(yacc)
+{
+    yacc += -t -v ;
+}
+yacc += $(YACCFLAGS) ;
+
+rule .yacc
+{
+    DEPENDS $(<) : $(>) ;
+    LEAVES $(<) ;
+    .yacc. $(<) : $(>) ;
+}
+if $(NT) { actions .yacc. {
+    "$(yacc)" $(>)
+    if not errorlevel 1 (
+        del /f $(<[1])
+        rename y.tab$(<[1]:S) $(<[1])
+        del /f $(<[2])
+        rename y.tab$(<[2]:S) $(<[2])
+    ) else set _error_ =
+} }
+if $(UNIX) { actions .yacc. {
+    if ` "$(yacc)" $(>) ` ; then
+        mv -f y.tab$(<[1]:S) $(<[1])
+        mv -f y.tab$(<[2]:S) $(<[2])
+    else
+        exit 1
+    fi
+} }
+if $(VMS) { actions .yacc. {
+    IF "$(yacc)" $(>)
+    THEN
+        RENAME y_tab$(<[1]:S) $(<[1])
+        RENAME y_tab$(<[2]:S) $(<[2])
+    ENDIF
+} }
+if $(grammar) && ! $(yacc)
+{
+    EXIT "Could not find the 'yacc' tool, and therefore can not build the grammar." ;
+}
+if $(grammar) && $(yacc)
+{
+    .yacc jamgram.c jamgram.h : jamgram.y ;
+}
+
+# How to build the compiled in jambase.
+rule .mkjambase
+{
+    local exe = [ .exe mkjambase : mkjambase.c ] ;
+    DEPENDS $(<) : $(exe) $(>) ;
+    LEAVES $(<) ;
+    mkjambase.exe on $(<) = $(exe:R=$(locate-target)) ;
+    .mkjambase. $(<) : $(>) ;
+}
+actions .mkjambase. {
+    $(--chmod+w)$(<)
+    $(mkjambase.exe) $(<) $(>)
+}
+.mkjambase jambase.c : Jambase ;
+
+# How to build Jam.
+rule .jam
+{
+    $(>).exe = [ .exe $(>) : $(jam.source) ] ;
+    $(<).exe = $(<:S=$($(>).exe:S)) ;
+    LOCATE on $($(<).exe) = $(locate-target) ;
+    .link $($(<).exe) : $($(>).exe) ;
+    
+    DEPENDS all : $($(>).exe) $($(<).exe) ;
+}
+.jam bjam : jam ;
+
+# Scan sources for header dependencies.
+rule .scan
+{
+    HDRRULE on $(<:D=) = .hdr.scan ;
+    HDRSCAN on $(<:D=) = "^[     ]*#[    ]*include[  ]*[<\"]([^\">]*)[\">].*$" ;
+}
+rule .hdr.scan
+{
+    local hdrs = [ GLOB . : $(>:D=) ] ;
+    INCLUDES $(<:D=) : $(hdrs:D=) ;
+    HDRRULE on $(>:D=) = .hdr.scan ;
+    HDRSCAN on $(>:D=) = "^[     ]*#[    ]*include[  ]*[<\"]([^\">]*)[\">].*$" ;
+}
+.scan [ GLOB . : *.c ] ;
+
+# Distribution making from here on out.
+dist.license =
+    #~ [ GLOB . : LICENSE_$(LICENSE).txt ] [ GLOB [ .path .. .. .. ] : LICENSE_$(LICENSE).txt ] ;
+    [ GLOB . : LICENSE_$(LICENSE).txt ]
+    [ GLOB [ .path .. .. .. ] : LICENSE_$(LICENSE).txt ]
+    [ GLOB [ .path .. boost ] : LICENSE_$(LICENSE).txt ] ;
+dist.docs =
+    $(dist.license[1])
+    index.html
+    Porting
+    Jam.html
+    ;
+dist.source =
+    [ GLOB . : *.c *.h ]
+    ;
+dist.source = $(dist.source:D=)
+    $(dist.docs)
+    build.jam build.bat build.sh build_vms.com
+    Jambase
+    jamgram.y jamgram.yy
+    [ .path debian changelog ]
+    [ .path debian control ]
+    [ .path debian copyright ]
+    [ .path debian jam.man.sgml ]
+    [ .path debian rules ]
+    [ .path modules set.c ]
+    [ .path modules path.c ]
+    [ .path modules regex.c ]
+    [ .path modules property-set.c ]
+    [ .path modules sequence.c ]
+    [ .path modules order.c ]
+    boost-jam.spec
+    ;
+dist.bin =
+    bjam
+    ;
+dist.bin =
+    $(dist.license[1])
+    $(dist.bin:S=$(bjam.exe:S))
+    ;
+
+if $(NT)
+{
+    zip ?= [ GLOB "$(ProgramFiles:J= )\\7-ZIP" "C:\\Program Files\\7-ZIP" : "7zn.exe" ] ;
+    zip ?= [ GLOB $(PATH) : zip.exe ] ;
+    zip ?= zip ;
+    zip = $(zip[1]) ;
+    switch $(zip:D=:S=)
+    {
+        case 7zn : zip += a -r -tzip ;
+        case zip  : zip += -9r ;
+    }
+    actions piecemeal .pack. {
+    "$(zip)" "$(<)" "$(>)"
+    }
+    actions piecemeal .zip. {
+    "$(zip)" "$(<)" "$(>)"
+    }
+    actions piecemeal .cp. {
+    copy /Y "$(>)" "$(<)"
+    }
+}
+if $(UNIX)
+{
+    actions .pack. {
+    tar zcf "$(<)" "$(>)"
+    }
+    actions .zip. {
+    gzip -c9 "$(>)" > "$(<)"
+    }
+    actions .cp. {
+    cp -Rpf "$(>)" "$(<)"
+    }
+}
+
+# The single binary, compressed.
+rule .binary
+{
+    local zip = ;
+    if $(NT) { zip = $($(<).exe:S=.zip) ; }
+    if $(UNIX) { zip = $($(<).exe:S=.tgz) ; }
+    zip = $(zip:S=)-$(VERSION)-$(RELEASE)-$(platform)$(zip:S) ;
+    DEPENDS $(zip) : $($(<).exe) ;
+    DEPENDS dist : $(zip) ;
+    #~ LOCATE on $(zip) = $(locate-target) ;
+    if $(NT) { .zip. $(zip) : $($(<).exe) ; }
+    if $(UNIX) { .pack. $(zip) : $($(<).exe) ; }
+    .clean $(zip) ;
+}
+
+# Package some file.
+rule .package ( dst-dir : src-files + )
+{
+    local dst-files ;
+    for local src-path in $(src-files)
+    {
+        local src-subdir = $(src-path:D) ;
+        local src-file = $(src-path) ;
+        while $(src-subdir:D) { src-subdir = $(src-subdir:D) ; }
+        if $(src-subdir) = ".."
+        {
+            src-file = $(src-file:D=) ;
+        }
+        dst-files += $(src-file:R=$(dst-dir)) ;
+    }
+    
+    local pack = ;
+    if $(NT) { pack = $(dst-dir).zip ; }
+    if $(UNIX) { pack = $(dst-dir).tgz ; }
+    
+    DEPENDS dist : $(pack) ;
+    DEPENDS $(pack) : $(dst-files) ;
+    
+    local dst-files-queue = $(dst-files) ;
+    for local src-path in $(src-files)
+    {
+        local dst-file = $(dst-files-queue[1]) ;
+        dst-files-queue = $(dst-files-queue[2-]) ;
+        DEPENDS $(dst-file) : $(src-path) $(dst-file:D) ;
+        .mkdir $(dst-file:D) ;
+        
+        .cp. $(dst-file) : $(src-path) ;
+        .clean $(dst-file) ;
+    }
+    
+    .pack. $(pack) : $(dst-files) ;
+    .clean $(pack) ;
+}
+
+# RPM distro file.
+rpm-tool = [ GLOB $(PATH) : "rpmbuild" "rpm" ] ;
+rule .rpm ( name : source )
+{
+    local rpm-arch = ;
+    switch $(OSPLAT)
+    {
+        case X86       : rpm-arch ?= i386 ;
+        case PPC       : rpm-arch ?= ppc ;
+        case AXP       : rpm-arch ?= alpha ;
+        # no guaranty for these:
+        case IA64      : rpm-arch ?= ia64 ;
+        case ARM       : rpm-arch ?= arm ;
+        case SPARC     : rpm-arch ?= sparc ;
+        case *         : rpm-arch ?= other ;
+    }
+    local target = $(name)-rpm ;
+    NOTFILE $(target) ;
+    DEPENDS dist : $(target) ;
+    DEPENDS $(target) : $(name).$(rpm-arch).rpm $(name).src.rpm ;
+    DEPENDS $(name).$(rpm-arch).rpm : $(source) ;
+    DEPENDS $(name).src.rpm : $(name).$(rpm-arch).rpm ;
+    docs on $(target) = $(dist.docs:J=" ") ;
+    arch on $(target) = $(rpm-arch) ;
+    if $(rpm-arch) = ppc { target-opt on $(target) = --target= ; }
+    else { target-opt on $(target) = "--target " ; }
+    .rpm. $(target) : $(source) ;
+    .clean $(name).$(rpm-arch).rpm $(name).src.rpm ;
+}
+actions .rpm. {
+    export BOOST_JAM_TOOLSET="$(toolset)"
+    $(rpm-tool[1]) -ta $(target-opt)$(arch) $(>) | tee rpm.out
+    cp `grep -e '^Wrote:' rpm.out | sed 's/^Wrote: //'` .
+    rm -f rpm.out
+}
+
+# The distribution targets. Don't bother with the targets if
+# distribution build not requested.
+if dist in $(ARGV)
+{
+    #~ .binary bjam ;
+    .package $(NAME)-$(VERSION) : $(dist.source) ;
+    .package $(NAME)-$(VERSION)-$(RELEASE)-$(platform) : $(dist.bin) ;
+    if $(rpm-tool)
+    {
+        .rpm $(NAME)-$(VERSION)-$(RELEASE) : $(NAME)-$(VERSION).tgz ;
+    }
+}

Added: boost-jam/boost-build/branches/upstream/current/jam_src/build.sh
===================================================================
--- boost-jam/boost-build/branches/upstream/current/jam_src/build.sh	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/jam_src/build.sh	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,225 @@
+#!/bin/sh
+
+#~ Copyright 2002-2003 Rene Rivera.
+#~ Distributed under the Boost Software License, Version 1.0.
+#~ (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+
+# Reset the toolset.
+BOOST_JAM_TOOLSET=
+
+# Run a command, and echo before doing so. Also checks the exit
+# status and quits if there was an error.
+echo_run ()
+{
+    echo "$@"
+    "$@"
+    r=$?
+    if test $r -ne 0 ; then
+        exit $r
+    fi
+}
+
+# Print an error message, and exit with a status of 1.
+error_exit ()
+{
+    echo "###"
+    echo "###" "$@"
+    echo "###"
+    echo "### You can specify the toolset as the argument, i.e.:"
+    echo "###     ./build.sh gcc"
+    echo "###"
+    echo "### Toolsets supported by this script are:"
+    echo "###     acc, como, darwin, gcc, intel-linux, kcc, kylix, mipspro,"
+    echo "###     sunpro, tru64cxx, vacpp"
+    echo "###"
+    echo "### A special toolset; cc, is available which is used as a fallback"
+    echo "### when a more specific toolset is not found and the cc command is"
+    echo "### detected. The 'cc' toolset will use the CC, CFLAGS, and LIBS"
+    echo "### envrironment variables, if present."
+    echo "###"
+    exit 1
+}
+
+# Check that a command is in the PATH.
+test_path ()
+{
+    if `whence 1>/dev/null 2>/dev/null`; then
+        whence $1 1>/dev/null 2>/dev/null
+    else
+        hash $1 1>/dev/null 2>/dev/null
+    fi
+}
+
+# Check that the OS name, as returned by "uname", is as given.
+test_uname ()
+{
+    if test_path uname; then
+        test `uname` = $*
+    fi
+}
+
+# Try and guess the toolset to bootstrap the build with...
+Guess_Toolset ()
+{
+    if test_uname Darwin ; then BOOST_JAM_TOOLSET=darwin
+    elif test_uname IRIX ; then BOOST_JAM_TOOLSET=mipspro
+    elif test_uname IRIX64 ; then BOOST_JAM_TOOLSET=mipspro
+    elif test_path gcc ; then BOOST_JAM_TOOLSET=gcc
+    elif test_path icc ; then BOOST_JAM_TOOLSET=intel-linux
+    elif test -r /opt/intel/compiler70/ia32/bin/iccvars.sh ; then
+        BOOST_JAM_TOOLSET=intel-linux
+        BOOST_JAM_TOOLSET_ROOT=/opt/intel/compiler70/ia32/
+    elif test -r /opt/intel/compiler60/ia32/bin/iccvars.sh ; then
+        BOOST_JAM_TOOLSET=intel-linux
+        BOOST_JAM_TOOLSET_ROOT=/opt/intel/compiler60/ia32/
+    elif test -r /opt/intel/compiler50/ia32/bin/iccvars.sh ; then
+        BOOST_JAM_TOOLSET=intel-linux
+        BOOST_JAM_TOOLSET_ROOT=/opt/intel/compiler50/ia32/
+    elif test_path xlc ; then BOOST_JAM_TOOLSET=vacpp
+    elif test_path como ; then BOOST_JAM_TOOLSET=como
+    elif test_path KCC ; then BOOST_JAM_TOOLSET=kcc
+    elif test_path bc++ ; then BOOST_JAM_TOOLSET=kylix
+    elif test_path aCC ; then BOOST_JAM_TOOLSET=acc
+    elif test_uname HP-UX ; then BOOST_JAM_TOOLSET=acc
+    elif test -r /opt/SUNWspro/bin/cc ; then
+        BOOST_JAM_TOOLSET=sunpro
+        BOOST_JAM_TOOLSET_ROOT=/opt/SUNWspro/
+    # Test for "cc" as the default fallback.
+    elif test_path $CC ; then BOOST_JAM_TOOLSET=cc
+    elif test_path cc ; then
+        BOOST_JAM_TOOLSET=cc
+        CC=cc
+    fi
+    if test "$BOOST_JAM_TOOLSET" = "" ; then
+        error_exit "Could not find a suitable toolset."
+    fi
+}
+
+# The one option we support in the invocation
+# is the name of the toolset to force building
+# with.
+case "$1" in
+    -*) Guess_Toolset ;;
+    ?*) BOOST_JAM_TOOLSET=$1 ; shift ;;
+    *) Guess_Toolset ;;
+esac
+BOOST_JAM_OPT_JAM="-o bootstrap.$BOOST_JAM_TOOLSET/jam0"
+BOOST_JAM_OPT_MKJAMBASE="-o bootstrap.$BOOST_JAM_TOOLSET/mkjambase0"
+BOOST_JAM_OPT_YYACC="-o bootstrap.$BOOST_JAM_TOOLSET/yyacc0"
+case $BOOST_JAM_TOOLSET in
+    gcc)
+    BOOST_JAM_CC=gcc
+    ;;
+    
+    darwin)
+    BOOST_JAM_CC=cc
+    ;;
+    
+    intel-linux)
+    if test -r /opt/intel/compiler70/ia32/bin/iccvars.sh ; then
+        BOOST_JAM_TOOLSET_ROOT=/opt/intel/compiler70/ia32/
+    elif test -r /opt/intel/compiler60/ia32/bin/iccvars.sh ; then
+        BOOST_JAM_TOOLSET_ROOT=/opt/intel/compiler60/ia32/
+    elif test -r /opt/intel/compiler50/ia32/bin/iccvars.sh ; then
+        BOOST_JAM_TOOLSET_ROOT=/opt/intel/compiler50/ia32/
+    fi
+    if test -r ${BOOST_JAM_TOOLSET_ROOT}bin/iccvars.sh ; then
+        . ${BOOST_JAM_TOOLSET_ROOT}bin/iccvars.sh
+    fi
+    BOOST_JAM_CC=icc
+    ;;
+    
+    vacpp)
+    BOOST_JAM_CC=xlc
+    ;;
+    
+    como)
+    BOOST_JAM_CC="como --c"
+    ;;
+    
+    kcc)
+    BOOST_JAM_CC=KCC
+    ;;
+    
+    kylix)
+    BOOST_JAM_CC=bc++
+    ;;
+    
+    mipspro)
+    BOOST_JAM_CC=cc
+    ;;
+    
+    sunpro)
+    if test -r /opt/SUNWspro/bin/cc ; then
+        BOOST_JAM_TOOLSET_ROOT=/opt/SUNWspro/
+    fi
+    if test -r $BOOST_JAM_TOOLSET_ROOTbin/cc ; then
+        export PATH=$BOOST_JAM_TOOLSET_ROOTbin:$PATH
+    fi
+    BOOST_JAM_CC=cc
+    ;;
+    
+    tru64cxx)
+    BOOST_JAM_CC=cc
+    ;;
+    
+    acc)
+    BOOST_JAM_CC="cc -Ae"
+    ;;
+    
+    cc)
+    if test -z "$CC" ; then CC=cc ; fi
+    BOOST_JAM_CC=$CC
+    BOOST_JAM_OPT_JAM="$BOOST_JAM_OPT_JAM $CFLAGS $LIBS"
+    BOOST_JAM_OPT_MKJAMBASE="$BOOST_JAM_OPT_MKJAMBASE $CFLAGS $LIBS"
+    BOOST_JAM_OPT_YYACC="$BOOST_JAM_OPT_YYACC $CFLAGS $LIBS"
+    ;;
+   
+    *)
+    error_exit "Unknown toolset: $BOOST_JAM_TOOLSET"
+    ;;
+esac
+
+echo "###"
+echo "### Using '$BOOST_JAM_TOOLSET' toolset."
+echo "###"
+
+YYACC_SOURCES="yyacc.c"
+MKJAMBASE_SOURCES="mkjambase.c"
+BJAM_SOURCES="\
+ command.c compile.c execnt.c execunix.c execvms.c expand.c\
+ filent.c fileos2.c fileunix.c filevms.c glob.c hash.c\
+ hdrmacro.c headers.c jam.c jambase.c jamgram.c lists.c make.c make1.c\
+ newstr.c option.c parse.c pathunix.c pathvms.c regexp.c\
+ rules.c scan.c search.c subst.c timestamp.c variable.c modules.c\
+ strings.c filesys.c builtins.c pwd.c class.c native.c modules/set.c\
+ modules/path.c modules/regex.c modules/property-set.c\
+ modules/sequence.c modules/order.c"
+
+echo_run rm -rf bootstrap.$BOOST_JAM_TOOLSET
+echo_run mkdir bootstrap.$BOOST_JAM_TOOLSET
+if test ! -r jamgram.y -o ! -r jamgramtab.h ; then
+    echo_run ${BOOST_JAM_CC} ${BOOST_JAM_OPT_YYACC} ${YYACC_SOURCES}
+    if test -x "./bootstrap.$BOOST_JAM_TOOLSET/yyacc0" ; then
+        echo_run ./bootstrap.$BOOST_JAM_TOOLSET/yyacc0 jamgram.y jamgramtab.h jamgram.yy
+    fi
+fi
+if test ! -r jamgram.c -o ! -r jamgram.h ; then
+    if test_path yacc ; then YACC="yacc -d"
+    elif test_path bison ; then YACC="bison -y -d --yacc"
+    fi
+    echo_run $YACC jamgram.y
+    mv -f y.tab.c jamgram.c
+    mv -f y.tab.h jamgram.h
+fi
+if test ! -r jambase.c ; then
+    echo_run ${BOOST_JAM_CC} ${BOOST_JAM_OPT_MKJAMBASE} ${MKJAMBASE_SOURCES}
+    if test -x "./bootstrap.$BOOST_JAM_TOOLSET/mkjambase0" ; then
+        echo_run ./bootstrap.$BOOST_JAM_TOOLSET/mkjambase0 jambase.c Jambase
+    fi
+fi
+echo_run ${BOOST_JAM_CC} ${BOOST_JAM_OPT_JAM} ${BJAM_SOURCES}
+if test -x "./bootstrap.$BOOST_JAM_TOOLSET/jam0" ; then
+    echo_run ./bootstrap.$BOOST_JAM_TOOLSET/jam0 -f build.jam --toolset=$BOOST_JAM_TOOLSET "--toolset-root=$BOOST_JAM_TOOLSET_ROOT" clean
+    echo_run ./bootstrap.$BOOST_JAM_TOOLSET/jam0 -f build.jam --toolset=$BOOST_JAM_TOOLSET "--toolset-root=$BOOST_JAM_TOOLSET_ROOT" "$@"
+fi


Property changes on: boost-jam/boost-build/branches/upstream/current/jam_src/build.sh
___________________________________________________________________
Name: svn:executable
   + 

Added: boost-jam/boost-build/branches/upstream/current/jam_src/build_vms.com
===================================================================
--- boost-jam/boost-build/branches/upstream/current/jam_src/build_vms.com	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/jam_src/build_vms.com	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,105 @@
+$ ! Copyright 2002-2003 Rene Rivera, Johan Nilsson.
+$ ! Distributed under the Boost Software License, Version 1.0.
+$ ! (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+$ ! 
+$ ! bootstrap build script for Jam
+$ ! 
+$ SAY :== WRITE SYS$OUTPUT
+$ ! 
+$ ON WARNING THEN CONTINUE
+$ ! 
+$ IF "" .NES. F$SEARCH("[.bootstrap_vms]*.*")
+$ THEN
+$   SAY "Cleaning previous boostrap files..."
+$ ! 
+$   SET FILE/PROTECTION=(S:RWED) [.bootstrap_vms]*.*;*
+$   DELETE [.bootstrap_vms]*.*;*
+$ ENDIF
+$ ! 
+$ IF "" .NES. F$SEARCH("bootstrap_vms.dir")
+$ THEN
+$   SAY "Removing previous boostrap directory..."
+$ ! 
+$   SET FILE/PROT=(S:RWED) bootstrap_vms.dir
+$   DELETE bootstrap_vms.dir;
+$ ENDIF
+$ ! 
+$ SAY "Creating boostrap directory..."
+$ ! 
+$ CREATE/DIR [.bootstrap_vms]
+$ ! 
+$ SAY "Building bootstrap jam..."
+$ ! 
+$ CC_FLAGS = "/DEFINE=VMS /STANDARD=VAXC /PREFIX_LIBRARY_ENTRIES=ALL_ENTRIES "
+$ cc 'CC_FLAGS /OBJECT=[.bootstrap_vms]builtins.obj builtins.c
+$ cc 'CC_FLAGS /OBJECT=[.bootstrap_vms]command.obj command.c
+$ cc 'CC_FLAGS /OBJECT=[.bootstrap_vms]compile.obj compile.c
+$ cc 'CC_FLAGS /OBJECT=[.bootstrap_vms]execvms.obj execvms.c
+$ cc 'CC_FLAGS /OBJECT=[.bootstrap_vms]expand.obj expand.c
+$ cc 'CC_FLAGS /OBJECT=[.bootstrap_vms]filesys.obj filesys.c
+$ cc 'CC_FLAGS /OBJECT=[.bootstrap_vms]filevms.obj filevms.c
+$ cc 'CC_FLAGS /OBJECT=[.bootstrap_vms]glob.obj glob.c
+$ cc 'CC_FLAGS /OBJECT=[.bootstrap_vms]hash.obj hash.c
+$ cc 'CC_FLAGS /OBJECT=[.bootstrap_vms]hdrmacro.obj hdrmacro.c
+$ cc 'CC_FLAGS /OBJECT=[.bootstrap_vms]headers.obj headers.c
+$ cc 'CC_FLAGS /OBJECT=[.bootstrap_vms]jam.obj jam.c
+$ cc 'CC_FLAGS /OBJECT=[.bootstrap_vms]jambase.obj jambase.c
+$ cc 'CC_FLAGS /OBJECT=[.bootstrap_vms]jamgram.obj jamgram.c
+$ cc 'CC_FLAGS /OBJECT=[.bootstrap_vms]lists.obj lists.c
+$ cc 'CC_FLAGS /OBJECT=[.bootstrap_vms]make.obj make.c
+$ cc 'CC_FLAGS /OBJECT=[.bootstrap_vms]make1.obj make1.c
+$ cc 'CC_FLAGS /OBJECT=[.bootstrap_vms]modules.obj modules.c
+$ cc 'CC_FLAGS /OBJECT=[.bootstrap_vms]newstr.obj newstr.c
+$ cc 'CC_FLAGS /OBJECT=[.bootstrap_vms]option.obj option.c
+$ cc 'CC_FLAGS /OBJECT=[.bootstrap_vms]parse.obj parse.c
+$ cc 'CC_FLAGS /OBJECT=[.bootstrap_vms]pathvms.obj pathvms.c
+$ cc 'CC_FLAGS /OBJECT=[.bootstrap_vms]pwd.obj pwd.c
+$ cc 'CC_FLAGS /OBJECT=[.bootstrap_vms]regexp.obj regexp.c
+$ cc 'CC_FLAGS /OBJECT=[.bootstrap_vms]rules.obj rules.c
+$ cc 'CC_FLAGS /OBJECT=[.bootstrap_vms]scan.obj scan.c
+$ cc 'CC_FLAGS /OBJECT=[.bootstrap_vms]search.obj search.c
+$ cc 'CC_FLAGS /OBJECT=[.bootstrap_vms]strings.obj strings.c
+$ cc 'CC_FLAGS /OBJECT=[.bootstrap_vms]subst.obj subst.c
+$ cc 'CC_FLAGS /OBJECT=[.bootstrap_vms]timestamp.obj timestamp.c
+$ cc 'CC_FLAGS /OBJECT=[.bootstrap_vms]variable.obj variable.c
+$ link -
+ /EXECUTABLE=[.bootstrap_vms]jam0.exe -
+ [.bootstrap_vms]builtins.obj, -
+ [.bootstrap_vms]command.obj, -
+ [.bootstrap_vms]compile.obj, -
+ [.bootstrap_vms]execvms.obj, -
+ [.bootstrap_vms]expand.obj, -
+ [.bootstrap_vms]filesys.obj, -
+ [.bootstrap_vms]filevms.obj, -
+ [.bootstrap_vms]glob.obj, -
+ [.bootstrap_vms]hash.obj, -
+ [.bootstrap_vms]hdrmacro.obj, -
+ [.bootstrap_vms]headers.obj, -
+ [.bootstrap_vms]jam.obj, -
+ [.bootstrap_vms]jambase.obj, -
+ [.bootstrap_vms]jamgram.obj, -
+ [.bootstrap_vms]lists.obj, -
+ [.bootstrap_vms]make.obj, -
+ [.bootstrap_vms]make1.obj, -
+ [.bootstrap_vms]modules.obj, -
+ [.bootstrap_vms]newstr.obj, -
+ [.bootstrap_vms]option.obj, -
+ [.bootstrap_vms]parse.obj, -
+ [.bootstrap_vms]pathvms.obj, -
+ [.bootstrap_vms]pwd.obj, -
+ [.bootstrap_vms]regexp.obj, -
+ [.bootstrap_vms]rules.obj, -
+ [.bootstrap_vms]scan.obj, -
+ [.bootstrap_vms]search.obj, -
+ [.bootstrap_vms]strings.obj, -
+ [.bootstrap_vms]subst.obj, -
+ [.bootstrap_vms]timestamp.obj, -
+ [.bootstrap_vms]variable.obj
+$ ! 
+$ SAY "Cleaning any previous build..."
+$ ! 
+$ MCR [.bootstrap_vms]jam0.exe -f build.jam --toolset=vmsdecc clean
+$ ! 
+$ SAY "Building Boost.Jam..."
+$ ! 
+$ MCR [.bootstrap_vms]jam0.exe -f build.jam --toolset=vmsdecc

Added: boost-jam/boost-build/branches/upstream/current/jam_src/builtins.c
===================================================================
--- boost-jam/boost-build/branches/upstream/current/jam_src/builtins.c	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/jam_src/builtins.c	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,1144 @@
+/*
+ * Copyright 1993-2002 Christopher Seiwald and Perforce Software, Inc.
+ *
+ * This file is part of Jam - see jam.c for Copyright information.
+ */
+
+# include "jam.h"
+
+# include "lists.h"
+# include "parse.h"
+# include "builtins.h"
+# include "rules.h"
+# include "filesys.h"
+# include "newstr.h"
+# include "regexp.h"
+# include "frames.h"
+# include "hash.h"
+# include "strings.h"
+# include "pwd.h"
+# include "pathsys.h"
+# include "make.h"
+# include "hdrmacro.h"
+# include "compile.h"
+# include "native.h"
+# include <ctype.h>
+
+/*
+ * builtins.c - builtin jam rules
+ *
+ * External routines:
+ *
+ * 	load_builtin() - define builtin rules
+ *
+ * Internal routines:
+ *
+ *	builtin_depends() - DEPENDS/INCLUDES rule
+ *	builtin_echo() - ECHO rule
+ *	builtin_exit() - EXIT rule
+ *	builtin_flags() - NOCARE, NOTFILE, TEMPORARY rule
+ *	builtin_glob() - GLOB rule
+ *	builtin_match() - MATCH rule
+ *
+ * 01/10/01 (seiwald) - split from compile.c
+ */
+
+/*
+ * compile_builtin() - define builtin rules
+ */
+
+# define P0 (PARSE *)0
+# define C0 (char *)0
+
+# ifdef OS_NT
+LIST* builtin_system_registry( PARSE *parse, FRAME *frame );
+# endif
+
+int glob( char *s, char *c );
+
+void lol_build( LOL* lol, char** elements );
+void backtrace( FRAME *frame );
+void backtrace_line( FRAME *frame );
+void print_source_line( PARSE* p );
+
+RULE* bind_builtin( char* name, LIST*(*f)(PARSE*, FRAME*), int flags, char** args )
+{
+    argument_list* arg_list = 0;
+    
+    if ( args )
+    {
+        arg_list = args_new();
+        lol_build( arg_list->data, args );
+    }
+
+    return new_rule_body( root_module(), name, arg_list,
+                          parse_make( f, P0, P0, P0, C0, C0, flags ), 1 );
+}
+
+RULE* duplicate_rule( char* name, RULE* other )
+{
+    return import_rule( other, root_module(), name );
+}
+
+void
+load_builtins()
+{
+    duplicate_rule( "Always" ,
+      bind_builtin( "ALWAYS" ,
+                    builtin_flags, T_FLAG_TOUCHED, 0 ) );
+
+    duplicate_rule( "Depends" ,
+      bind_builtin( "DEPENDS" ,
+                    builtin_depends, 0, 0 ) );
+
+    duplicate_rule( "echo" ,
+    duplicate_rule( "Echo" ,
+      bind_builtin( "ECHO" ,
+                    builtin_echo, 0, 0 ) ) );
+
+    duplicate_rule( "exit" ,
+    duplicate_rule( "Exit" ,
+      bind_builtin( "EXIT" ,
+                    builtin_exit, 0, 0 ) ) );
+
+    {
+        char * args[] = { "directories", "*", ":", "patterns", "*", ":", "case-insensitive", "?", 0 };
+        duplicate_rule(
+            "Glob" ,
+            bind_builtin( "GLOB" , builtin_glob, 0, args )
+            );
+    }
+
+    duplicate_rule( "Includes" ,
+      bind_builtin( "INCLUDES" ,
+                    builtin_depends, 1, 0 ) );
+
+    duplicate_rule( "Leaves" ,
+      bind_builtin( "LEAVES" ,
+                    builtin_flags, T_FLAG_LEAVES, 0 ) );
+
+    duplicate_rule( "Match" ,
+      bind_builtin( "MATCH" ,
+                    builtin_match, 0, 0 ) );
+
+    duplicate_rule( "NoCare" ,
+      bind_builtin( "NOCARE" ,
+                    builtin_flags, T_FLAG_NOCARE, 0 ) );
+
+    duplicate_rule( "NOTIME" ,
+    duplicate_rule( "NotFile" ,
+      bind_builtin( "NOTFILE" ,
+                    builtin_flags, T_FLAG_NOTFILE, 0 ) ) );
+
+    duplicate_rule( "NoUpdate" ,
+      bind_builtin( "NOUPDATE" ,
+                    builtin_flags, T_FLAG_NOUPDATE, 0 ) );
+
+    duplicate_rule( "Temporary" ,
+      bind_builtin( "TEMPORARY" ,
+                    builtin_flags, T_FLAG_TEMP, 0 ) );
+
+    duplicate_rule( "HdrMacro" ,
+      bind_builtin( "HDRMACRO" ,
+                    builtin_hdrmacro, 0, 0 ) );
+
+    /* FAIL_EXPECTED is used to indicate that the result of a target build */
+    /* action should be inverted (ok <=> fail) this can be useful when     */
+    /* performing test runs from Jamfiles..                                */
+      bind_builtin( "FAIL_EXPECTED" ,
+                    builtin_flags, T_FLAG_FAIL_EXPECTED, 0 );
+
+      bind_builtin( "RMOLD" , builtin_flags, T_FLAG_RMOLD, 0 );
+      
+      {
+          char * args[] = { "targets", "*", 0 };
+          bind_builtin( "UPDATE", builtin_update, 0, args );
+      }
+
+      {
+          char * args[] = { "string", "pattern", "replacements", "+", 0 };
+          duplicate_rule( "subst" ,
+            bind_builtin( "SUBST" ,
+                          builtin_subst, 0, args ) );
+      }
+
+      {
+          char * args[] = { "module", "?", 0 };
+          bind_builtin( "RULENAMES" ,
+                         builtin_rulenames, 0, args );
+      }
+
+
+      {
+          char * args[] = { "module", "?", 0 };
+          bind_builtin( "VARNAMES" ,
+                         builtin_varnames, 0, args );
+      }
+
+      {
+          char * args[] = { "module", "?", 0 };
+          bind_builtin( "DELETE_MODULE" ,
+                         builtin_delete_module, 0, args );
+      }
+
+      {
+           char * args[] = { "source_module", "?",
+                             ":", "source_rules", "*",
+                             ":", "target_module", "?",
+                             ":", "target_rules", "*",
+                             ":", "localize", "?", 0 };
+           bind_builtin( "IMPORT" ,
+                         builtin_import, 0, args );
+      }
+
+      {
+          char * args[] = { "module", "?", ":", "rules", "*", 0 };
+          bind_builtin( "EXPORT" ,
+                        builtin_export, 0, args );
+      }
+
+      {
+          char * args[] = { "levels", "?", 0 };
+          bind_builtin( "CALLER_MODULE" ,
+                         builtin_caller_module, 0, args );
+      }
+
+      {
+          char * args[] = { "levels", "?", 0 };
+          bind_builtin( "BACKTRACE" ,
+                        builtin_backtrace, 0, args );
+      }
+
+      {
+          char * args[] = { 0 };
+          bind_builtin( "PWD" ,
+                        builtin_pwd, 0, args );
+      }
+
+      {
+          char * args[] = { "target", "*", ":", "path", "*", 0 };
+          bind_builtin( "SEARCH_FOR_TARGET",
+                        builtin_search_for_target, 0, args );
+      }
+
+      {
+          char * args[] = { "modules_to_import", "+", ":", "target_module", "?", 0 };
+          bind_builtin( "IMPORT_MODULE",
+                        builtin_import_module, 0, args );
+      }
+
+      {
+          char * args[] = { "module", "?", 0 };
+          bind_builtin( "IMPORTED_MODULES",
+                        builtin_imported_modules, 0, args );
+      }
+
+      {
+          char * args[] = { "instance_module", ":", "class_module", 0 };
+          bind_builtin( "INSTANCE",
+                        builtin_instance, 0, args );
+      }
+
+      {
+          char * args[] = { "sequence", "*", 0 };
+          bind_builtin( "SORT",
+                        builtin_sort, 0, args );
+      }
+
+      {
+          char * args[] = { "path", 0 };
+          bind_builtin( "NORMALIZE_PATH",
+              builtin_normalize_path, 0, args );
+      }
+
+      {
+          char * args[] = { "args", "*", 0 };
+          bind_builtin( "CALC",
+              builtin_calc, 0, args );
+      }
+
+      {
+          char * args[] = { "module", ":", "rule", 0 };
+          bind_builtin( "NATIVE_RULE",
+              builtin_native_rule, 0, args );
+      }
+
+# ifdef OS_NT
+      {
+          char * args[] = { "key_path", ":", "data", "?", 0 };
+          bind_builtin( "W32_GETREG",
+              builtin_system_registry, 0, args );
+      }
+# endif
+
+      /* Initialize builtin modules */
+      init_set();
+      init_path();
+      init_regex();
+      init_property_set();
+      init_sequence();
+      init_order();
+}
+
+/*
+* builtin_calc() - CALC rule
+*
+* The CALC rule performs simple mathematical operations on two arguments.
+*/
+
+LIST *
+builtin_calc(
+    PARSE *parse,
+    FRAME *frame )
+{
+    LIST *arg = lol_get( frame->args, 0 );
+
+    LIST *result = 0;
+    long lhs_value;
+    long rhs_value;
+    long result_value;
+    char buffer [16];
+    const char* lhs;
+    const char* op;
+    const char* rhs;
+
+    if (arg == 0) return L0;
+    lhs = arg->string;
+
+    arg = list_next( arg );
+    if (arg == 0) return L0;
+    op = arg->string;
+
+    arg = list_next( arg );
+    if (arg == 0) return L0;
+    rhs = arg->string;
+
+    lhs_value = atoi (lhs);
+    rhs_value = atoi (rhs);
+
+    if (strcmp ("+", op) == 0)
+    {
+        result_value = lhs_value + rhs_value;
+    }
+    else if (strcmp ("-", op) == 0)
+    {
+        result_value = lhs_value - rhs_value;
+    }
+    else
+    {
+        return L0;
+    }
+
+    sprintf (buffer, "%ld", result_value);
+    result = list_new( result, newstr( buffer ) );
+    return result;
+}
+
+/*
+ * builtin_depends() - DEPENDS/INCLUDES rule
+ *
+ * The DEPENDS builtin rule appends each of the listed sources on the 
+ * dependency list of each of the listed targets.  It binds both the 
+ * targets and sources as TARGETs.
+ */
+
+LIST *
+builtin_depends(
+	PARSE	*parse,
+	FRAME *frame )
+{
+	LIST *targets = lol_get( frame->args, 0 );
+	LIST *sources = lol_get( frame->args, 1 );
+	int which = parse->num;
+	LIST *l;
+
+	for( l = targets; l; l = list_next( l ) )
+	{
+	    TARGET *t = bindtarget( l->string );
+
+	    /* If doing INCLUDES, switch to the TARGET's include */
+	    /* TARGET, creating it if needed.  The internal include */
+	    /* TARGET shares the name of its parent. */
+
+	    if( parse->num )
+	    {
+            if( !t->includes ) {
+                t->includes = copytarget( t );
+                t->includes->original_target = t;
+            }
+            t = t->includes;
+	    }
+
+	    t->depends = targetlist( t->depends, sources );
+	}
+
+	return L0;
+}
+
+/*
+ * builtin_echo() - ECHO rule
+ *
+ * The ECHO builtin rule echoes the targets to the user.  No other 
+ * actions are taken.
+ */
+
+LIST *
+builtin_echo(
+	PARSE	*parse,
+	FRAME *frame )
+{
+	list_print( lol_get( frame->args, 0 ) );
+	printf( "\n" );
+	return L0;
+}
+
+/*
+ * builtin_exit() - EXIT rule
+ *
+ * The EXIT builtin rule echoes the targets to the user and exits
+ * the program with a failure status.
+ */
+
+LIST *
+builtin_exit(
+	PARSE	*parse,
+	FRAME *frame )
+{
+	list_print( lol_get( frame->args, 0 ) );
+	printf( "\n" );
+	exit( EXITBAD ); /* yeech */
+	return L0;
+}
+
+/*
+ * builtin_flags() - NOCARE, NOTFILE, TEMPORARY rule
+ *
+ * Builtin_flags() marks the target with the appropriate flag, for use
+ * by make0().  It binds each target as a TARGET.
+ */
+
+LIST *
+builtin_flags(
+	PARSE	*parse,
+	FRAME *frame )
+{
+	LIST *l = lol_get( frame->args, 0 );
+
+	for( ; l; l = list_next( l ) )
+	    bindtarget( l->string )->flags |= parse->num;
+
+	return L0;
+}
+
+/*
+ * builtin_globbing() - GLOB rule
+ */
+
+struct globbing {
+    LIST    *patterns;
+    LIST    *results;
+    LIST    *case_insensitive;
+} ;
+
+static void downcase_inplace( char* p )
+{
+    for ( ; *p; ++p )
+    {
+        *p = tolower(*p);
+    }
+}
+    
+static void
+builtin_glob_back(
+    void    *closure,
+    char    *file,
+    int status,
+    time_t  time )
+{
+    struct globbing *globbing = (struct globbing *)closure;
+    LIST        *l;
+    PATHNAME    f;
+    string          buf[1];
+
+    /* Null out directory for matching. */
+    /* We wish we had file_dirscan() pass up a PATHNAME. */
+
+    path_parse( file, &f );
+    f.f_dir.len = 0;
+    string_new( buf );
+    path_build( &f, buf, 0 );
+
+    if (globbing->case_insensitive)
+        downcase_inplace( buf->value );
+
+    for( l = globbing->patterns; l; l = l->next )
+    {
+        if( !glob( l->string, buf->value ) )
+        {
+            globbing->results = list_new( globbing->results, newstr( file ) );
+            break;
+        }
+    }
+    
+    string_free( buf );
+}
+
+static LIST* downcase_list( LIST *in )
+{
+    LIST* result = 0;
+    
+    string s[1];
+    string_new( s );
+        
+    while (in)
+    {
+        string_copy( s, in->string );
+        downcase_inplace( s->value );
+        result = list_append( result, list_new( 0, newstr( s->value ) ) );
+        in = in->next;
+    }
+    
+    string_free( s );
+    return result;
+}
+
+LIST *
+builtin_glob(
+    PARSE   *parse,
+    FRAME *frame )
+{
+    LIST *l = lol_get( frame->args, 0 );
+    LIST *r = lol_get( frame->args, 1 );
+    
+    struct globbing globbing;
+
+    globbing.results = L0;
+    globbing.patterns = r;
+    
+    globbing.case_insensitive
+# if defined( OS_NT ) || defined( OS_CYGWIN )
+       = l;  /* always case-insensitive if any files can be found */
+# else 
+       = lol_get( frame->args, 2 );
+# endif
+
+    if ( globbing.case_insensitive )
+    {
+        globbing.patterns = downcase_list( r );
+    }
+    
+    for( ; l; l = list_next( l ) )
+        file_dirscan( l->string, builtin_glob_back, &globbing );
+
+    if ( globbing.case_insensitive )
+    {
+        list_free( globbing.patterns );
+    }
+    return globbing.results;
+}
+
+/*
+ * builtin_match() - MATCH rule, regexp matching
+ */
+
+LIST *
+builtin_match(
+	PARSE	*parse,
+	FRAME	*frame )
+{
+	LIST *l, *r;
+	LIST *result = 0;
+        
+        string buf[1];
+        string_new(buf);
+
+	/* For each pattern */
+
+	for( l = lol_get( frame->args, 0 ); l; l = l->next )
+	{
+            /* Result is cached and intentionally never freed */
+	    regexp *re = regex_compile( l->string );
+
+	    /* For each string to match against */
+            for( r = lol_get( frame->args, 1 ); r; r = r->next )
+            {
+                if( regexec( re, r->string ) )
+                {
+                    int i, top;
+
+                    /* Find highest parameter */
+
+                    for( top = NSUBEXP; top-- > 1; )
+                        if( re->startp[top] )
+                            break;
+
+                    /* And add all parameters up to highest onto list. */
+                    /* Must have parameters to have results! */
+
+                    for( i = 1; i <= top; i++ )
+                    {
+                        string_append_range( buf, re->startp[i], re->endp[i] );
+                        result = list_new( result, newstr( buf->value ) );
+                        string_truncate( buf, 0 );
+                    }
+                }
+            }
+        }
+
+        string_free( buf );
+        return result;
+}
+
+LIST *
+builtin_hdrmacro(
+    PARSE    *parse,
+    FRAME *frame )
+{
+  LIST*  l = lol_get( frame->args, 0 );
+  
+  for ( ; l; l = list_next(l) )
+  {
+    TARGET*  t = bindtarget( l->string );
+
+    /* scan file for header filename macro definitions */    
+    if ( DEBUG_HEADER )
+      printf( "scanning '%s' for header file macro definitions\n",
+              l->string );
+
+    macro_headers( t );
+  }
+  
+  return L0;
+}
+
+/*  builtin_rulenames() - RULENAMES ( MODULE ? )
+ *
+ *  Returns a list of the non-local rule names in the given MODULE. If
+ *  MODULE is not supplied, returns the list of rule names in the
+ *  global module.
+ */
+
+/* helper function for builtin_rulenames(), below */
+static void add_rule_name( void* r_, void* result_ )
+{
+    RULE* r = (RULE*)r_;
+    LIST** result = (LIST**)result_;
+
+    if ( r->exported )
+        *result = list_new( *result, copystr( r->name ) );
+}
+
+LIST *
+builtin_rulenames(
+    PARSE   *parse,
+    FRAME *frame )
+{
+    LIST *arg0 = lol_get( frame->args, 0 );
+    LIST *result = L0;
+    module_t* source_module = bindmodule( arg0 ? arg0->string : 0 );
+
+    if ( source_module->rules )
+        hashenumerate( source_module->rules, add_rule_name, &result );
+    return result;
+}
+
+/*  builtin_varnames() - VARNAMES ( MODULE ? )
+ *
+ *  Returns a list of the variable names in the given MODULE. If
+ *  MODULE is not supplied, returns the list of variable names in the
+ *  global module.
+ */
+
+/* helper function for builtin_varnames(), below.  Used with
+ * hashenumerate, will prepend the key of each element to a list
+ */
+static void add_hash_key( void* np, void* result_ )
+{
+    LIST** result = (LIST**)result_;
+
+    *result = list_new( *result, copystr( *(char**)np ) );
+}
+
+LIST *
+builtin_varnames(
+    PARSE   *parse,
+    FRAME *frame )
+{
+    LIST *arg0 = lol_get( frame->args, 0 );
+    LIST *result = L0;
+    module_t* source_module = bindmodule( arg0 ? arg0->string : 0 );
+
+    if ( source_module->variables )
+        hashenumerate( source_module->variables, add_hash_key, &result );
+    return result;
+}
+
+/*
+ * builtin_delete_module() - MODULE ?
+ *
+ * Clears all rules and variables from the given module.
+ */
+LIST *
+builtin_delete_module(
+    PARSE   *parse,
+    FRAME *frame )
+{
+    LIST *arg0 = lol_get( frame->args, 0 );
+    LIST *result = L0;
+    module_t* source_module = bindmodule( arg0 ? arg0->string : 0 );
+
+    delete_module( source_module );
+    return result;
+}
+
+static void unknown_rule( FRAME *frame, char* key, char *module_name, char *rule_name )
+{
+    backtrace_line( frame->prev );
+    printf( "%s error: rule \"%s\" unknown in module \"%s\"\n", key, rule_name, module_name );
+    backtrace( frame->prev );
+    exit(1);
+    
+}
+
+/*
+ * builtin_import() - IMPORT ( SOURCE_MODULE ? : SOURCE_RULES * : TARGET_MODULE ? : TARGET_RULES * : LOCALIZE ? )
+ *
+ * The IMPORT rule imports rules from the SOURCE_MODULE into the
+ * TARGET_MODULE as local rules. If either SOURCE_MODULE or
+ * TARGET_MODULE is not supplied, it refers to the global
+ * module. SOURCE_RULES specifies which rules from the SOURCE_MODULE
+ * to import; TARGET_RULES specifies the names to give those rules in
+ * TARGET_MODULE. If SOURCE_RULES contains a name which doesn't
+ * correspond to a rule in SOURCE_MODULE, or if it contains a
+ * different number of items than TARGET_RULES, an error is issued.
+ * if LOCALIZE is specified, the rules will be executed in
+ * TARGET_MODULE, with corresponding access to its module local
+ * variables.
+ */
+LIST *
+builtin_import(
+    PARSE *parse,
+    FRAME *frame )
+{
+    LIST *source_module_list = lol_get( frame->args, 0 );
+    LIST *source_rules = lol_get( frame->args, 1 );
+    LIST *target_module_list = lol_get( frame->args, 2 );
+    LIST *target_rules = lol_get( frame->args, 3 );
+    LIST *localize = lol_get( frame->args, 4 );
+
+    module_t* target_module = bindmodule( target_module_list ? target_module_list->string : 0 );
+    module_t* source_module = bindmodule( source_module_list ? source_module_list->string : 0 );
+    
+    LIST *source_name, *target_name;
+            
+    for ( source_name = source_rules, target_name = target_rules;
+          source_name && target_name;
+          source_name = list_next( source_name )
+          , target_name = list_next( target_name ) )
+    {
+        RULE r_, *r = &r_, *imported;
+        r_.name = source_name->string;
+                
+        if ( !source_module->rules
+             || !hashcheck( source_module->rules, (HASHDATA**)&r )
+            )
+        {
+            unknown_rule( frame, "IMPORT", source_module->name, r_.name );
+        }
+        
+        imported = import_rule( r, target_module, target_name->string );
+        if ( localize )
+            imported->module = target_module;
+        imported->exported = 0; /* this rule is really part of some other module; just refer to it here, but don't let it out */
+    }
+    
+    if ( source_name || target_name )
+    {
+        backtrace_line( frame->prev );
+        printf( "import error: length of source and target rule name lists don't match!\n" );
+        printf( "    source: " );
+        list_print( source_rules );
+        printf( "\n    target: " );
+        list_print( target_rules );
+        printf( "\n" );
+        backtrace( frame->prev );
+        exit(1);
+    }
+
+    return L0;
+}
+
+
+/*
+ * builtin_export() - EXPORT ( MODULE ? : RULES * )
+ *
+ * The EXPORT rule marks RULES from the SOURCE_MODULE as non-local
+ * (and thus exportable). If an element of RULES does not name a rule
+ * in MODULE, an error is issued.
+ */
+LIST *
+builtin_export(
+    PARSE *parse,
+    FRAME *frame )
+{
+    LIST *module_list = lol_get( frame->args, 0 );
+    LIST *rules = lol_get( frame->args, 1 );
+
+    module_t* m = bindmodule( module_list ? module_list->string : 0 );
+    
+            
+    for ( ; rules; rules = list_next( rules ) )
+    {
+        RULE r_, *r = &r_;
+        r_.name = rules->string;
+                
+        if ( !m->rules || !hashcheck( m->rules, (HASHDATA**)&r ) )
+            unknown_rule( frame, "EXPORT", m->name, r_.name );
+        
+        r->exported = 1;
+    }
+    return L0;
+}
+
+/*  Retrieve the file and line number that should be indicated for a
+ *  given procedure in debug output or an error backtrace
+ */
+static void get_source_line( PARSE* procedure, char** file, int* line )
+{
+    if ( procedure )
+    {
+        char* f = procedure->file;
+        int l = procedure->line;
+        if ( !strcmp( f, "+" ) )
+        {
+            f = "jambase.c";
+            l += 3;
+        }
+        *file = f;
+        *line = l;
+    }
+    else
+    {
+        *file = "(builtin)";
+        *line = -1;
+    }
+}
+
+void print_source_line( PARSE* p )
+{
+    char* file;
+    int line;
+
+    get_source_line( p, &file, &line );
+    if ( line < 0 )
+        printf( "(builtin):" );
+    else
+        printf( "%s:%d:", file, line);
+}
+
+/* Print a single line of error backtrace for the given frame */
+void backtrace_line( FRAME *frame )
+{
+    if ( frame == 0 )
+    {
+        printf( "(no frame):" );
+    }
+    else
+    {
+        print_source_line( frame->procedure );
+        printf( " in %s\n", frame->rulename );
+    }
+}
+
+/*  Print the entire backtrace from the given frame to the Jambase
+ *  which invoked it.
+ */
+void backtrace( FRAME *frame )
+{
+	if ( !frame ) return;
+    while ( frame = frame->prev )
+    {
+        backtrace_line( frame );
+    }
+}
+
+/*  A Jam version of the backtrace function, taking no arguments and
+ *  returning a list of quadruples: FILENAME LINE MODULE. RULENAME
+ *  describing each frame. Note that the module-name is always
+ *  followed by a period.
+ */
+LIST *builtin_backtrace( PARSE *parse, FRAME *frame )
+{
+    LIST* levels_arg = lol_get( frame->args, 0 );
+    int levels = levels_arg ? atoi( levels_arg->string ) : ((unsigned int)(-1) >> 1) ;
+
+    LIST* result = L0;
+    for(; (frame = frame->prev) && levels ; --levels )
+    {
+        char* file;
+        int line;
+        char buf[32];
+        get_source_line( frame->procedure, &file, &line );
+        sprintf( buf, "%d", line );
+        result = list_new( result, newstr( file ) );
+        result = list_new( result, newstr( buf ) );
+        result = list_new( result, newstr( frame->module->name ) );
+        result = list_new( result, newstr( frame->rulename ) );
+    }
+    return result;
+}
+
+/*
+ * builtin_caller_module() - CALLER_MODULE ( levels ? )
+ *
+ * If levels is not supplied, returns the name of the module of the rule which
+ * called the one calling this one. If levels is supplied, it is interpreted as
+ * an integer specifying a number of additional levels of call stack to traverse
+ * in order to locate the module in question. If no such module exists,
+ * returns the empty list. Also returns the empty list when the module in
+ * question is the global module. This rule is needed for implementing module
+ * import behavior.
+ */
+LIST *builtin_caller_module( PARSE *parse, FRAME *frame )
+{
+    LIST* levels_arg = lol_get( frame->args, 0 );
+    int levels = levels_arg ? atoi( levels_arg->string ) : 0 ;
+
+    int i;
+    for (i = 0; i < levels + 2 && frame->prev; ++i)
+        frame = frame->prev;
+
+    if ( frame->module == root_module() )
+    {
+        return L0;
+    }
+    else
+    {
+        LIST* result;
+        
+        string name;
+        string_copy( &name, frame->module->name );
+        string_pop_back( &name );
+
+        result = list_new( L0, newstr(name.value) );
+        
+        string_free( &name );
+        
+        return result;
+    }
+}
+
+/*
+ * Return the current working directory.
+ *
+ * Usage: pwd = [ PWD ] ;
+ */
+LIST*
+builtin_pwd( PARSE *parse, FRAME *frame )
+{
+    return pwd();
+}
+
+/*
+ * Adds targets to the list of target that jam will attempt to update.
+ */
+LIST* 
+builtin_update( PARSE *parse, FRAME *frame)
+{
+    LIST* result = list_copy( L0, targets_to_update() );
+    LIST* arg1 = lol_get( frame->args, 0 );
+    clear_targets_to_update();
+    for ( ; arg1; arg1 = list_next( arg1 ) )
+        mark_target_for_updating( newstr(arg1->string) );
+    return result;
+}
+
+LIST*
+builtin_search_for_target( PARSE *parse, FRAME *frame )
+{
+    LIST* arg1 = lol_get( frame->args, 0 );
+    LIST* arg2 = lol_get( frame->args, 1 );
+
+    TARGET* t = search_for_target( arg1->string, arg2 );
+    return list_new( L0, t->name );
+}
+
+LIST *builtin_import_module( PARSE *parse, FRAME *frame )
+{
+    LIST* arg1 = lol_get( frame->args, 0 );
+    LIST* arg2 = lol_get( frame->args, 1 );
+
+    module_t* m = arg2 ? bindmodule(arg2->string) : root_module();
+
+    import_module(arg1, m);
+
+    return L0;
+}
+
+
+LIST *builtin_imported_modules( PARSE *parse, FRAME *frame )
+{
+    LIST *arg0 = lol_get( frame->args, 0 );
+    module_t* source_module = bindmodule( arg0 ? arg0->string : 0 );
+
+    return imported_modules(source_module);
+}
+
+LIST *builtin_instance( PARSE *parse, FRAME *frame )
+{
+    LIST* arg1 = lol_get( frame->args, 0 );
+    LIST* arg2 = lol_get( frame->args, 1 );
+
+    module_t* instance = bindmodule( arg1->string );
+    module_t* class_module = bindmodule( arg2->string );
+    instance->class_module = class_module;
+
+    return L0;
+}
+
+LIST*
+builtin_sort( PARSE *parse, FRAME *frame )
+{
+    LIST* arg1 = lol_get( frame->args, 0 );
+
+    return list_sort(arg1);
+}
+
+LIST *builtin_normalize_path( PARSE *parse, FRAME *frame )
+{
+    LIST* arg1 = lol_get( frame->args, 0 );
+
+    /* First, we iterate over all '/'-separated elements, starting from
+       the end of string. If we see '..', we remove previous path elements.
+       If we see '.', we remove it.
+       The removal is done by putting '\1' in the string. After all the string
+       is processed, we do a second pass, removing '\1' characters.
+    */
+    
+    string in[1], out[1], tmp[1];
+    char* end;      /* Last character of the part of string still to be processed. */
+    char* current;  /* Working pointer. */  
+    int dotdots = 0; /* Number of '..' elements seen and not processed yet. */
+    int rooted = arg1->string[0] == '/';
+    char* result;
+
+    /* Make a copy of input: we should not change it. */
+    string_new(in);
+    if (!rooted)
+        string_push_back(in, '/');
+    string_append(in, arg1->string);
+    
+
+    end = in->value + in->size - 1;
+    current = end;
+    
+    for(;end >= in->value;) {
+        /* Set 'current' to the next occurence of '/', which always exists. */
+        for(current = end; *current != '/'; --current)
+            ;
+        
+        if (current == end && current != in->value) {
+            /* Found a trailing slash. Remove it. */
+            *current = '\1';
+        } else if (current == end && *(current+1) == '/') {
+            /* Found duplicated slash. Remove it. */
+            *current = '\1';
+        } else if (end - current == 1 && strncmp(current, "/.", 2) == 0) {
+            /* Found '/.'. Drop them all. */
+            *current = '\1';
+            *(current+1) = '\1';                   
+        } else if (end - current == 2 && strncmp(current, "/..", 3) == 0) {
+            /* Found '/..' */                
+            *current = '\1';
+            *(current+1) = '\1';                   
+            *(current+2) = '\1';                   
+            ++dotdots;
+        } else if (dotdots) {
+            char* p = current;
+            memset(current, '\1', end-current+1);
+            --dotdots;
+        }                 
+        end = current-1;
+    }
+
+
+    string_new(tmp);
+    while(dotdots--)
+        string_append(tmp, "/..");
+    string_append(tmp, in->value);
+    string_copy(in, tmp->value);
+    string_free(tmp);
+        
+       
+    string_new(out);
+    /* The resulting path is either empty or has '/' as the first significant
+       element. If the original path was not rooted, we need to drop first '/'. 
+       If the original path was rooted, and we've got empty path, need to add '/'
+    */
+    if (!rooted) {
+        current = strchr(in->value, '/');
+        if (current)
+            *current = '\1';
+    } 
+       
+    for (current = in->value; *current; ++current)
+        if (*current != '\1')
+            string_push_back(out, *current);
+
+    
+    result = newstr(out->size ? out->value : (rooted ? "/" : "."));
+    string_free(in);
+    string_free(out);
+
+    return list_new(0, result);
+
+}
+
+LIST *builtin_native_rule( PARSE *parse, FRAME *frame )
+{
+    LIST* module_name = lol_get( frame->args, 0 );    
+    LIST* rule_name = lol_get( frame->args, 1 );    
+
+    module_t* module = bindmodule(module_name->string);
+
+    native_rule_t n, *np = &n;
+    n.name = rule_name->string;
+    if (module->native_rules && hashcheck(module->native_rules, (HASHDATA**)&np))
+    {
+        new_rule_body(module, np->name, np->arguments, np->procedure, 1);
+    }
+    else
+    {
+        backtrace_line( frame->prev );
+        printf( "error: no native rule \"%s\" defined in module \"%s\"\n", 
+                n.name, module->name);
+        backtrace( frame->prev );
+        exit(1);
+    }
+    return L0;    
+}
+
+
+void lol_build( LOL* lol, char** elements )
+{
+    LIST* l = L0;
+    lol_init( lol );
+    
+    while ( elements && *elements )
+    {
+        if ( !strcmp( *elements, ":" ) )
+        {
+            lol_add( lol, l );
+            l = L0 ;
+        }
+        else
+        {
+            l = list_new( l, newstr( *elements ) );
+        }
+        ++elements;
+    }
+    
+    if ( l != L0 )
+        lol_add( lol, l );
+}
+

Added: boost-jam/boost-build/branches/upstream/current/jam_src/builtins.h
===================================================================
--- boost-jam/boost-build/branches/upstream/current/jam_src/builtins.h	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/jam_src/builtins.h	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,46 @@
+/*
+ * Copyright 1993-2002 Christopher Seiwald and Perforce Software, Inc.
+ *
+ * This file is part of Jam - see jam.c for Copyright information.
+ */
+
+#ifndef JAM_BUILTINS_H
+# define JAM_BUILTINS_H
+
+# include "frames.h"
+
+/*
+ * builtins.h - compile parsed jam statements
+ */
+
+void load_builtins();
+
+LIST *builtin_calc( PARSE *parse, FRAME *args );
+LIST *builtin_depends( PARSE *parse, FRAME *args );
+LIST *builtin_echo( PARSE *parse, FRAME *args );
+LIST *builtin_exit( PARSE *parse, FRAME *args );
+LIST *builtin_flags( PARSE *parse, FRAME *args );
+LIST *builtin_glob( PARSE *parse, FRAME *args );
+LIST *builtin_subst( PARSE  *parse, FRAME *args );
+LIST *builtin_match( PARSE *parse, FRAME *args );
+LIST *builtin_hdrmacro( PARSE *parse, FRAME *args );
+LIST *builtin_rulenames( PARSE *parse, FRAME *args );
+LIST *builtin_varnames( PARSE *parse, FRAME *args );
+LIST *builtin_delete_module( PARSE *parse, FRAME *args );
+LIST *builtin_import( PARSE *parse, FRAME *args );
+LIST *builtin_export( PARSE *parse, FRAME *args );
+LIST *builtin_caller_module( PARSE *parse, FRAME *args );
+LIST *builtin_backtrace( PARSE *parse, FRAME *args );
+LIST *builtin_pwd( PARSE *parse, FRAME *args );
+LIST *builtin_update( PARSE *parse, FRAME *args );
+LIST *builtin_search_for_target( PARSE *parse, FRAME *args );
+LIST *builtin_import_module( PARSE *parse, FRAME *args );
+LIST *builtin_imported_modules( PARSE *parse, FRAME *frame );
+LIST *builtin_instance( PARSE *parse, FRAME *frame );
+LIST *builtin_sort( PARSE *parse, FRAME *frame );
+LIST *builtin_normalize_path( PARSE *parse, FRAME *frame );
+LIST *builtin_native_rule( PARSE *parse, FRAME *frame );
+
+void backtrace( FRAME *frame );
+
+#endif

Added: boost-jam/boost-build/branches/upstream/current/jam_src/bump_version.py
===================================================================
--- boost-jam/boost-build/branches/upstream/current/jam_src/bump_version.py	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/jam_src/bump_version.py	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,55 @@
+#!/usr/bin/python
+
+# This script is used to bump version of bjam. It takes a single argument, e.g
+#
+#    ./bump_version.py 3.1.9
+#
+# and updates all necessary files. For the time being, it's assumes presense
+# of 'perl' executable and Debian-specific 'dch' executable.
+#
+ 
+
+import sys
+import string
+import os
+
+def spec(version):
+    os.system("perl -pi -e 's|^Version:.*|Version: %s|' boost-jam.spec" %
+              string.join(version, "."))
+
+def build_jam(version):
+    os.system("perl -pi -e 's|^VERSION = .* ;|VERSION = %s\$(.)%s\$(.)%s ;|' build.jam"
+              % (version[0], version[1], version[2]))
+
+def index_html(version):
+    os.system("perl -pi -e 's|This is version .* of BJam|This is version %s of BJam|' index.html"
+              % string.join(version, "."))
+
+def jam_c(version):
+    re = "\\*major_version = .*, \\*minor_version = .*, \\*changenum = .*";
+    new = ('*major_version = "%02d", *minor_version = "%02d", *changenum = "%02d";' %
+        (int(version[0]), int(version[1]), int(version[2])))
+    os.system("perl -pi -e 's|%s|%s|' jam.c" % (re, new))
+
+def patchlevel(version):
+    os.system("perl -pi -e 's|VERSION .*|VERSION \"%s\"|' patchlevel.h" %
+              string.join(version, "."))
+
+def dch(version):
+    os.system("dch --ignore-dirname -v " + string.join(version, ".") + "-1")
+       
+bumpers = [spec, build_jam, index_html, jam_c, patchlevel, dch]
+
+def main():
+
+    if len(sys.argv) < 2:
+        print "Expect new version as argument"
+        sys.exit(1)
+                
+    new_version = string.split(sys.argv[1], ".")
+    print "Setting version to", new_version
+    for b in bumpers:
+        b(new_version)
+
+if __name__ == '__main__':
+    main()


Property changes on: boost-jam/boost-build/branches/upstream/current/jam_src/bump_version.py
___________________________________________________________________
Name: svn:executable
   + 

Added: boost-jam/boost-build/branches/upstream/current/jam_src/class.c
===================================================================
--- boost-jam/boost-build/branches/upstream/current/jam_src/class.c	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/jam_src/class.c	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,131 @@
+/* Copyright Vladiir Prus 2003. Distributed under the Boost */
+/* Software License, Version 1.0. (See accompanying */
+/* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */
+
+#include "class.h"
+#include "strings.h"
+#include "variable.h"
+#include "frames.h"
+#include "rules.h"
+#include "newstr.h"
+
+#include "hash.h"
+
+static struct hash* classes = 0;
+
+static void check_defined(LIST* class_names)
+{
+    for (; class_names; class_names = class_names->next) {
+        char** p = &class_names->string;
+        if (!hashcheck(classes, (HASHDATA**)&p)) {
+            printf("Class %s is not defined\n", class_names->string);
+            abort();
+        }
+    }
+}
+
+static char* class_module_name(char* declared_name)
+{
+    string name[1];
+    char* result;
+    
+    string_new(name);
+    string_append(name, "class@");
+    string_append(name, declared_name);
+
+    result = newstr(name->value);
+    string_free(name);
+    
+    return result;
+}
+
+struct import_base_data {
+    char* base_name;
+    module_t* base_module;
+    module_t* class_module;
+};
+
+static void import_base_rule(void* r_, void* d_)
+{
+    RULE* r = (RULE*)r_;
+    RULE* ir1;
+    RULE* ir2;
+    struct import_base_data* d = (struct import_base_data*)d_;
+    string qualified_name[1];
+    int basename_lenght = strlen(d->base_name)+1;
+
+    string_new(qualified_name);
+    string_append(qualified_name, d->base_name);
+    string_push_back(qualified_name, '.');
+    string_append(qualified_name, r->name);    
+
+    ir1 = import_rule(r, d->class_module, r->name);
+    ir2 = import_rule(r, d->class_module, qualified_name->value);
+
+    /* Copy 'exported' flag. */
+    ir1->exported = ir2->exported = r->exported;
+
+    /* If we're importing class method, localize it. */
+    if (r->module == d->base_module 
+        || r->module->class_module && r->module->class_module == d->base_module) {
+        ir1->module = ir2->module = d->class_module;        
+    }
+        
+    string_free(qualified_name);
+}
+
+/** For each exported rule 'n', declared in class module for base,
+    imports that rule in 'class' as 'n' and as 'base.n'. Imported
+    rules are localized and marked as exported.
+*/
+static void import_base_rules(module_t* class, char* base)
+{
+    module_t* base_module = bindmodule(class_module_name(base));
+    struct import_base_data d;
+    d.base_name = base;
+    d.base_module = base_module;
+    d.class_module = class;
+
+    if (base_module->rules)
+        hashenumerate(base_module->rules, import_base_rule, &d);
+
+    import_module( imported_modules(base_module), class );
+}
+
+char* make_class_module(LIST* xname, LIST* bases, FRAME* frame)
+{
+    char* name = class_module_name(xname->string);
+    char** pp = &xname->string;
+    module_t* class_module = 0;
+    module_t* outer_module = frame->module;    
+
+    if (!classes)
+        classes = hashinit(sizeof(char*), "classes");
+
+    
+    if (hashcheck(classes, (HASHDATA**)&pp)) {        
+        printf("Class %s already defined\n", xname->string);
+        abort();
+    } else {
+        hashenter(classes, (HASHDATA**)&pp);
+    }
+    check_defined(bases);
+    
+    class_module = bindmodule(name);
+
+    exit_module( outer_module );
+    enter_module( class_module );
+
+    var_set("__name__", xname, VAR_SET);
+    var_set("__bases__", bases, VAR_SET);
+    
+    exit_module( class_module );
+    enter_module( outer_module );
+    
+    for(; bases; bases = bases->next)
+        import_base_rules(class_module, bases->string);
+
+
+
+    return name;
+}

Added: boost-jam/boost-build/branches/upstream/current/jam_src/class.h
===================================================================
--- boost-jam/boost-build/branches/upstream/current/jam_src/class.h	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/jam_src/class.h	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,13 @@
+/* Copyright Vladimir Prus 2003. Distributed under the Boost */
+/* Software License, Version 1.0. (See accompanying */
+/* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */
+
+#ifndef CLASS_H_VP_2003_08_01
+#define CLASS_H_VP_2003_08_01
+
+#include "lists.h"
+#include "frames.h"
+
+char* make_class_module(LIST* xname, LIST* bases, FRAME* frame);
+
+#endif

Added: boost-jam/boost-build/branches/upstream/current/jam_src/command.c
===================================================================
--- boost-jam/boost-build/branches/upstream/current/jam_src/command.c	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/jam_src/command.c	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,104 @@
+/*
+ * Copyright 1993, 1995 Christopher Seiwald.
+ *
+ * This file is part of Jam - see jam.c for Copyright information.
+ */
+
+/*  This file is ALSO:
+ *  Copyright 2001-2004 David Abrahams.
+ *  Distributed under the Boost Software License, Version 1.0.
+ *  (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+ */
+
+/*
+ * command.c - maintain lists of commands
+ */
+
+# include "jam.h"
+
+# include "lists.h"
+# include "parse.h"
+# include "variable.h"
+# include "rules.h"
+
+# include "command.h"
+# include <limits.h>
+# include <string.h>
+
+/*
+ * cmd_new() - return a new CMD or 0 if too many args
+ */
+
+CMD *
+cmd_new(
+	RULE	*rule,
+	LIST	*targets,
+	LIST	*sources,
+	LIST	*shell )
+{
+    CMD *cmd = (CMD *)malloc( sizeof( CMD ) );
+    /* lift line-length limitation entirely when JAMSHELL is just "%" */
+    int no_limit = ( shell && !strcmp(shell->string,"%") && !list_next(shell) );
+    int max_line = MAXLINE;
+    int allocated = -1;
+
+    cmd->rule = rule;
+    cmd->shell = shell;
+    cmd->next = 0;
+
+    lol_init( &cmd->args );
+    lol_add( &cmd->args, targets );
+    lol_add( &cmd->args, sources );
+    cmd->buf = 0;
+
+    do
+    {
+        free(cmd->buf); /* free any buffer from previous iteration */
+        
+        cmd->buf = (char*)malloc(max_line + 1);
+        
+        if (cmd->buf == 0)
+            break;
+        
+        allocated = var_string( rule->actions->command, cmd->buf, max_line, &cmd->args );
+        
+        max_line = max_line * 2;
+    }
+    while( allocated < 0 && max_line < INT_MAX / 2 );
+
+    if ( !no_limit )
+    {
+        /* Bail if the result won't fit in MAXLINE */
+        char *s = cmd->buf;
+        while ( *s )
+        {
+            size_t l = strcspn( s, "\n" );
+            
+            if ( l > MAXLINE )
+            {
+                /* We don't free targets/sources/shell if bailing. */
+                cmd_free( cmd );
+                return 0;
+            }
+            
+            s += l;
+            if ( *s )
+                ++s;
+        }
+    }
+
+    return cmd;
+}
+
+/*
+ * cmd_free() - free a CMD
+ */
+
+void
+cmd_free( CMD *cmd )
+{
+	lol_free( &cmd->args );
+	list_free( cmd->shell );
+    free( cmd->buf );
+	free( (char *)cmd );
+}

Added: boost-jam/boost-build/branches/upstream/current/jam_src/command.h
===================================================================
--- boost-jam/boost-build/branches/upstream/current/jam_src/command.h	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/jam_src/command.h	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,58 @@
+/*
+ * Copyright 1994 Christopher Seiwald.
+ *
+ * This file is part of Jam - see jam.c for Copyright information.
+ */
+
+/*
+ * command.h - the CMD structure and routines to manipulate them
+ *
+ * Both ACTION and CMD contain a rule, targets, and sources.  An
+ * ACTION describes a rule to be applied to the given targets and
+ * sources; a CMD is what actually gets executed by the shell.  The
+ * differences are due to:
+ *
+ *	ACTIONS must be combined if 'actions together' is given.
+ *	ACTIONS must be split if 'actions piecemeal' is given.
+ *	ACTIONS must have current sources omitted for 'actions updated'.
+ *
+ * The CMD datatype holds a single command that is to be executed 
+ * against a target, and they can chain together to represent the 
+ * full collection of commands used to update a target.
+ *
+ * Structures:
+ *
+ * 	CMD - an action, ready to be formatted into a buffer and executed
+ *
+ * External routines:
+ *
+ * 	cmd_new() - return a new CMD or 0 if too many args
+ *	cmd_free() - delete CMD and its parts
+ *	cmd_next() - walk the CMD chain
+ */
+
+/*
+ * CMD - an action, ready to be formatted into a buffer and executed
+ */
+
+typedef struct _cmd CMD;
+
+struct _cmd
+{
+	CMD	*next;
+	CMD	*tail;		/* valid on in head */
+	RULE	*rule;		/* rule->actions contains shell script */
+	LIST	*shell;		/* $(SHELL) value */
+	LOL	args;		/* LISTs for $(<), $(>) */
+	char*   buf;	/* actual commands */
+} ;
+
+CMD *cmd_new(
+	RULE	*rule,		/* rule (referenced) */
+	LIST	*targets,	/* $(<) (freed) */
+	LIST	*sources,	/* $(>) (freed) */
+	LIST	*shell );	/* $(SHELL) (freed) */
+
+void cmd_free( CMD *cmd );
+
+# define cmd_next( c ) ((c)->next)

Added: boost-jam/boost-build/branches/upstream/current/jam_src/compile.c
===================================================================
--- boost-jam/boost-build/branches/upstream/current/jam_src/compile.c	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/jam_src/compile.c	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,1319 @@
+/*
+ * Copyright 1993, 2000 Christopher Seiwald.
+ *
+ * This file is part of Jam - see jam.c for Copyright information.
+ */
+
+/*  This file is ALSO:
+ *  Copyright 2001-2004 David Abrahams.
+ *  Distributed under the Boost Software License, Version 1.0.
+ *  (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+ */
+
+# include "jam.h"
+
+# include "lists.h"
+# include "parse.h"
+# include "compile.h"
+# include "variable.h"
+# include "expand.h"
+# include "rules.h"
+# include "newstr.h"
+# include "make.h"
+# include "search.h"
+# include "hdrmacro.h"
+# include "hash.h"
+# include "modules.h"
+# include "strings.h"
+# include "builtins.h"
+# include "class.h"
+
+# include <time.h>
+# include <assert.h>
+# include <string.h>
+# include <stdarg.h>
+
+/*
+ * compile.c - compile parsed jam statements
+ *
+ * External routines:
+ *
+ *  compile_append() - append list results of two statements
+ *	compile_eval() - evaluate if to determine which leg to compile
+ *  compile_foreach() - compile the "for x in y" statement
+ *  compile_if() - compile 'if' rule
+ *  compile_while() - compile 'while' rule
+ *  compile_include() - support for 'include' - call include() on file
+ *  compile_list() - expand and return a list 
+ *  compile_local() - declare (and set) local variables
+ *  compile_null() - do nothing -- a stub for parsing
+ *  compile_on() - run rule under influence of on-target variables
+ *  compile_rule() - compile a single user defined rule
+ *  compile_rules() - compile a chain of rules
+ *  compile_set() - compile the "set variable" statement
+ *  compile_setcomp() - support for `rule` - save parse tree 
+ *  compile_setexec() - support for `actions` - save execution string 
+ *  compile_settings() - compile the "on =" (set variable on exec) statement
+ *  compile_switch() - compile 'switch' rule
+ *
+ * Internal routines:
+ *
+ *  debug_compile() - printf with indent to show rule expansion.
+ *  evaluate_rule() - execute a rule invocation
+ *
+ *  builtin_depends() - DEPENDS/INCLUDES rule
+ *  builtin_echo() - ECHO rule
+ *  builtin_exit() - EXIT rule
+ *  builtin_flags() - NOCARE, NOTFILE, TEMPORARY rule
+ *
+ * 02/03/94 (seiwald) - Changed trace output to read "setting" instead of 
+ *          the awkward sounding "settings".
+ * 04/12/94 (seiwald) - Combined build_depends() with build_includes().
+ * 04/12/94 (seiwald) - actionlist() now just appends a single action.
+ * 04/13/94 (seiwald) - added shorthand L0 for null list pointer
+ * 05/13/94 (seiwald) - include files are now bound as targets, and thus
+ *          can make use of $(SEARCH)
+ * 06/01/94 (seiwald) - new 'actions existing' does existing sources
+ * 08/23/94 (seiwald) - Support for '+=' (append to variable)
+ * 12/20/94 (seiwald) - NOTIME renamed NOTFILE.
+ * 01/22/95 (seiwald) - Exit rule.
+ * 02/02/95 (seiwald) - Always rule; LEAVES rule.
+ * 02/14/95 (seiwald) - NoUpdate rule.
+ * 09/11/00 (seiwald) - new evaluate_rule() for headers().
+ * 09/11/00 (seiwald) - compile_xxx() now return LIST *.
+ *          New compile_append() and compile_list() in
+ *          support of building lists here, rather than
+ *          in jamgram.yy.
+ * 01/10/00 (seiwald) - built-ins split out to builtin.c.
+ */
+
+static void debug_compile( int which, char *s, FRAME* frame );
+int glob( char *s, char *c );
+/* Internal functions from builtins.c */
+void backtrace( FRAME *frame );
+void backtrace_line( FRAME *frame );
+void print_source_line( PARSE* p );
+
+
+void frame_init( FRAME* frame )
+{
+    frame->prev = 0;
+    lol_init(frame->args);
+    frame->module = root_module();
+    frame->rulename = "module scope";
+    frame->procedure = 0;
+}
+
+void frame_free( FRAME* frame )
+{
+    lol_free( frame->args );
+}
+
+/*
+ * compile_append() - append list results of two statements
+ *
+ *  parse->left more compile_append() by left-recursion
+ *  parse->right    single rule
+ */
+
+LIST *
+compile_append(
+    PARSE   *parse,
+    FRAME *frame )
+{
+    /* Append right to left. */
+
+    return list_append( 
+        parse_evaluate( parse->left, frame ),
+        parse_evaluate( parse->right, frame ) );
+}
+
+/*
+ * compile_eval() - evaluate if to determine which leg to compile
+ *
+ * Returns:
+ *	list 	if expression true - compile 'then' clause
+ *	L0	if expression false - compile 'else' clause
+ */
+
+static int
+lcmp( LIST *t, LIST *s )
+{
+	int status = 0;
+
+	while( !status && ( t || s ) )
+	{
+	    char *st = t ? t->string : "";
+	    char *ss = s ? s->string : "";
+
+	    status = strcmp( st, ss );
+
+	    t = t ? list_next( t ) : t;
+	    s = s ? list_next( s ) : s;
+	}
+
+	return status;
+}
+
+LIST *
+compile_eval(
+	PARSE	*parse,
+	FRAME	*frame )
+{
+	LIST *ll, *lr, *s, *t;
+	int status = 0;
+
+	/* Short circuit lr eval for &&, ||, and 'in' */
+
+	ll = parse_evaluate( parse->left, frame );
+	lr = 0;
+
+	switch( parse->num )
+	{
+	case EXPR_AND: 
+	case EXPR_IN: 	if( ll ) goto eval; break;
+	case EXPR_OR: 	if( !ll ) goto eval; break;
+	default: eval: 	lr = parse_evaluate( parse->right, frame );
+	}
+
+	/* Now eval */
+
+	switch( parse->num )
+	{
+	case EXPR_NOT:	
+		if( !ll ) status = 1;
+		break;
+
+	case EXPR_AND:
+		if( ll && lr ) status = 1;
+		break;
+
+	case EXPR_OR:
+		if( ll || lr ) status = 1;
+		break;
+
+	case EXPR_IN:
+		/* "a in b": make sure each of */
+		/* ll is equal to something in lr. */
+
+		for( t = ll; t; t = list_next( t ) )
+		{
+		    for( s = lr; s; s = list_next( s ) )
+			if( !strcmp( t->string, s->string ) )
+			    break;
+		    if( !s ) break;
+		}
+
+		/* No more ll? Success */
+
+		if( !t ) status = 1;
+
+		break;
+
+	case EXPR_EXISTS:       if( lcmp( ll, L0 ) != 0 ) status = 1; break;
+	case EXPR_EQUALS:	if( lcmp( ll, lr ) == 0 ) status = 1; break;
+	case EXPR_NOTEQ:	if( lcmp( ll, lr ) != 0 ) status = 1; break;
+	case EXPR_LESS:		if( lcmp( ll, lr ) < 0  ) status = 1; break;
+	case EXPR_LESSEQ:	if( lcmp( ll, lr ) <= 0 ) status = 1; break;
+	case EXPR_MORE:		if( lcmp( ll, lr ) > 0  ) status = 1; break;
+	case EXPR_MOREEQ:	if( lcmp( ll, lr ) >= 0 ) status = 1; break;
+
+	}
+
+	if( DEBUG_IF )
+	{
+	    debug_compile( 0, "if", frame );
+	    list_print( ll );
+	    printf( "(%d) ", status );
+	    list_print( lr );
+	    printf( "\n" );
+	}
+
+	/* Find something to return. */
+	/* In odd circumstances (like "" = "") */
+	/* we'll have to return a new string. */
+
+	if( !status ) t = 0;
+	else if( ll ) t = ll, ll = 0;
+	else if( lr ) t = lr, lr = 0;
+	else t = list_new( L0, newstr( "1" ) );
+
+	if( ll ) list_free( ll );
+	if( lr ) list_free( lr );
+	return t;
+}
+
+
+/*
+ * compile_foreach() - compile the "for x in y" statement
+ *
+ * Compile_foreach() resets the given variable name to each specified
+ * value, executing the commands enclosed in braces for each iteration.
+ *
+ *  parse->string   index variable
+ *  parse->left variable values
+ *  parse->right    rule to compile
+ */
+
+LIST *
+compile_foreach(
+    PARSE   *parse,
+    FRAME *frame )
+{
+    LIST    *nv = parse_evaluate( parse->left, frame );
+    LIST    *l;
+    SETTINGS *s = 0;
+        
+        if ( parse->num )
+        {
+            s = addsettings( s, 0, parse->string, L0 );
+            pushsettings( s );
+        }
+
+    /* Call var_set to reset $(parse->string) for each val. */
+
+    for( l = nv; l; l = list_next( l ) )
+    {
+        LIST *val = list_new( L0, copystr( l->string ) );
+
+        var_set( parse->string, val, VAR_SET );
+
+        list_free( parse_evaluate( parse->right, frame ) );
+    }
+
+        if ( parse->num )
+        {
+            popsettings( s );
+            freesettings( s );
+        }
+
+    list_free( nv );
+
+    return L0;
+}
+
+/*
+ * compile_if() - compile 'if' rule
+ *
+ *  parse->left     condition tree
+ *  parse->right        then tree
+ *  parse->third        else tree
+ */
+
+LIST *
+compile_if(
+    PARSE   *p,
+    FRAME *frame )
+{
+    LIST *l = parse_evaluate( p->left, frame );
+    if( l )
+    {
+        list_free( l );
+        return parse_evaluate( p->right, frame );
+    }
+    else
+    {
+        return parse_evaluate( p->third, frame );
+    }
+}
+
+LIST *
+compile_while(
+    PARSE   *p,
+    FRAME *frame )
+{
+    LIST *r = 0;
+    LIST *l;
+    while ( l = parse_evaluate( p->left, frame ) )
+    {
+        list_free( l );
+        if( r ) list_free( r );
+        r = parse_evaluate( p->right, frame );
+    }
+    return r;
+}
+
+
+/*
+ * compile_include() - support for 'include' - call include() on file
+ *
+ *  parse->left list of files to include (can only do 1)
+ */
+
+LIST *
+compile_include(
+    PARSE   *parse,
+    FRAME *frame )
+{
+    LIST    *nt = parse_evaluate( parse->left, frame );
+
+    if( DEBUG_COMPILE )
+    {
+        debug_compile( 0, "include", frame);
+        list_print( nt );
+        printf( "\n" );
+    }
+
+    if( nt )
+    {
+        TARGET *t = bindtarget( nt->string );
+
+            /* DWA 2001/10/22 - Perforce Jam clears the arguments here, which
+             * prevents an included file from being treated as part of the body
+             * of a rule. I didn't see any reason to do that, so I lifted the
+             * restriction.
+             */
+               
+        /* Bind the include file under the influence of */
+        /* "on-target" variables.  Though they are targets, */
+        /* include files are not built with make(). */
+
+        pushsettings( t->settings );
+        /* We don't expect that file to be included is generated by some
+           action. Therefore, pass 0 as third argument. */
+        t->boundname = search( t->name, &t->time, 0 );
+        popsettings( t->settings );
+
+        parse_file( t->boundname, frame );
+    }
+
+    list_free( nt );
+
+    return L0;
+}
+
+static LIST* evaluate_in_module ( char* module_name, PARSE * p, FRAME* frame)
+{
+    LIST* result;
+
+    module_t* outer_module = frame->module;
+    frame->module = module_name ? bindmodule( module_name ) : root_module();
+
+    if ( outer_module != frame->module )
+    {
+        exit_module( outer_module );
+        enter_module( frame->module );
+    }
+    
+    result = parse_evaluate( p, frame );
+    
+    if ( outer_module != frame->module )
+    {
+        exit_module( frame->module );
+        enter_module( outer_module );
+        frame->module = outer_module;
+    }
+
+    return result;
+}
+
+LIST *
+compile_module(
+    PARSE   *p,
+    FRAME *frame )
+{
+    /* Here we are entering a module declaration block. 
+     */
+    LIST* module_name = parse_evaluate( p->left, frame );
+    LIST* result = evaluate_in_module( module_name ? module_name->string : 0, 
+                                       p->right, frame );
+    
+    list_free( module_name );
+    return result;
+}
+
+LIST *
+compile_class( 
+    PARSE *p, 
+    FRAME *frame )
+{
+    /** Todo: check for empty class name.
+        Check for class redeclaration. */
+
+    char* class_module = 0;
+
+    LIST* name = parse_evaluate( p->left->right, frame );
+    LIST* bases = 0;
+
+    if (p->left->left)
+        bases = parse_evaluate( p->left->left->right, frame );
+
+    class_module = make_class_module(name, bases, frame);    
+    evaluate_in_module( class_module, p->right, frame );
+
+    return L0;    
+}
+
+
+/*
+ * compile_list() - expand and return a list 
+ *
+ *  parse->string - character string to expand
+ */
+
+LIST *
+compile_list(
+    PARSE   *parse,
+    FRAME *frame )
+{
+    /* voodoo 1 means: s is a copyable string */
+    char *s = parse->string;
+    return var_expand( L0, s, s + strlen( s ), frame->args, 1 );
+}
+
+/*
+ * compile_local() - declare (and set) local variables
+ *
+ *  parse->left list of variables
+ *  parse->right    list of values
+ *  parse->third    rules to execute
+ */
+
+LIST *
+compile_local(
+    PARSE   *parse,
+    FRAME *frame )
+{
+    LIST *l;
+    SETTINGS *s = 0;
+    LIST    *nt = parse_evaluate( parse->left, frame );
+    LIST    *ns = parse_evaluate( parse->right, frame );
+    LIST    *result;
+
+    if( DEBUG_COMPILE )
+    {
+        debug_compile( 0, "local", frame);
+        list_print( nt );
+        printf( " = " );
+        list_print( ns );
+        printf( "\n" );
+    }
+
+    /* Initial value is ns */
+
+    for( l = nt; l; l = list_next( l ) )
+        s = addsettings( s, 0, l->string, list_copy( (LIST*)0, ns ) );
+
+    list_free( ns );
+    list_free( nt );
+
+    /* Note that callees of the current context get this "local" */
+    /* variable, making it not so much local as layered. */
+
+    pushsettings( s );
+    result = parse_evaluate( parse->third, frame );
+    popsettings( s );
+
+    freesettings( s );
+
+    return result;
+}
+
+/*
+ * compile_null() - do nothing -- a stub for parsing
+ */
+
+LIST *
+compile_null(
+    PARSE   *parse,
+    FRAME *frame )
+{
+    return L0;
+}
+
+/*
+ * compile_on() - run rule under influence of on-target variables
+ *
+ * 	parse->left	list of files to include (can only do 1)
+ *	parse->right	rule to run
+ *
+ * EXPERIMENTAL!
+ */
+
+LIST *
+compile_on(
+	PARSE	*parse,
+	FRAME	*frame )
+{
+	LIST    *nt = parse_evaluate( parse->left, frame );
+	LIST	*result = 0;
+
+	if( DEBUG_COMPILE )
+	{
+	    debug_compile( 0, "on", frame );
+	    list_print( nt );
+	    printf( "\n" );
+	}
+
+	if( nt )
+	{
+	    TARGET *t = bindtarget( nt->string );
+	    pushsettings( t->settings );
+
+	    result = parse_evaluate( parse->right, frame );
+
+	    popsettings( t->settings );
+	}
+
+	list_free( nt );
+
+	return result;
+}
+
+
+/*
+ * compile_rule() - compile a single user defined rule
+ *
+ *  parse->string   name of user defined rule
+ *  parse->left parameters (list of lists) to rule, recursing left
+ *
+ * Wrapped around evaluate_rule() so that headers() can share it.
+ */
+
+LIST *
+compile_rule(
+    PARSE   *parse,
+    FRAME *frame )
+{
+    FRAME       inner[1];
+    LIST    *result;
+    PARSE   *p;
+    
+
+    /* Build up the list of arg lists */
+
+    frame_init( inner );
+    inner->prev = frame;
+    inner->module = frame->module; /* This gets fixed up in evaluate_rule(), below */
+    inner->procedure = parse;
+
+    for( p = parse->left; p; p = p->left )
+        lol_add( inner->args, parse_evaluate( p->right, frame ) );
+
+    /* And invoke rule */
+
+    result = evaluate_rule( parse->string, inner );
+
+    frame_free( inner );
+
+    return result;
+}
+
+static void argument_error( char* message, RULE* rule, FRAME* frame, LIST* arg )
+{
+    LOL* actual = frame->args;
+    assert( frame->procedure != 0 );
+    backtrace_line( frame->prev );
+    printf( "*** argument error\n* rule %s ( ", frame->rulename );
+    lol_print( rule->arguments->data );
+    printf( " )\n* called with: ( " );
+    lol_print( actual );
+    printf( " )\n* %s %s\n", message, arg ? arg->string : "" );
+    print_source_line( rule->procedure );
+    printf( "see definition of rule '%s' being called\n", rule->name );
+    backtrace( frame->prev );
+    exit(1);
+}
+
+/* define delimiters for type check elements in argument lists (and
+ * return type specifications, eventually)
+ */
+# define TYPE_OPEN_DELIM '['
+# define TYPE_CLOSE_DELIM ']'
+
+/* is_type_name - true iff the given string represents a type check
+ * specification
+ */
+static int
+is_type_name( char* s )
+{
+    return s[0] == TYPE_OPEN_DELIM
+        && s[strlen(s) - 1] == TYPE_CLOSE_DELIM;
+}
+
+/*
+ * arg_modifier - if the next element of formal is a single character,
+ * return that; return 0 otherwise.  Used to extract "*+?" modifiers
+ * from argument lists.
+ */
+static char
+arg_modifier( LIST* formal )
+{
+    if ( formal->next )
+    {
+        char *next = formal->next->string;
+        if ( next && next[0] != 0 && next[1] == 0 )
+            return next[0];
+    }
+    return 0;
+}
+
+/*
+ * type_check - checks that each element of values satisfies the
+ * requirements of type_name.
+ *
+ *      caller   - the frame of the rule calling the rule whose
+ *                 arguments are being checked
+ *
+ *      called   - the rule being called
+ *
+ *      arg_name - a list element containing the name of the argument
+ *                 being checked
+ */
+static void
+type_check( char* type_name, LIST *values, FRAME* caller, RULE* called, LIST* arg_name )
+{
+    static module_t *typecheck = 0;
+
+    /* if nothing to check, bail now */
+    if ( !values || !type_name )
+        return;
+
+    if ( !typecheck )
+        typecheck = bindmodule(".typecheck");
+
+    /* if the checking rule can't be found, also bail */
+    {
+        RULE checker_, *checker = &checker_;
+
+        checker->name = type_name;
+        if ( !typecheck->rules || !hashcheck( typecheck->rules, (HASHDATA**)&checker ) )
+            return;
+    }
+    
+    exit_module( caller->module );
+    
+    while ( values != 0 )
+    {
+        LIST *error;
+        FRAME frame[1];
+        frame_init( frame );
+        frame->module = typecheck;
+        frame->prev = caller;
+
+        enter_module( typecheck );
+        /* Prepare the argument list */
+        lol_add( frame->args, list_new( L0, values->string ) );
+        error = evaluate_rule( type_name, frame );
+        
+        exit_module( typecheck );
+        
+        if ( error )
+            argument_error( error->string, called, caller, arg_name );
+
+        frame_free( frame );
+		values = values->next;
+    }
+
+    enter_module( caller->module );
+}
+
+/*
+ * collect_arguments() - local argument checking and collection
+ */
+static SETTINGS *
+collect_arguments( RULE* rule, FRAME* frame )
+{
+    SETTINGS *locals = 0;
+    
+    LOL* all_actual = frame->args;
+    LOL *all_formal = rule->arguments ? rule->arguments->data : 0;
+    if ( all_formal ) /* Nothing to set; nothing to check */
+    {
+        int max = all_formal->count > all_actual->count
+            ? all_formal->count
+            : all_actual->count;
+        
+        int n;
+        for ( n = 0; n < max ; ++n )
+        {
+            LIST *actual = lol_get( all_actual, n );
+            char *type_name = 0;
+            
+            LIST *formal;
+            for ( formal = lol_get( all_formal, n ); formal; formal = formal->next )
+            {
+                char* name = formal->string;
+
+                if ( is_type_name(name) )
+                {
+                    if ( type_name )
+                        argument_error( "missing argument name before type name:", rule, frame, formal );
+                    
+                    if ( !formal->next )
+                        argument_error( "missing argument name after type name:", rule, frame, formal );
+
+                    type_name = formal->string;
+                }
+                else
+                {
+                    LIST* value = 0;
+                    char modifier;
+                    LIST* arg_name = formal; /* hold the argument name for type checking */
+                    
+                    /* Stop now if a variable number of arguments are specified */
+                    if ( name[0] == '*' && name[1] == 0 )
+                        return locals;
+
+                    modifier = arg_modifier( formal );
+                
+                    if ( !actual && modifier != '?' && modifier != '*' )
+                        argument_error( "missing argument", rule, frame, formal );
+
+                    switch ( modifier )
+                    {
+                    case '+':
+                    case '*':
+                        value = list_copy( 0, actual );
+                        actual = 0;
+                        /* skip an extra element for the modifier */
+                        formal = formal->next; 
+                        break;
+                    case '?':
+                        /* skip an extra element for the modifier */
+                        formal = formal->next; 
+                        /* fall through */
+                    default:
+                        if ( actual ) /* in case actual is missing */
+                        {
+                            value = list_new( 0, actual->string );
+                            actual = actual->next;
+                        }
+                    }
+                
+                    locals = addsettings( locals, 0, name, value );
+                    type_check( type_name, value, frame, rule, arg_name );
+                    type_name = 0;
+                }
+            }
+            
+            if ( actual )
+            {
+                argument_error( "extra argument", rule, frame, actual );
+            }
+        }
+    }
+    return locals;
+}
+
+struct profile_info
+{
+    char* name;                 /* name of rule being called */
+    clock_t cumulative;         /* cumulative time spent in rule */
+    clock_t net;                /* time spent in rule proper */
+    unsigned long num_entries;  /* number of time rule was entered */
+    unsigned long stack_count;  /* number of the times this function is present in stack */
+};
+typedef struct profile_info profile_info;
+
+struct profile_frame
+{
+    profile_info* info;               /* permanent storage where data accumulates */
+    clock_t overhead;                 /* overhead for profiling in this call */
+    clock_t entry_time;               /* time of last entry to rule */
+    struct profile_frame* caller;     /* stack frame of caller */
+    clock_t subrules;                 /* time spent in subrules */
+};
+typedef struct profile_frame profile_frame;
+
+static profile_frame* profile_stack = 0;
+static struct hash* profile_hash = 0;
+
+static void profile_enter( char* rulename, profile_frame* frame )
+{
+    clock_t start = clock();
+    profile_info info, *p = &info;
+    
+    if ( !profile_hash )
+        profile_hash = hashinit(sizeof(profile_info), "profile");
+
+    info.name = rulename;
+    
+    if ( hashenter( profile_hash, (HASHDATA **)&p ) )
+        p->cumulative = p->net = p->num_entries = p->stack_count = 0;
+
+    ++(p->num_entries);
+    ++(p->stack_count);
+    
+    frame->info = p;
+    
+    frame->caller = profile_stack;
+    profile_stack = frame;
+
+    frame->entry_time = clock();
+    frame->overhead = 0;
+    frame->subrules = 0;
+
+    /* caller pays for the time it takes to play with the hash table */
+    if ( frame->caller )
+        frame->caller->overhead += frame->entry_time - start;
+}
+    
+static void profile_exit(profile_frame* frame)
+{
+    /* cumulative time for this call */
+    clock_t t = clock() - frame->entry_time - frame->overhead;
+    /* If this rule is already present on the stack, don't add the time for
+       this instance. */
+    if (frame->info->stack_count == 1)
+        frame->info->cumulative += t;
+    /* Net time does not depend on presense of the same rule in call stack. */
+    frame->info->net += t - frame->subrules;
+        
+    if (frame->caller)
+    {
+        /* caller's cumulative time must account for this overhead */
+        frame->caller->overhead += frame->overhead;
+        frame->caller->subrules += t;
+    }
+    /* pop this stack frame */
+    --frame->info->stack_count;
+    profile_stack = frame->caller;
+}
+
+static void dump_profile_entry(void* p_, void* ignored)
+{
+    profile_info* p = (profile_info*)p_;
+    printf("%10d %10d %10d %s\n", p->cumulative, p->net, p->num_entries, p->name);
+}
+
+void profile_dump()
+{
+    if ( profile_hash )
+    {
+        printf("%10s %10s %10s %s\n", "gross", "net", "# entries", "name");
+        hashenumerate( profile_hash, dump_profile_entry, 0 );
+    }
+}
+
+/*
+ * evaluate_rule() - execute a rule invocation
+ */
+
+LIST *
+evaluate_rule(
+    char    *rulename,
+    FRAME *frame )
+{
+    LIST      *result = L0;
+    RULE          *rule;
+    profile_frame prof[1];
+    module_t    *prev_module = frame->module;
+    
+    LIST      *l;
+    {
+        LOL arg_context_, *arg_context = &arg_context_;
+        if ( !frame->prev )
+            lol_init(arg_context);
+        else
+            arg_context = frame->prev->args;
+        
+        l = var_expand( L0, rulename, rulename+strlen(rulename), arg_context, 0 );
+    }
+
+    if ( !l )
+    {
+        backtrace_line( frame->prev );
+        printf( "warning: rulename %s expands to empty string\n", rulename );
+        backtrace( frame->prev );
+        return result;
+    }
+
+    rulename = l->string;
+    rule = bindrule( l->string, frame->module );
+
+    /* drop the rule name */
+    l = list_pop_front( l );
+
+    /* tack the rest of the expansion onto the front of the first argument */
+    frame->args->list[0] = list_append( l, lol_get( frame->args, 0 ) );
+
+    if ( DEBUG_COMPILE )
+    {
+        /* Try hard to indicate in which module the rule is going to execute */
+        if ( rule->module != frame->module
+             && rule->procedure != 0 && strcmp(rulename, rule->procedure->rulename) )
+        {
+            char buf[256] = "";
+            strncat( buf, rule->module->name, sizeof(buf) - 1 );
+            strncat( buf, rule->name, sizeof(buf) - 1 );
+            debug_compile( 1, buf, frame);
+        }
+        else
+        {
+            debug_compile( 1, rulename, frame);
+        }
+
+        lol_print( frame->args );
+        printf( "\n" );
+    }
+    
+    if ( rule->procedure && rule->module != prev_module )
+    {
+        /* propagate current module to nested rule invocations */
+        frame->module = rule->module;
+        
+        /* swap variables */
+        exit_module( prev_module );
+        enter_module( rule->module );
+    }
+        
+    /* record current rule name in frame */
+    if ( rule->procedure )
+    {
+        frame->rulename = rulename;
+        /* and enter record profile info */
+        if ( DEBUG_PROFILE )
+            profile_enter( rule->procedure->rulename, prof );
+    }
+
+    /* Check traditional targets $(<) and sources $(>) */
+
+    if( !rule->actions && !rule->procedure )
+    {
+        backtrace_line( frame->prev );
+        printf( "rule %s unknown in module %s\n", rule->name, frame->module->name );
+        backtrace( frame->prev );
+        exit(1);
+    }
+
+    /* If this rule will be executed for updating the targets */
+    /* then construct the action for make(). */
+
+    if( rule->actions )
+    {
+        TARGETS *t;
+        ACTION  *action;
+
+        /* The action is associated with this instance of this rule */
+
+        action = (ACTION *)malloc( sizeof( ACTION ) );
+        memset( (char *)action, '\0', sizeof( *action ) );
+
+        action->rule = rule;
+        action->targets = targetlist( (TARGETS *)0, lol_get( frame->args, 0 ) );
+        action->sources = targetlist( (TARGETS *)0, lol_get( frame->args, 1 ) );
+
+        /* Append this action to the actions of each target */
+
+        for( t = action->targets; t; t = t->next )
+            t->target->actions = actionlist( t->target->actions, action );
+    }
+
+    /* Now recursively compile any parse tree associated with this rule */
+    /* refer/free to ensure rule not freed during use */
+
+    if( rule->procedure )
+    {
+        SETTINGS *local_args = collect_arguments( rule, frame );
+        PARSE *parse = rule->procedure;
+        parse_refer( parse );
+        
+        pushsettings( local_args );
+        result = parse_evaluate( parse, frame );
+        popsettings( local_args );
+        freesettings( local_args );
+        
+        parse_free( parse );
+    }
+
+    if ( frame->module != prev_module )
+    {
+        exit_module( frame->module );
+        enter_module( prev_module );
+    }
+
+    if ( DEBUG_PROFILE && rule->procedure )
+        profile_exit( prof );
+
+    if( DEBUG_COMPILE )
+        debug_compile( -1, 0, frame);
+
+    return result;
+}
+
+/*
+ * Call the given rule with the specified parameters.
+ * The parameters should be of LIST* and end with NULL pointer.
+ * This differs from the 'evaluate_rule' in that frame
+ * for called rule is prepared in 'call_rule'.
+ *
+ * This function is usefull when builtin rule (in C) wants to
+ * call another rule, which might be implemented in Jam.
+ */
+LIST *call_rule( char *rulename, FRAME* caller_frame, ...)
+{
+    va_list va;
+    LIST *result;
+
+    FRAME       inner[1];
+    frame_init( inner );
+    inner->prev = caller_frame;
+    inner->module = caller_frame->module;
+    inner->procedure = 0;
+
+    va_start(va, caller_frame);    
+    for(;;)
+    {
+        LIST* l = va_arg(va, LIST*);
+        if (!l)
+            break;
+        lol_add(inner->args, l);
+    }
+    va_end(va);
+                
+    result = evaluate_rule(rulename, inner);    
+
+    frame_free(inner);
+
+    return result;
+}
+
+/*
+ * compile_rules() - compile a chain of rules
+ *
+ *	parse->left	single rule
+ *	parse->right	more compile_rules() by right-recursion
+ */
+
+LIST *
+compile_rules(
+    PARSE   *parse,
+    FRAME *frame )
+{
+    /* Ignore result from first statement; return the 2nd. */
+	/* Optimize recursion on the right by looping. */
+
+    do list_free( parse_evaluate( parse->left, frame ) );
+    while( (parse = parse->right)->func == compile_rules );
+
+    return parse_evaluate( parse, frame );
+}
+
+/*
+ * compile_set() - compile the "set variable" statement
+ *
+ *  parse->left variable names
+ *  parse->right    variable values 
+ *  parse->num  ASSIGN_SET/APPEND/DEFAULT
+ */
+
+LIST *
+compile_set(
+    PARSE   *parse,
+    FRAME *frame )
+{
+    LIST    *nt = parse_evaluate( parse->left, frame );
+    LIST    *ns = parse_evaluate( parse->right, frame );
+    LIST    *l;
+    int     setflag;
+    char    *trace;
+
+    switch( parse->num )
+    {
+    case ASSIGN_SET:    setflag = VAR_SET; trace = "="; break;
+    case ASSIGN_APPEND: setflag = VAR_APPEND; trace = "+="; break;
+    case ASSIGN_DEFAULT:    setflag = VAR_DEFAULT; trace = "?="; break;
+    default:        setflag = VAR_SET; trace = ""; break;
+    }
+
+    if( DEBUG_COMPILE )
+    {
+        debug_compile( 0, "set", frame);
+        list_print( nt );
+        printf( " %s ", trace );
+        list_print( ns );
+        printf( "\n" );
+    }
+
+    /* Call var_set to set variable */
+    /* var_set keeps ns, so need to copy it */
+
+    for( l = nt; l; l = list_next( l ) )
+        var_set( l->string, list_copy( L0, ns ), setflag );
+
+    list_free( nt );
+
+    return ns;
+}
+
+/*
+ * compile_setcomp() - support for `rule` - save parse tree 
+ *
+ *  parse->string   rule name
+ *  parse->left rules for rule
+ *  parse->right optional list-of-lists describing arguments
+ */
+
+LIST *
+compile_setcomp(
+    PARSE   *parse,
+    FRAME *frame)
+{
+    argument_list* arg_list = 0;
+    
+    /* Create new LOL describing argument requirements if supplied */
+    if ( parse->right )
+    {
+        PARSE *p;
+        arg_list = args_new();
+        for( p = parse->right; p; p = p->left )
+            lol_add( arg_list->data, parse_evaluate( p->right, frame ) );
+    }
+    
+    new_rule_body( frame->module, parse->string, arg_list, parse->left, !parse->num );
+    return L0;
+}
+
+/*
+ * compile_setexec() - support for `actions` - save execution string 
+ *
+ *  parse->string   rule name
+ *  parse->string1  OS command string
+ *  parse->num  flags
+ *  parse->left `bind` variables
+ *
+ * Note that the parse flags (as defined in compile.h) are transfered
+ * directly to the rule flags (as defined in rules.h).
+ */
+
+LIST *
+compile_setexec(
+    PARSE   *parse,
+    FRAME *frame )
+{
+    LIST* bindlist = parse_evaluate( parse->left, frame );
+
+    new_rule_actions( frame->module, parse->string, parse->string1, bindlist, parse->num );
+
+    return L0;
+}
+
+/*
+ * compile_settings() - compile the "on =" (set variable on exec) statement
+ *
+ *  parse->left variable names
+ *  parse->right    target name 
+ *  parse->third    variable value 
+ *  parse->num  ASSIGN_SET/APPEND   
+ */
+
+LIST *
+compile_settings(
+    PARSE   *parse,
+    FRAME *frame )
+{
+    LIST    *nt = parse_evaluate( parse->left, frame );
+    LIST    *ns = parse_evaluate( parse->third, frame );
+    LIST    *targets = parse_evaluate( parse->right, frame );
+    LIST    *ts;
+    int append = parse->num == ASSIGN_APPEND;
+
+    if( DEBUG_COMPILE )
+    {
+        debug_compile( 0, "set", frame);
+        list_print( nt );
+        printf( " on " );
+        list_print( targets );
+        printf( " %s ", append ? "+=" : "=" );
+        list_print( ns );
+        printf( "\n" );
+    }
+
+    /* Call addsettings to save variable setting */
+    /* addsettings keeps ns, so need to copy it */
+    /* Pass append flag to addsettings() */
+
+    for( ts = targets; ts; ts = list_next( ts ) )
+    {
+        TARGET  *t = bindtarget( ts->string );
+        LIST    *l;
+
+        for( l = nt; l; l = list_next( l ) )
+        t->settings = addsettings( t->settings, append, 
+                l->string, list_copy( (LIST*)0, ns ) );
+    }
+
+    list_free( nt );
+    list_free( targets );
+
+    return ns;
+}
+
+/*
+ * compile_switch() - compile 'switch' rule
+ *
+ *  parse->left switch value (only 1st used)
+ *  parse->right    cases
+ *
+ *  cases->left 1st case
+ *  cases->right    next cases
+ *
+ *  case->string    argument to match
+ *  case->left  parse tree to execute
+ */
+
+LIST *
+compile_switch(
+    PARSE   *parse,
+    FRAME *frame )
+{
+    LIST    *nt = parse_evaluate( parse->left, frame );
+    LIST    *result = 0;
+
+    if( DEBUG_COMPILE )
+    {
+        debug_compile( 0, "switch", frame);
+        list_print( nt );
+        printf( "\n" );
+    }
+
+    /* Step through cases */
+
+    for( parse = parse->right; parse; parse = parse->right )
+    {
+        if( !glob( parse->left->string, nt ? nt->string : "" ) )
+        {
+        /* Get & exec parse tree for this case */
+        parse = parse->left->left;
+        result = parse_evaluate( parse, frame );
+        break;
+        }
+    }
+
+    list_free( nt );
+
+    return result;
+}
+
+/*
+ * debug_compile() - printf with indent to show rule expansion.
+ */
+
+static void
+debug_compile( int which, char *s, FRAME* frame )
+{
+    static int level = 0;
+    static char indent[36] = ">>>>|>>>>|>>>>|>>>>|>>>>|>>>>|>>>>|";
+
+    if ( which >= 0 )
+    {
+      int i;
+      
+      print_source_line( frame->procedure );
+      
+      i = (level+1)*2;
+      while ( i > 35 )
+      {
+        printf( indent );
+        i -= 35;
+      }
+
+      printf( "%*.*s ", i, i, indent );
+    }
+
+    if( s )
+        printf( "%s ", s );
+
+    level += which;
+}

Added: boost-jam/boost-build/branches/upstream/current/jam_src/compile.h
===================================================================
--- boost-jam/boost-build/branches/upstream/current/jam_src/compile.h	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/jam_src/compile.h	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,84 @@
+/*
+ * Copyright 1993, 2000 Christopher Seiwald.
+ *
+ * This file is part of Jam - see jam.c for Copyright information.
+ */
+
+/*  This file is ALSO:
+ *  Copyright 2001-2004 David Abrahams.
+ *  Distributed under the Boost Software License, Version 1.0.
+ *  (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+ */
+
+#ifndef COMPILE_DWA20011022_H
+# define COMPILE_DWA20011022_H
+
+# include "frames.h"
+# include "parse.h"
+# include "regexp.h"
+
+/*
+ * compile.h - compile parsed jam statements
+ */
+
+void compile_builtins();
+
+LIST *compile_append( PARSE *parse, FRAME *frame );
+LIST *compile_foreach( PARSE *parse, FRAME *frame );
+LIST *compile_if( PARSE *parse, FRAME *frame );
+LIST *compile_eval( PARSE *parse, FRAME *args );
+LIST *compile_include( PARSE *parse, FRAME *frame );
+LIST *compile_list( PARSE *parse, FRAME *frame );
+LIST *compile_local( PARSE *parse, FRAME *frame );
+LIST *compile_module( PARSE *parse, FRAME *frame );
+LIST *compile_class( PARSE *parse, FRAME *frame );
+LIST *compile_null( PARSE *parse, FRAME *frame );
+LIST *compile_on( PARSE *parse, FRAME *frame );
+LIST *compile_rule( PARSE *parse, FRAME *frame );
+LIST *compile_rules( PARSE *parse, FRAME *frame );
+LIST *compile_set( PARSE *parse, FRAME *frame );
+LIST *compile_setcomp( PARSE *parse, FRAME *frame );
+LIST *compile_setexec( PARSE *parse, FRAME *frame );
+LIST *compile_settings( PARSE *parse, FRAME *frame );
+LIST *compile_switch( PARSE *parse, FRAME *frame );
+LIST *compile_while( PARSE *parse, FRAME *frame );
+
+LIST *evaluate_rule( char *rulename, FRAME *frame );
+LIST *call_rule( char *rulename, FRAME* caller_frame, ...);
+
+regexp* regex_compile( const char* pattern );
+
+void profile_dump();
+
+/* Flags for compile_set(), etc */
+
+# define ASSIGN_SET	0x00	/* = assign variable */
+# define ASSIGN_APPEND	0x01	/* += append variable */
+# define ASSIGN_DEFAULT	0x02	/* set only if unset */
+
+/* Flags for compile_setexec() */
+
+# define EXEC_UPDATED	0x01	/* executes updated */
+# define EXEC_TOGETHER	0x02	/* executes together */
+# define EXEC_IGNORE	0x04	/* executes ignore */
+# define EXEC_QUIETLY	0x08	/* executes quietly */
+# define EXEC_PIECEMEAL	0x10	/* executes piecemeal */
+# define EXEC_EXISTING	0x20	/* executes existing */
+
+/* Conditions for compile_if() */
+
+# define EXPR_NOT	0	/* ! cond */
+# define EXPR_AND	1	/* cond && cond */
+# define EXPR_OR	2	/* cond || cond */
+
+# define EXPR_EXISTS	3	/* arg */
+# define EXPR_EQUALS	4	/* arg = arg */
+# define EXPR_NOTEQ	5	/* arg != arg */
+# define EXPR_LESS	6	/* arg < arg  */
+# define EXPR_LESSEQ	7	/* arg <= arg */
+# define EXPR_MORE	8	/* arg > arg  */
+# define EXPR_MOREEQ	9	/* arg >= arg */
+# define EXPR_IN	10	/* arg in arg */
+
+#endif
+

Added: boost-jam/boost-build/branches/upstream/current/jam_src/debian/changelog
===================================================================
--- boost-jam/boost-build/branches/upstream/current/jam_src/debian/changelog	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/jam_src/debian/changelog	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,54 @@
+bjam (3.1.9-2) unstable; urgency=low
+
+  * Use default value of BOOST_BUILD_PATH is not is set in environment.
+
+ -- Vladimir Prus <ghost at zigzag.lvk.cs.msu.su>  Wed, 17 Dec 2003 16:44:35 +0300
+
+bjam (3.1.9-1) unstable; urgency=low
+
+  * Implement NATIVE_FILE builtin and several native rules.
+
+ -- Vladimir Prus <ghost at zigzag.lvk.cs.msu.su>  Thu, 11 Dec 2003 13:15:26 +0300
+
+bjam (3.1.8-1) unstable; urgency=low
+
+  * New upstream release.
+
+ -- Vladimir Prus <ghost at zigzag.lvk.cs.msu.su>  Tue,  4 Nov 2003 20:50:43 +0300
+
+bjam (3.1.7-1) unstable; urgency=low
+
+  * New upstream release.
+
+ -- Vladimir Prus <ghost at zigzag.lvk.cs.msu.su>  Thu, 11 Sep 2003 10:45:44 +0400
+
+bjam (3.1.6-1) unstable; urgency=low
+
+  * New upstream release.
+
+ -- Vladimir Prus <ghost at zigzag.lvk.cs.msu.su>  Tue,  1 Jul 2003 09:12:18 +0400
+
+bjam (3.1.5-1) unstable; urgency=low
+
+  * New upstream release.
+
+ -- Vladimir Prus <ghost at zigzag.lvk.cs.msu.su>  Mon, 19 May 2003 14:05:13 +0400
+
+bjam (3.1.3-2) unstable; urgency=low
+
+  * Changed Debian package to be similar to Jam's package.
+
+ -- Vladimir Prus <ghost at cs.msu.su>  Thu, 10 Oct 2002 18:43:26 +0400
+
+bjam (3.1.3-1) unstable; urgency=low
+
+  * New upstream release.
+
+ -- Vladimir Prus <ghost at zigzag.lvk.cs.msu.su>  Fri,  4 Oct 2002 18:16:54 +0400
+
+bjam (3.1.2-1) unstable; urgency=low
+
+  * Initial Release.
+
+ -- Vladimir Prus <ghost at cs.msu.su>  Wed, 14 Aug 2002 14:08:00 +0400
+

Added: boost-jam/boost-build/branches/upstream/current/jam_src/debian/control
===================================================================
--- boost-jam/boost-build/branches/upstream/current/jam_src/debian/control	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/jam_src/debian/control	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,16 @@
+Source: bjam
+Section: devel
+Priority: optional
+Maintainer: Vladimir Prus <ghost at cs.msu.su>
+Build-Depends: debhelper (>> 3.0.0), docbook-to-man, bison
+Standards-Version: 3.5.2
+
+Package: bjam
+Architecture: any
+Depends: ${shlibs:Depends}
+Description: Build tool 
+ Boost.Jam is a portable build tool with its own interpreted language, which 
+ allows to implement rather complex logic in a readable way and without 
+ resorting to external programs. It is a descendant of Jam/MR tool modified to 
+ suit the needs of Boost.Build. In particular, modules and rule parameters
+ were added, as well as several new builtins.

Added: boost-jam/boost-build/branches/upstream/current/jam_src/debian/copyright
===================================================================
--- boost-jam/boost-build/branches/upstream/current/jam_src/debian/copyright	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/jam_src/debian/copyright	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,24 @@
+This package was debianized by Vladimir Prus <ghost at cs.msu.su> on
+Wed, 17 July 2002, 19:27:00 +0400.
+
+Copyright:
+
+    /+\
+    +\	Copyright 1993-2002 Christopher Seiwald and Perforce Software, Inc.
+    \+/
+
+    This is Release 2.4 of Jam/MR, a make-like program.
+
+    License is hereby granted to use this software and distribute it
+    freely, as long as this copyright notice is retained and modifications 
+    are clearly marked.
+
+    ALL WARRANTIES ARE HEREBY DISCLAIMED.
+
+Some portions are also:
+
+    Copyright 2001-2004 David Abrahams.
+    Copyright 2002-2004 Rene Rivera.
+    
+    Distributed under the Boost Software License, Version 1.0.
+    (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)

Added: boost-jam/boost-build/branches/upstream/current/jam_src/debian/jam.man.sgml
===================================================================
--- boost-jam/boost-build/branches/upstream/current/jam_src/debian/jam.man.sgml	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/jam_src/debian/jam.man.sgml	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,236 @@
+<!doctype refentry PUBLIC "-//OASIS//DTD DocBook V4.1//EN" [
+
+<!-- Process this file with docbook-to-man to generate an nroff manual
+     page: `docbook-to-man manpage.sgml > manpage.1'.  You may view
+     the manual page with: `docbook-to-man manpage.sgml | nroff -man |
+     less'.  A typical entry in a Makefile or Makefile.am is:
+
+manpage.1: manpage.sgml
+	docbook-to-man $< > $@
+  -->
+
+  <!ENTITY dhfirstname "<firstname>Yann</firstname>">
+  <!ENTITY dhsurname   "<surname>Dirson</surname>">
+  <!-- Please adjust the date whenever revising the manpage. -->
+  <!ENTITY dhdate      "<date>mai 23, 2001</date>">
+  <!ENTITY dhemail     "<email>dirson at debian.org</email>">
+  <!ENTITY dhusername  "Yann Dirson">
+  <!ENTITY dhpackage   "jam">
+
+  <!ENTITY debian      "<productname>Debian GNU/Linux</productname>">
+  <!ENTITY gnu         "<acronym>GNU</acronym>">
+]>
+
+<refentry>
+  <refentryinfo>
+    <address>
+      &dhemail;
+    </address>
+    <author>
+      &dhfirstname;
+      &dhsurname;
+    </author>
+    <copyright>
+      <year>2001</year>
+      <holder>&dhusername;</holder>
+    </copyright>
+    &dhdate;
+  </refentryinfo>
+
+  <refmeta>
+    <refentrytitle>JAM</refentrytitle>
+    <manvolnum>1</manvolnum>
+  </refmeta>
+
+  <refnamediv>
+    <refname>Jam/MR</refname>
+    <refpurpose>Make(1) Redux</refpurpose>
+  </refnamediv>
+
+  <refsynopsisdiv>
+    <cmdsynopsis>
+      <command>jam</command>
+
+      <arg><option>-a</option></arg>
+      <arg><option>-n</option></arg>
+      <arg><option>-v</option></arg>
+
+      <arg><option>-d <replaceable/debug/</option></arg>
+      <arg><option>-f <replaceable/jambase/</option></arg>
+      <arg><option>-j <replaceable/jobs/</option></arg>
+      <arg><option>-o <replaceable/actionsfile/</option></arg>
+      <arg><option>-s <replaceable/var/=<replaceable/value/</option></arg>
+      <arg><option>-t <replaceable/target/</option></arg>
+
+      <arg repeat><option><replaceable/target/</option></arg>
+    </cmdsynopsis>
+  </refsynopsisdiv>
+
+  <refsect1>
+    <title>DESCRIPTION</title>
+
+    <para>Jam is a program construction tool, like make(1).</para>
+
+    <para>Jam recursively builds target files from source files, using
+    dependency information and updating actions expressed in the
+    Jambase file, which is written in jam's own interpreted language.
+    The default Jambase is compiled into jam and provides a
+    boilerplate for common use, relying on a user-provide file
+    "Jamfile" to enumerate actual targets and sources.</para>
+  </refsect1>
+
+  <refsect1>
+    <title>OPTIONS</title>
+
+    <variablelist>
+      <varlistentry>
+        <term><option/-a/</term>
+        <listitem>
+          <para>Build all targets anyway, even if they are up-to-date.</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><option>-d <replaceable/n/</option></term>
+        <listitem>
+          <para>Enable cummulative debugging levels from 1 to
+	    <replaceable/n/. Interesting values are:
+
+	    <glosslist>
+	      <glossentry><glossterm/1/ <glossdef><simpara/Show
+	      actions (the default)/</glossdef></glossentry>
+
+	      <glossentry><glossterm/2/ <glossdef><simpara/Show
+	      "quiet" actions and display all action
+	      text/</glossdef></glossentry>
+
+	      <glossentry><glossterm/3/ <glossdef><simpara>Show
+	      dependency analysis, and target/source
+	      timestamps/paths</simpara></glossdef></glossentry>
+
+	      <glossentry><glossterm/4/ <glossdef><simpara/Show shell
+	      arguments/</glossdef></glossentry>
+
+	      <glossentry><glossterm/5/ <glossdef><simpara/Show rule
+	      invocations and variable
+	      expansions/</glossdef></glossentry>
+
+	      <glossentry><glossterm/6/ <glossdef><simpara>Show
+	      directory/header file/archive
+	      scans</simpara></glossdef></glossentry>
+
+	      <glossentry><glossterm/7/ <glossdef><simpara/Show
+	      variable settings/</glossdef></glossentry>
+
+	      <glossentry><glossterm/8/ <glossdef><simpara/Show
+	      variable fetches/</glossdef></glossentry>
+
+	      <glossentry><glossterm/9/ <glossdef><simpara/Show
+	      variable manipulation, scanner
+	      tokens/</glossdef></glossentry>
+	    </glosslist>
+	  </para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><option>-d +<replaceable/n/</option></term>
+        <listitem>
+          <para>Enable debugging level <replaceable/n/.</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><option/-d 0/</term>
+        <listitem>
+          <para>Turn off all debugging levels. Only errors are not
+          suppressed.</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><option>-f <replaceable/jambase/</option></term>
+        <listitem>
+          <para>Read <replaceable/jambase/ instead of using the
+          built-in Jambase. Only one <option/-f/ flag is permitted,
+          but the <replaceable/jambase/ may explicitly include other
+          files.</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><option>-j <replaceable/n/</option></term>
+        <listitem>
+          <para>Run up to <replaceable/n/ shell commands concurrently
+          (UNIX and NT only). The default is 1.</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><option/-n/</term>
+        <listitem>
+          <para>Don't actually execute the updating actions, but do
+          everything else. This changes the debug level default to
+          <option/-d2/.</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><option>-o <replaceable/file/</option></term>
+        <listitem>
+          <para>Write the updating actions to the specified file
+          instead of running them (or outputting them, as on the
+          Mac).</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><option>-s <replaceable/var/=<replaceable/value/</option></term>
+        <listitem>
+          <para>Set the variable <replaceable/var/ to
+          <replaceable/value/, overriding both internal variables and
+          variables imported from the environment. </para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><option>-t <replaceable/target/</option></term>
+        <listitem>
+          <para>Rebuild <replaceable/target/ and everything that
+          depends on it, even if it is up-to-date.</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><option/-v/</term>
+        <listitem>
+          <para>Print the version of jam and exit.</para>
+        </listitem>
+      </varlistentry>
+
+    </variablelist>
+  </refsect1>
+
+  <refsect1>
+    <title>SEE ALSO</title>
+
+    <para>Jam is documented fully in HTML pages available on Debian
+    systems from
+    <filename>/usr/share/doc/jam/Jam.html</filename>.</para>
+  </refsect1>
+
+  <refsect1>
+    <title>AUTHOR</title>
+
+    <para>This manual page was created by &dhusername; &dhemail; from
+    the <filename/Jam.html/ documentation, for the &debian; system
+    (but may be used by others).</para>
+  </refsect1>
+</refentry>
+
+<!-- Keep this comment at the end of the file
+Local variables:
+sgml-omittag:t
+sgml-shorttag:t
+End:
+-->

Added: boost-jam/boost-build/branches/upstream/current/jam_src/debian/rules
===================================================================
--- boost-jam/boost-build/branches/upstream/current/jam_src/debian/rules	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/jam_src/debian/rules	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,73 @@
+#!/usr/bin/make -f
+# Sample debian/rules that uses debhelper.
+# GNU copyright 1997 to 1999 by Joey Hess.
+# GNU copyright 2001 by Yann Dirson.
+
+# This is the debian/rules file for packages jam and ftjam
+# It should be usable with both packages without any change
+
+# Uncomment this to turn on verbose mode.
+#export DH_VERBOSE=1
+
+# This is the debhelper compatability version to use.
+export DH_COMPAT=3
+
+topdir=$(shell pwd)
+
+jam=bjam
+binname=bjam
+
+build: build-stamp
+build-stamp: debian/jam.1
+	dh_testdir
+
+	./build.sh
+
+	touch build-stamp
+
+%.1: %.man.sgml
+	/usr/bin/docbook-to-man $< > $@
+
+clean:
+	dh_testdir
+	dh_testroot
+	rm -f build-stamp
+	rm -rf bin.*
+	rm -f jam0 debian/jam.1
+	dh_clean
+
+install: build
+	dh_testdir
+	dh_testroot
+	dh_clean -k
+	dh_installdirs
+
+	install -d ${topdir}/debian/${jam}/usr/bin
+	install -m755 bin.linuxx86/bjam ${topdir}/debian/${jam}/usr/bin/
+	install -d ${topdir}/debian/${jam}/usr/share/man/man1/
+	install -m644 debian/jam.1 ${topdir}/debian/${jam}/usr/share/man/man1/${binname}.1
+
+
+# Build architecture-independent files here.
+binary-indep: build install
+# We have nothing to do by default.
+
+# Build architecture-dependent files here.
+binary-arch: build install
+	dh_testdir
+	dh_testroot
+	dh_installdocs README RELNOTES Jambase *.html
+#	dh_installemacsen
+#	dh_undocumented
+	dh_installchangelogs 
+	dh_strip
+	dh_compress
+	dh_fixperms
+	dh_installdeb
+	dh_shlibdeps
+	dh_gencontrol
+	dh_md5sums
+	dh_builddeb
+
+binary: binary-indep binary-arch
+.PHONY: build clean binary-indep binary-arch binary install configure


Property changes on: boost-jam/boost-build/branches/upstream/current/jam_src/debian/rules
___________________________________________________________________
Name: svn:executable
   + 

Added: boost-jam/boost-build/branches/upstream/current/jam_src/execcmd.h
===================================================================
--- boost-jam/boost-build/branches/upstream/current/jam_src/execcmd.h	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/jam_src/execcmd.h	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,23 @@
+/*
+ * Copyright 1993, 1995 Christopher Seiwald.
+ *
+ * This file is part of Jam - see jam.c for Copyright information.
+ */
+
+/*
+ * execcmd.h - execute a shell script
+ *
+ * 05/04/94 (seiwald) - async multiprocess interface
+ */
+
+void execcmd(
+	char *string,
+	void (*func)( void *closure, int status ),
+	void *closure,
+	LIST *shell );
+
+int execwait();
+
+# define EXEC_CMD_OK	0
+# define EXEC_CMD_FAIL	1
+# define EXEC_CMD_INTR	2

Added: boost-jam/boost-build/branches/upstream/current/jam_src/execmac.c
===================================================================
--- boost-jam/boost-build/branches/upstream/current/jam_src/execmac.c	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/jam_src/execmac.c	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,69 @@
+/*
+ * Copyright 1993, 1995 Christopher Seiwald.
+ *
+ * This file is part of Jam - see jam.c for Copyright information.
+ */
+
+# include "jam.h"
+# include "lists.h"
+# include "execcmd.h"
+# include <errno.h>
+
+# ifdef OS_MAC
+
+/*
+ * execunix.c - execute a shell script on UNIX
+ *
+ * If $(JAMSHELL) is defined, uses that to formulate execvp().
+ * The default is:
+ *
+ *	/bin/sh -c %
+ *
+ * Each word must be an individual element in a jam variable value.
+ *
+ * In $(JAMSHELL), % expands to the command string and ! expands to 
+ * the slot number (starting at 1) for multiprocess (-j) invocations.
+ * If $(JAMSHELL) doesn't include a %, it is tacked on as the last
+ * argument.
+ *
+ * Don't just set JAMSHELL to /bin/sh - it won't work!
+ *
+ * External routines:
+ *	execcmd() - launch an async command execution
+ * 	execwait() - wait and drive at most one execution completion
+ *
+ * Internal routines:
+ *	onintr() - bump intr to note command interruption
+ *
+ * 04/08/94 (seiwald) - Coherent/386 support added.
+ * 05/04/94 (seiwald) - async multiprocess interface
+ * 01/22/95 (seiwald) - $(JAMSHELL) support
+ */
+
+/*
+ * execcmd() - launch an async command execution
+ */
+
+void
+execcmd( 
+	char *string,
+	void (*func)( void *closure, int status ),
+	void *closure,
+	LIST *shell )
+{
+	
+	printf( "%s", string );
+	(*func)( closure, EXEC_CMD_OK );
+}
+
+/*
+ * execwait() - wait and drive at most one execution completion
+ */
+
+int
+execwait()
+{
+	return 0;
+}
+
+# endif /* OS_MAC */

Added: boost-jam/boost-build/branches/upstream/current/jam_src/execnt.c
===================================================================
--- boost-jam/boost-build/branches/upstream/current/jam_src/execnt.c	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/jam_src/execnt.c	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,838 @@
+/*
+ * Copyright 1993, 1995 Christopher Seiwald.
+ *
+ * This file is part of Jam - see jam.c for Copyright information.
+ */
+
+/*  This file is ALSO:
+ *  Copyright 2001-2004 David Abrahams.
+ *  Distributed under the Boost Software License, Version 1.0.
+ *  (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+ */
+
+# include "jam.h"
+# include "lists.h"
+# include "execcmd.h"
+# include <errno.h>
+# include <assert.h>
+# include <ctype.h>
+
+# ifdef USE_EXECNT
+
+# define WIN32_LEAN_AND_MEAN
+# include <windows.h>		/* do the ugly deed */
+# include <process.h>
+
+# if !defined( __BORLANDC__ ) && !defined( OS_OS2 )
+# define wait my_wait
+static int my_wait( int *status );
+# endif
+
+/*
+ * execnt.c - execute a shell command on Windows NT and Windows 95/98
+ *
+ * If $(JAMSHELL) is defined, uses that to formulate execvp()/spawnvp().
+ * The default is:
+ *
+ *	/bin/sh -c %		[ on UNIX/AmigaOS ]
+ *	cmd.exe /c %		[ on Windows NT ]
+ *
+ * Each word must be an individual element in a jam variable value.
+ *
+ * In $(JAMSHELL), % expands to the command string and ! expands to 
+ * the slot number (starting at 1) for multiprocess (-j) invocations.
+ * If $(JAMSHELL) doesn't include a %, it is tacked on as the last
+ * argument.
+ *
+ * Don't just set JAMSHELL to /bin/sh or cmd.exe - it won't work!
+ *
+ * External routines:
+ *	execcmd() - launch an async command execution
+ * 	execwait() - wait and drive at most one execution completion
+ *
+ * Internal routines:
+ *	onintr() - bump intr to note command interruption
+ *
+ * 04/08/94 (seiwald) - Coherent/386 support added.
+ * 05/04/94 (seiwald) - async multiprocess interface
+ * 01/22/95 (seiwald) - $(JAMSHELL) support
+ * 06/02/97 (gsar)    - full async multiprocess support for Win32
+ */
+
+static int intr = 0;
+static int cmdsrunning = 0;
+static void (*istat)( int );
+
+static int  is_nt_351        = 0;
+static int  is_win95         = 1;
+static int  is_win95_defined = 0;
+
+
+static struct
+{
+	int	pid; /* on win32, a real process handle */
+	void	(*func)( void *closure, int status );
+	void 	*closure;
+	char	*tempfile;
+
+} cmdtab[ MAXJOBS ] = {{0}};
+
+
+static void
+set_is_win95( void )
+{
+  OSVERSIONINFO  os_info;
+
+  os_info.dwOSVersionInfoSize = sizeof(os_info);
+  os_info.dwPlatformId        = VER_PLATFORM_WIN32_WINDOWS;
+  GetVersionEx( &os_info );
+  
+  is_win95         = (os_info.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS);
+  is_win95_defined = 1;
+  
+  /* now, test wether we're running Windows 3.51                */
+  /* this is later used to limit the system call command length */
+  if (os_info.dwPlatformId ==  VER_PLATFORM_WIN32_NT)
+    is_nt_351 = os_info.dwMajorVersion == 3;
+}
+
+int maxline()
+{
+    if (!is_win95_defined)
+        set_is_win95();
+    
+    /* Set the maximum command line length according to the OS */
+    return is_nt_351 ? 996
+        : is_win95 ? 1023
+        : 2047;
+}
+
+static char**
+string_to_args( const char*  string, int*  pcount )
+{
+  int    total    = strlen( string );
+  int    in_quote = 0,
+      num_args = 0; /* was uninitialized -- dwa */
+  char*  line;
+  char*  p;
+  char** arg;
+  char** args;
+
+  *pcount = 0;  
+
+  /* do not copy trailing newlines, if any */  
+  while ( total > 0 )
+  {
+      if ( !isspace( string[total - 1] ) )
+          break;
+      --total;
+  }
+  
+  /* first of all, copy the input string */
+  line    = (char*)malloc( total+2 );
+  if (!line)
+    return 0;
+    
+  memcpy( line+1, string, total );
+  line[0]       = 0;
+  line[total+1] = 0;
+  
+  in_quote = 0;
+  for ( p = line+1; p[0]; p++ )
+  {
+    switch (p[0])
+    {
+      case '"':
+        in_quote = !in_quote;
+        break;
+        
+      case ' ':
+      case '\t':
+        if (!in_quote)
+          p[0]    = 0;
+        
+      default:
+        ;
+    }
+  }
+  
+  /* now count the arguments.. */
+  for ( p = line; p < line+total+1; p++ )
+    if ( !p[0] && p[1] )
+      num_args++;
+      
+  /* allocate the args array */
+  /* dwa -- did you really mean to allocate only 2 additional bytes? */
+#if 0 /* was like this */
+  args = (char**)malloc( num_args*sizeof(char*)+2 );
+#endif
+  args = (char**)malloc( (num_args + 2) * sizeof(char*) );
+  if (!args)
+  {
+    free( line );
+    return 0;
+  }
+  
+  arg = args+1;
+  for ( p = line; p < line+total+1; p++ )
+    if ( !p[0] && p[1] )
+    {
+      arg[0] = p+1;
+      arg++;
+    }
+  arg[0]  = 0;
+  *pcount = num_args;
+  args[0] = line;
+  return args+1;
+}
+
+static void
+free_args( char** args )
+{
+  free( args[-1] );
+  free( args-1 );
+}
+
+
+/* process a "del" or "erase" command under Windows 95/98 */
+static int
+process_del( char*  command )
+{
+  char** arg;
+  char*  p = command, *q;
+  int    wildcard = 0, result = 0;
+
+  /* first of all, skip the command itself */
+  if ( p[0] == 'd' )
+    p += 3; /* assumes "del..;" */
+  else if ( p[0] == 'e' )
+    p += 5; /* assumes "erase.." */
+  else
+    return 1; /* invalid command */
+
+  /* process all targets independently */
+  for (;;)
+  {
+    /* skip leading spaces */
+    while ( *p && isspace(*p) )
+      p++;
+      
+    /* exit if we encounter an end of string */
+    if (!*p)
+      return 0;
+      
+    /* ignore toggles/flags */
+    while (*p == '/')
+    {
+      p++;
+      while ( *p && isalnum(*p) )
+          p++;
+      while (*p && isspace(*p) )
+          ++p;
+    }
+
+    
+    {
+      int  in_quote = 0;
+      int  wildcard = 0;
+      int  go_on    = 1;
+      
+      q = p;
+      while (go_on)
+      {
+        switch (*p)
+        {
+          case '"':
+            in_quote = !in_quote;
+            break;
+          
+          case '?':
+          case '*':
+            if (!in_quote)
+              wildcard = 1;
+            break;
+            
+          case '\0':
+            if (in_quote)
+              return 1;
+            /* fall-through */
+              
+          case ' ':
+          case '\t':
+            if (!in_quote)
+            {
+              int    len = p - q;
+              int    result;
+              char*  line;
+              
+              /* q..p-1 contains the delete argument */
+              if ( len <= 0 )
+                return 1;
+  
+              line = (char*)malloc( len+4+1 );
+              if (!line)
+                return 1;
+                
+              strncpy( line, "del ", 4 );
+              strncpy( line+4, q, len );
+              line[len+4] = '\0';
+              
+              if ( wildcard )
+                result = system( line );
+              else
+                result = !DeleteFile( line+4 );
+  
+              free( line );
+              if (result)
+                return 1;
+                
+              go_on = 0;
+            }
+            
+          default:
+            ;
+        }
+        p++;
+      } /* while (go_on) */
+    }
+  }
+}
+
+
+/*
+ * onintr() - bump intr to note command interruption
+ */
+
+void
+onintr( int disp )
+{
+	intr++;
+	printf( "...interrupted\n" );
+}
+
+#if 0 // the shell is too different from direct invocation; let's
+      // always use the shell unless forced.
+/*
+ * use_bat_file() - return true iff the command demands the use of a
+ * .bat file to run it
+ */
+int use_bat_file(char* command)
+{
+    char *p = command;
+    
+    char inquote = 0;
+
+    p += strspn( p, " \t" );
+
+    /* spawnvp can't handle any paths with spaces or quoted filenames with no directory prefix */
+    if ( *p == '"' )
+    {
+        char* q = p + 1 + strcspn( p + 1, "\" /\\" );
+        if ( *q == '"' || *q == ' ' )
+            return 1;
+    }
+        
+    /* Look for newlines and unquoted i/o redirection */
+    do
+    {
+        p += strcspn( p, "'\n\"<>|" );
+
+        switch (*p)
+        {
+        case '\n':
+            /* skip over any following spaces */
+            while( isspace( *p ) )
+                ++p;
+            /* return true iff there is anything significant following
+             * the newline
+             */
+            if (*p)
+                return 1;
+            break;
+            
+        case '"':
+        case '\'':
+            if (p > command && p[-1] != '\\')
+            {
+                if (inquote == *p)
+                    inquote = 0;
+                else if (inquote == 0)
+                    inquote = *p;
+            }
+                
+            ++p;
+            break;
+            
+        case '<':
+        case '>':
+        case '|':
+            if (!inquote)
+                return 1;
+            ++p;
+            break;
+        }
+    }
+    while (*p);
+    
+    return p - command >= MAXLINE;
+}
+#endif
+
+void execnt_unit_test()
+{
+#if 0 && !defined(NDEBUG)
+    /* vc6 preprocessor is broken, so assert with these strings gets
+     * confused. Use a table instead.
+     */
+    typedef struct test { char* command; int result; } test;
+    test tests[] = {
+        { "x", 0 },
+        { "x\n ", 0 },
+        { "x\ny", 1 },
+        { "x\n\n y", 1 },
+        { "\"x\"", 1 },
+        { "\"x y\"", 1 },
+        { "\"x/y\"", 0 },
+        { "\"x\\y\"", 0 },
+        { "echo x > foo.bar", 1 },
+        { "echo x < foo.bar", 1 },
+        { "echo x \">\" foo.bar", 0 },
+        { "echo x \"<\" foo.bar", 0 },
+        { "echo x \\\">\\\" foo.bar", 1 },
+        { "echo x \\\"<\\\" foo.bar", 1 }
+    };
+    int i;
+    for ( i = 0; i < sizeof(tests)/sizeof(*tests); ++i)
+    {
+        assert( use_bat_file( tests[i].command ) == tests[i].result );
+    }
+
+    {
+        char* long_command = malloc(MAXLINE + 10);
+        assert( long_command != 0 );
+        memset( long_command, 'x', MAXLINE + 9 );
+        long_command[MAXLINE + 9] = 0;
+        assert( use_bat_file( long_command ) );
+        free( long_command );
+    }
+#endif 
+}
+
+// SVA - handle temp dirs with spaces in the path
+static const char *getTempDir(void)
+{
+    static char tempPath[_MAX_PATH];
+    static char *pTempPath=NULL;
+
+    if(pTempPath == NULL)
+    {
+        char *p;
+
+        p = getenv("TEMP");
+        if(p == NULL)
+        {
+            p = getenv("TMP");
+        }
+        if(p == NULL)
+        {
+            pTempPath = "\\temp";
+        }
+        else
+        {
+            GetShortPathName(p, tempPath, _MAX_PATH);
+            pTempPath = tempPath;
+        }
+    }
+    return pTempPath;
+}
+
+/*
+ * execcmd() - launch an async command execution
+ */
+
+void
+execcmd( 
+	char *string,
+	void (*func)( void *closure, int status ),
+	void *closure,
+	LIST *shell )
+{
+    int pid;
+    int slot;
+    int raw_cmd = 0 ;
+    char *argv_static[ MAXARGC + 1 ];	/* +1 for NULL */
+    char **argv = argv_static;
+    char *p;
+
+    /* Check to see if we need to hack around the line-length limitation. */
+    /* Look for a JAMSHELL setting of "%", indicating that the command
+     * should be invoked directly */
+    if ( shell && !strcmp(shell->string,"%") && !list_next(shell) )
+    {
+        raw_cmd = 1;
+        shell = 0;
+    }
+
+    if ( !is_win95_defined )
+        set_is_win95();
+          
+    /* Find a slot in the running commands table for this one. */
+    if ( is_win95 )
+    {
+        /* only synchronous spans are supported on Windows 95/98 */
+        slot = 0;
+    }
+    else
+    {
+        for( slot = 0; slot < MAXJOBS; slot++ )
+            if( !cmdtab[ slot ].pid )
+                break;
+    }
+    if( slot == MAXJOBS )
+    {
+        printf( "no slots for child!\n" );
+        exit( EXITBAD );
+    }
+  
+    if( !cmdtab[ slot ].tempfile )
+    {
+        const char *tempdir;
+        DWORD procID;
+
+        tempdir = getTempDir();
+  
+        // SVA - allocate 64 other just to be safe
+        cmdtab[ slot ].tempfile = malloc( strlen( tempdir ) + 64 );
+  
+        procID = GetCurrentProcessId();
+  
+        sprintf( cmdtab[ slot ].tempfile, "%s\\jam%d-%02d.bat", 
+                 tempdir, procID, slot );		
+    }
+
+    /* Trim leading, ending white space */
+
+    while( isspace( *string ) )
+        ++string;
+
+    /* If multi line, or too long, or JAMSHELL is set, write to bat file. */
+    /* Otherwise, exec directly. */
+    /* Frankly, if it is a single long line I don't think the */
+    /* command interpreter will do any better -- it will fail. */
+
+    if( shell || !raw_cmd // && use_bat_file( string )
+        )
+    {
+        FILE *f;
+
+        /* Write command to bat file. */
+
+        f = fopen( cmdtab[ slot ].tempfile, "w" );
+        fputs( string, f );
+        fclose( f );
+
+        string = cmdtab[ slot ].tempfile;
+        
+        if( DEBUG_EXECCMD )
+        {
+            if (shell)
+                printf("using user-specified shell: %s", shell->string);
+            else
+                printf("Executing through .bat file\n");
+        }
+    }
+    else if( DEBUG_EXECCMD )
+    {
+        printf("Executing raw command directly\n");
+    }
+
+    /* Forumulate argv */
+    /* If shell was defined, be prepared for % and ! subs. */
+    /* Otherwise, use stock /bin/sh (on unix) or cmd.exe (on NT). */
+
+    if( shell )
+    {
+        int i;
+        char jobno[4];
+        int gotpercent = 0;
+
+        sprintf( jobno, "%d", slot + 1 );
+
+        for( i = 0; shell && i < MAXARGC; i++, shell = list_next( shell ) )
+        {
+            switch( shell->string[0] )
+            {
+            case '%':	argv[i] = string; gotpercent++; break;
+            case '!':	argv[i] = jobno; break;
+            default:	argv[i] = shell->string;
+            }
+            if( DEBUG_EXECCMD )
+                printf( "argv[%d] = '%s'\n", i, argv[i] );
+        }
+
+        if( !gotpercent )
+            argv[i++] = string;
+
+        argv[i] = 0;
+    }
+    else if (raw_cmd)
+    {
+        int ignored;
+        argv = string_to_args(string, &ignored);
+    }
+    else
+    {
+        /* don't worry, this is ignored on Win95/98, see later.. */
+        argv[0] = "cmd.exe";
+        argv[1] = "/Q/C";		/* anything more is non-portable */
+        argv[2] = string;
+        argv[3] = 0;
+    }
+
+    /* Catch interrupts whenever commands are running. */
+
+    if( !cmdsrunning++ )
+        istat = signal( SIGINT, onintr );
+
+    /* Start the command */
+
+    /* on Win95, we only do a synchronous call */
+    if ( is_win95 )
+    {
+        static const char* hard_coded[] =
+            {
+                "del", "erase", "copy", "mkdir", "rmdir", "cls", "dir",
+                "ren", "rename", "move", 0
+            };
+          
+        const char**  keyword;
+        int           len, spawn = 1;
+        int           result;
+          
+        for ( keyword = hard_coded; keyword[0]; keyword++ )
+        {
+            len = strlen( keyword[0] );
+            if ( strnicmp( string, keyword[0], len ) == 0 &&
+                 !isalnum(string[len]) )
+            {
+                /* this is one of the hard coded symbols, use 'system' to run */
+                /* them.. except for "del"/"erase"                            */
+                if ( keyword - hard_coded < 2 )
+                    result = process_del( string );
+                else
+                    result = system( string );
+
+                spawn  = 0;
+                break;
+            }
+        }
+          
+        if (spawn)
+        {
+            char**  args;
+            int     num_args;
+            
+            /* convert the string into an array of arguments */
+            /* we need to take care of double quotes !!      */
+            args = string_to_args( string, &num_args );
+            if ( args )
+            {
+#if 0
+                char** arg;
+                fprintf( stderr, "%s: ", args[0] );
+                arg = args+1;
+                while ( arg[0] )
+                {
+                    fprintf( stderr, " {%s}", arg[0] );
+                    arg++;
+                }
+                fprintf( stderr, "\n" );
+#endif              
+                result = spawnvp( P_WAIT, args[0], args );
+                free_args( args );
+            }
+            else
+                result = 1;
+        }
+        func( closure, result ? EXEC_CMD_FAIL : EXEC_CMD_OK );
+        return;
+    }
+
+    if( DEBUG_EXECCMD )
+    {
+        char **argp = argv;
+
+        printf("Executing command");
+        while(*argp != 0)
+        {
+            printf(" [%s]", *argp);
+            argp++;
+        }
+        printf("\n");
+    }
+
+    /* the rest is for Windows NT only */
+    /* spawn doesn't like quotes aroudn the command name */
+    if ( argv[0][0] == '"')
+    {
+        int l = strlen(argv[0]);
+        if (argv[0][l-1] == '"') argv[0][l-1] = '\0';
+        strcpy(argv[0],argv[0]+1);
+    }
+    if( ( pid = spawnvp( P_NOWAIT, argv[0], argv ) ) == -1 )
+    {
+        perror( "spawn" );
+        exit( EXITBAD );
+    }
+    /* Save the operation for execwait() to find. */
+
+    cmdtab[ slot ].pid = pid;
+    cmdtab[ slot ].func = func;
+    cmdtab[ slot ].closure = closure;
+
+    /* Wait until we're under the limit of concurrent commands. */
+    /* Don't trust globs.jobs alone.                            */
+
+    while( cmdsrunning >= MAXJOBS || cmdsrunning >= globs.jobs )
+        if( !execwait() )
+            break;
+    
+    if (argv != argv_static)
+    {
+        free_args(argv);
+    }
+}
+
+/*
+ * execwait() - wait and drive at most one execution completion
+ */
+
+int
+execwait()
+{
+	int i;
+	int status, w;
+	int rstat;
+
+	/* Handle naive make1() which doesn't know if cmds are running. */
+
+	if( !cmdsrunning )
+	    return 0;
+
+        if ( is_win95 )
+          return 0;
+          
+	/* Pick up process pid and status */
+    
+	while( ( w = wait( &status ) ) == -1 && errno == EINTR )
+		;
+
+	if( w == -1 )
+	{
+	    printf( "child process(es) lost!\n" );
+	    perror("wait");
+	    exit( EXITBAD );
+	}
+
+	/* Find the process in the cmdtab. */
+
+	for( i = 0; i < MAXJOBS; i++ )
+	    if( w == cmdtab[ i ].pid )
+		break;
+
+	if( i == MAXJOBS )
+	{
+	    printf( "waif child found!\n" );
+	    exit( EXITBAD );
+	}
+
+	/* Clear the temp file */
+    if ( cmdtab[i].tempfile )
+        unlink( cmdtab[ i ].tempfile );
+
+	/* Drive the completion */
+
+	if( !--cmdsrunning )
+	    signal( SIGINT, istat );
+
+	if( intr )
+	    rstat = EXEC_CMD_INTR;
+	else if( w == -1 || status != 0 )
+	    rstat = EXEC_CMD_FAIL;
+	else
+	    rstat = EXEC_CMD_OK;
+
+	cmdtab[ i ].pid = 0;
+	// SVA don't leak temp files
+	if(cmdtab[i].tempfile != NULL)
+	{
+            free(cmdtab[i].tempfile);
+            cmdtab[i].tempfile = NULL;
+	}
+	(*cmdtab[ i ].func)( cmdtab[ i ].closure, rstat );
+
+	return 1;
+}
+
+# if !defined( __BORLANDC__ )
+
+static int
+my_wait( int *status )
+{
+	int i, num_active = 0;
+	DWORD exitcode, waitcode;
+	static HANDLE *active_handles = 0;
+
+	if (!active_handles)
+	    active_handles = (HANDLE *)malloc(globs.jobs * sizeof(HANDLE) );
+
+	/* first see if any non-waited-for processes are dead,
+	 * and return if so.
+	 */
+	for ( i = 0; i < globs.jobs; i++ ) {
+	    if ( cmdtab[i].pid ) {
+		if ( GetExitCodeProcess((HANDLE)cmdtab[i].pid, &exitcode) ) {
+		    if ( exitcode == STILL_ACTIVE )
+			active_handles[num_active++] = (HANDLE)cmdtab[i].pid;
+		    else {
+			CloseHandle((HANDLE)cmdtab[i].pid);
+			*status = (int)((exitcode & 0xff) << 8);
+			return cmdtab[i].pid;
+		    }
+		}
+		else
+		    goto FAILED;
+	    }
+	}
+
+	/* if a child exists, wait for it to die */
+	if ( !num_active ) {
+	    errno = ECHILD;
+	    return -1;
+	}
+	waitcode = WaitForMultipleObjects( num_active,
+					   active_handles,
+					   FALSE,
+					   INFINITE );
+	if ( waitcode != WAIT_FAILED ) {
+	    if ( waitcode >= WAIT_ABANDONED_0
+		&& waitcode < WAIT_ABANDONED_0 + num_active )
+		i = waitcode - WAIT_ABANDONED_0;
+	    else
+		i = waitcode - WAIT_OBJECT_0;
+	    if ( GetExitCodeProcess(active_handles[i], &exitcode) ) {
+		CloseHandle(active_handles[i]);
+		*status = (int)((exitcode & 0xff) << 8);
+		return (int)active_handles[i];
+	    }
+	}
+
+FAILED:
+	errno = GetLastError();
+	return -1;
+    
+}
+
+# endif /* !__BORLANDC__ */
+
+# endif /* USE_EXECNT */

Added: boost-jam/boost-build/branches/upstream/current/jam_src/execunix.c
===================================================================
--- boost-jam/boost-build/branches/upstream/current/jam_src/execunix.c	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/jam_src/execunix.c	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,375 @@
+/*
+ * Copyright 1993, 1995 Christopher Seiwald.
+ *
+ * This file is part of Jam - see jam.c for Copyright information.
+ */
+
+# include "jam.h"
+# include "lists.h"
+# include "execcmd.h"
+# include <errno.h>
+
+#if defined(sun) || defined(__sun)
+#include <unistd.h> /* need to include unistd.h on sun for the vfork prototype*/
+#include <wait.h>
+#endif
+
+# ifdef USE_EXECUNIX
+
+# ifdef NO_VFORK
+# define vfork() fork()
+# endif
+
+# if defined( OS_NT ) || defined( OS_OS2 )
+
+# define USE_EXECNT
+
+# include <process.h>
+
+# if !defined( __BORLANDC__ ) && !defined( OS_OS2 )
+# define wait my_wait
+static int my_wait( int *status );
+# endif
+
+# endif
+
+/*
+ * execunix.c - execute a shell script on UNIX/WinNT/OS2/AmigaOS
+ *
+ * If $(JAMSHELL) is defined, uses that to formulate execvp()/spawnvp().
+ * The default is:
+ *
+ *	/bin/sh -c %		[ on UNIX/AmigaOS ]
+ *	cmd.exe /c %		[ on OS2/WinNT ]
+ *
+ * Each word must be an individual element in a jam variable value.
+ *
+ * In $(JAMSHELL), % expands to the command string and ! expands to 
+ * the slot number (starting at 1) for multiprocess (-j) invocations.
+ * If $(JAMSHELL) doesn't include a %, it is tacked on as the last
+ * argument.
+ *
+ * Don't just set JAMSHELL to /bin/sh or cmd.exe - it won't work!
+ *
+ * External routines:
+ *	execcmd() - launch an async command execution
+ * 	execwait() - wait and drive at most one execution completion
+ *
+ * Internal routines:
+ *	onintr() - bump intr to note command interruption
+ *
+ * 04/08/94 (seiwald) - Coherent/386 support added.
+ * 05/04/94 (seiwald) - async multiprocess interface
+ * 01/22/95 (seiwald) - $(JAMSHELL) support
+ * 06/02/97 (gsar)    - full async multiprocess support for Win32
+ */
+
+static int intr = 0;
+static int cmdsrunning = 0;
+static void (*istat)( int );
+
+static struct
+{
+	int	pid; /* on win32, a real process handle */
+	void	(*func)( void *closure, int status );
+	void 	*closure;
+
+# ifdef USE_EXECNT
+	char	*tempfile;
+# endif
+
+} cmdtab[ MAXJOBS ] = {{0}};
+
+/*
+ * onintr() - bump intr to note command interruption
+ */
+
+void
+onintr( int disp )
+{
+	intr++;
+	printf( "...interrupted\n" );
+}
+
+/*
+ * execcmd() - launch an async command execution
+ */
+
+void
+execcmd( 
+	char *string,
+	void (*func)( void *closure, int status ),
+	void *closure,
+	LIST *shell )
+{
+	int pid;
+	int slot;
+	char *argv[ MAXARGC + 1 ];	/* +1 for NULL */
+
+# ifdef USE_EXECNT
+	char *p;
+# endif
+
+	/* Find a slot in the running commands table for this one. */
+
+	for( slot = 0; slot < MAXJOBS; slot++ )
+	    if( !cmdtab[ slot ].pid )
+		break;
+
+	if( slot == MAXJOBS )
+	{
+	    printf( "no slots for child!\n" );
+	    exit( EXITBAD );
+	}
+
+# ifdef USE_EXECNT
+	if( !cmdtab[ slot ].tempfile )
+	{
+	    char *tempdir;
+
+	    if( !( tempdir = getenv( "TEMP" ) ) &&
+		!( tempdir = getenv( "TMP" ) ) )
+		    tempdir = "\\temp";
+
+	    cmdtab[ slot ].tempfile = malloc( strlen( tempdir ) + 14 );
+
+	    sprintf( cmdtab[ slot ].tempfile, "%s\\jamtmp%02d.bat", 
+				tempdir, slot );
+	}
+
+	/* Trim leading, ending white space */
+
+	while( isspace( *string ) )
+		++string;
+
+	p = strchr( string, '\n' );
+
+	while( p && isspace( *p ) )
+		++p;
+
+	/* If multi line, or too long, or JAMSHELL is set, write to bat file. */
+	/* Otherwise, exec directly. */
+	/* Frankly, if it is a single long line I don't think the */
+	/* command interpreter will do any better -- it will fail. */
+
+	if( p && *p || strlen( string ) > MAXLINE || shell )
+	{
+	    FILE *f;
+
+	    /* Write command to bat file. */
+
+	    f = fopen( cmdtab[ slot ].tempfile, "w" );
+	    fputs( string, f );
+	    fclose( f );
+
+	    string = cmdtab[ slot ].tempfile;
+	}
+# endif
+
+	/* Forumulate argv */
+	/* If shell was defined, be prepared for % and ! subs. */
+	/* Otherwise, use stock /bin/sh (on unix) or cmd.exe (on NT). */
+
+	if( shell )
+	{
+	    int i;
+	    char jobno[4];
+	    int gotpercent = 0;
+
+	    sprintf( jobno, "%d", slot + 1 );
+
+	    for( i = 0; shell && i < MAXARGC; i++, shell = list_next( shell ) )
+	    {
+		switch( shell->string[0] )
+		{
+		case '%':	argv[i] = string; gotpercent++; break;
+		case '!':	argv[i] = jobno; break;
+		default:	argv[i] = shell->string;
+		}
+		if( DEBUG_EXECCMD )
+		    printf( "argv[%d] = '%s'\n", i, argv[i] );
+	    }
+
+	    if( !gotpercent )
+		argv[i++] = string;
+
+	    argv[i] = 0;
+	}
+	else
+	{
+# ifdef USE_EXECNT
+	    argv[0] = "cmd.exe";
+	    argv[1] = "/Q/C";		/* anything more is non-portable */
+# else
+	    argv[0] = "/bin/sh";
+	    argv[1] = "-c";
+# endif
+	    argv[2] = string;
+	    argv[3] = 0;
+	}
+
+	/* Catch interrupts whenever commands are running. */
+
+	if( !cmdsrunning++ )
+	    istat = signal( SIGINT, onintr );
+
+	/* Start the command */
+
+# ifdef USE_EXECNT
+	if( ( pid = spawnvp( P_NOWAIT, argv[0], argv ) ) == -1 )
+	{
+	    perror( "spawn" );
+	    exit( EXITBAD );
+	}
+# else
+	if ((pid = vfork()) == 0) 
+   	{
+		execvp( argv[0], argv );
+		_exit(127);
+	}
+
+	if( pid == -1 )
+	{
+	    perror( "vfork" );
+	    exit( EXITBAD );
+	}
+# endif
+	/* Save the operation for execwait() to find. */
+
+	cmdtab[ slot ].pid = pid;
+	cmdtab[ slot ].func = func;
+	cmdtab[ slot ].closure = closure;
+
+	/* Wait until we're under the limit of concurrent commands. */
+	/* Don't trust globs.jobs alone. */
+
+	while( cmdsrunning >= MAXJOBS || cmdsrunning >= globs.jobs )
+	    if( !execwait() )
+		break;
+}
+
+/*
+ * execwait() - wait and drive at most one execution completion
+ */
+
+int
+execwait()
+{
+	int i;
+	int status, w;
+	int rstat;
+
+	/* Handle naive make1() which doesn't know if cmds are running. */
+
+	if( !cmdsrunning )
+	    return 0;
+
+	/* Pick up process pid and status */
+    
+	while( ( w = wait( &status ) ) == -1 && errno == EINTR )
+		;
+
+	if( w == -1 )
+	{
+	    printf( "child process(es) lost!\n" );
+	    perror("wait");
+	    exit( EXITBAD );
+	}
+
+	/* Find the process in the cmdtab. */
+
+	for( i = 0; i < MAXJOBS; i++ )
+	    if( w == cmdtab[ i ].pid )
+		break;
+
+	if( i == MAXJOBS )
+	{
+	    printf( "waif child found!\n" );
+	    exit( EXITBAD );
+	}
+
+	/* Drive the completion */
+
+	if( !--cmdsrunning )
+	    signal( SIGINT, istat );
+
+	if( intr )
+	    rstat = EXEC_CMD_INTR;
+	else if( w == -1 || status != 0 )
+	    rstat = EXEC_CMD_FAIL;
+	else
+	    rstat = EXEC_CMD_OK;
+
+	cmdtab[ i ].pid = 0;
+
+	(*cmdtab[ i ].func)( cmdtab[ i ].closure, rstat );
+
+	return 1;
+}
+
+# if defined( OS_NT ) && !defined( __BORLANDC__ )
+
+# define WIN32_LEAN_AND_MEAN
+
+# include <windows.h>		/* do the ugly deed */
+
+static int
+my_wait( int *status )
+{
+	int i, num_active = 0;
+	DWORD exitcode, waitcode;
+	static HANDLE *active_handles = 0;
+
+	if (!active_handles)
+	    active_handles = (HANDLE *)malloc(globs.jobs * sizeof(HANDLE) );
+
+	/* first see if any non-waited-for processes are dead,
+	 * and return if so.
+	 */
+	for ( i = 0; i < globs.jobs; i++ ) {
+	    if ( cmdtab[i].pid ) {
+		if ( GetExitCodeProcess((HANDLE)cmdtab[i].pid, &exitcode) ) {
+		    if ( exitcode == STILL_ACTIVE )
+			active_handles[num_active++] = (HANDLE)cmdtab[i].pid;
+		    else {
+			CloseHandle((HANDLE)cmdtab[i].pid);
+			*status = (int)((exitcode & 0xff) << 8);
+			return cmdtab[i].pid;
+		    }
+		}
+		else
+		    goto FAILED;
+	    }
+	}
+
+	/* if a child exists, wait for it to die */
+	if ( !num_active ) {
+	    errno = ECHILD;
+	    return -1;
+	}
+	waitcode = WaitForMultipleObjects( num_active,
+					   active_handles,
+					   FALSE,
+					   INFINITE );
+	if ( waitcode != WAIT_FAILED ) {
+	    if ( waitcode >= WAIT_ABANDONED_0
+		&& waitcode < WAIT_ABANDONED_0 + num_active )
+		i = waitcode - WAIT_ABANDONED_0;
+	    else
+		i = waitcode - WAIT_OBJECT_0;
+	    if ( GetExitCodeProcess(active_handles[i], &exitcode) ) {
+		CloseHandle(active_handles[i]);
+		*status = (int)((exitcode & 0xff) << 8);
+		return (int)active_handles[i];
+	    }
+	}
+
+FAILED:
+	errno = GetLastError();
+	return -1;
+    
+}
+
+# endif /* NT && !__BORLANDC__ */
+
+# endif /* USE_EXECUNIX */

Added: boost-jam/boost-build/branches/upstream/current/jam_src/execvms.c
===================================================================
--- boost-jam/boost-build/branches/upstream/current/jam_src/execvms.c	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/jam_src/execvms.c	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,167 @@
+/* 
+ * Copyright 1993, 1995 Christopher Seiwald.
+ *
+ * This file is part of Jam - see jam.c for Copyright information.
+ */
+
+# include "jam.h"
+# include "lists.h"
+# include "execcmd.h"
+
+# ifdef OS_VMS
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <iodef.h>
+#include <ssdef.h>
+#include <descrip.h>
+#include <dvidef.h>
+#include <clidef.h>
+
+/*
+ * execvms.c - execute a shell script, ala VMS
+ *
+ * The approach is this:
+ *
+ *	If the command is a single line, and shorter than WRTLEN (what we 
+ *	believe to be the maximum line length), we just system() it.
+ *
+ *	If the command is multi-line, or longer than WRTLEN, we write the 
+ *	command block to a temp file, splitting long lines (using "-" at 
+ *	the end of the line to indicate contiuation), and then source that 
+ *	temp file.  We use special logic to make sure we don't continue in
+ *	the middle of a quoted string.
+ *
+ * 05/04/94 (seiwald) - async multiprocess interface; noop on VMS
+ * 12/20/96 (seiwald) - rewritten to handle multi-line commands well
+ * 01/14/96 (seiwald) - don't put -'s between "'s
+ */
+
+#define WRTLEN 240
+
+#define MIN( a, b )	((a) < (b) ? (a) : (b))
+
+/* 1 for the @ and 4 for the .com */
+
+char tempnambuf[ L_tmpnam + 1 + 4 ] = {0};
+
+void
+execcmd( 
+	char *string,
+	void (*func)( void *closure, int status ),
+	void *closure,
+	LIST *shell )
+{
+	char *s, *e, *p;
+	int rstat = EXEC_CMD_OK;
+	int status;
+
+	/* See if string is more than one line */
+	/* discounting leading/trailing white space */
+
+	for( s = string; *s && isspace( *s ); s++ )
+		;
+
+	e = p = strchr( s, '\n' );
+
+	while( p && isspace( *p ) )
+		++p;
+
+	/* If multi line or long, write to com file. */
+	/* Otherwise, exec directly. */
+
+	if( p && *p || e - s > WRTLEN )
+	{
+	    FILE *f;
+
+	    /* Create temp file invocation "@sys$scratch:tempfile.com" */
+
+	    if( !*tempnambuf )
+	    {
+		tempnambuf[0] = '@';
+		(void)tmpnam( tempnambuf + 1 );
+		strcat( tempnambuf, ".com" );
+	    }
+	    
+	    /* Open tempfile */
+
+	    if( !( f = fopen( tempnambuf + 1, "w" ) ) )
+	    {
+		printf( "can't open command file\n" );
+		(*func)( closure, EXEC_CMD_FAIL );
+		return;
+	    }
+
+	    /* For each line of the string */
+
+	    while( *string )
+	    {
+		char *s = strchr( string, '\n' );
+		int len = s ? s + 1 - string : strlen( string );
+
+		fputc( '$', f );
+
+		/* For each chunk of a line that needs to be split */
+
+		while( len > 0 )
+		{
+		    char *q = string;
+		    char *qe = string + MIN( len, WRTLEN );
+		    char *qq = q;
+		    int quote = 0;
+
+		    /* Look for matching "'s */
+
+		    for( ; q < qe; q++ )
+			if( *q == '"' && ( quote = !quote ) )
+			    qq = q;
+
+		    /* Back up to opening quote, if in one */
+
+		    if( quote )
+			q = qq;
+
+		    fwrite( string, ( q - string ), 1, f );
+
+		    len -= ( q - string );
+		    string = q;
+
+		    if( len )
+		    {
+			fputc( '-', f );
+			fputc( '\n', f );
+		    }
+		}
+	    }
+
+	    fclose( f );
+
+	    status = system( tempnambuf ) & 0x07;
+
+	    unlink( tempnambuf + 1 );
+	}
+	else
+	{
+	    /* Execute single line command */
+	    /* Strip trailing newline before execing */
+	    if( e ) *e = 0;
+	    status = system( s ) & 0x07;
+	}
+
+	/* Fail for error or fatal error */
+	/* OK on OK, warning, or info exit */
+
+	if( status == 2 || status == 4 )
+	    rstat = EXEC_CMD_FAIL;
+
+	(*func)( closure, rstat );
+}
+
+int 
+execwait()
+{
+	return 0;
+}
+
+# endif /* VMS */

Added: boost-jam/boost-build/branches/upstream/current/jam_src/expand.c
===================================================================
--- boost-jam/boost-build/branches/upstream/current/jam_src/expand.c	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/jam_src/expand.c	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,710 @@
+# include "jam.h"
+# include "lists.h"
+# include "variable.h"
+# include "expand.h"
+# include "pathsys.h"
+# include "newstr.h"
+# include <assert.h>
+
+# ifdef OS_CYGWIN
+#  include <sys/cygwin.h>
+#  include <windows.h>
+# endif
+
+/*
+ * expand.c - expand a buffer, given variable values
+ *
+ * External routines:
+ *
+ *	var_expand() - variable-expand input string into list of strings
+ *
+ * Internal routines:
+ *
+ *	var_edit_parse() - parse : modifiers into PATHNAME structure
+ *	var_edit_file() - copy input target name to output, modifying filename
+ *	var_edit_shift() - do upshift/downshift mods
+ *
+ * 01/25/94 (seiwald) - $(X)$(UNDEF) was expanding like plain $(X)
+ * 04/13/94 (seiwald) - added shorthand L0 for null list pointer
+ * 01/11/01 (seiwald) - added support for :E=emptyvalue, :J=joinval
+ */
+
+typedef struct {
+	PATHNAME	f;		/* :GDBSMR -- pieces */
+	char		parent;		/* :P -- go to parent directory */
+	char		filemods;	/* one of the above applied */
+	char		downshift;	/* :L -- downshift result */
+	char		upshift;	     /* :U -- upshift result */
+    char        to_slashes;    /* :T -- convert "\" to "/" */
+    char        to_windows;    /* :W -- convert cygwin to native paths */
+	PATHPART	empty;		/* :E -- default for empties */
+	PATHPART	join;		/* :J -- join list with char */
+} VAR_EDITS ;
+
+static void var_edit_parse( char *mods, VAR_EDITS *edits );
+static void var_edit_file( char *in, string *out, VAR_EDITS *edits );
+static void var_edit_shift( string *out, VAR_EDITS *edits );
+
+# define MAGIC_COLON	'\001'
+# define MAGIC_LEFT	'\002'
+# define MAGIC_RIGHT	'\003'
+
+/*
+ * var_expand() - variable-expand input string into list of strings
+ *
+ * Would just copy input to output, performing variable expansion, 
+ * except that since variables can contain multiple values the result
+ * of variable expansion may contain multiple values (a list).  Properly
+ * performs "product" operations that occur in "$(var1)xxx$(var2)" or
+ * even "$($(var2))".
+ *
+ * Returns a newly created list.
+ */
+
+LIST *
+var_expand( 
+	LIST	*l,
+	char	*in,
+	char	*end,
+	LOL	*lol,
+	int	cancopyin )
+{
+    char out_buf[ MAXSYM ];
+    string buf[1];
+    string out1[1]; /* Temporary buffer */
+    size_t prefix_length;
+    char *out;
+    char *inp = in;
+    char *ov;		/* for temp copy of variable in outbuf */
+    int depth;
+
+    if( DEBUG_VAREXP )
+        printf( "expand '%.*s'\n", end - in, in );
+
+    /* This gets alot of cases: $(<) and $(>) */
+
+    if( in[0] == '$' && in[1] == '(' && in[3] == ')' && !in[4] )
+    {
+        switch( in[2] )
+        {
+        case '1':
+        case '<':
+            return list_copy( l, lol_get( lol, 0 ) );
+
+        case '2':
+        case '>':
+            return list_copy( l, lol_get( lol, 1 ) );
+        }
+    }
+
+    /* Just try simple copy of in to out. */
+
+    while( in < end )
+        if( *in++ == '$' && *in == '(' ) 
+            goto expand;
+
+    /* No variables expanded - just add copy of input string to list. */
+
+    /* Cancopyin is an optimization: if the input was already a list */
+    /* item, we can use the copystr() to put it on the new list. */
+    /* Otherwise, we use the slower newstr(). */
+
+    if( cancopyin ) 
+    {
+        return list_new( l, copystr( inp ) );
+    }
+    else
+    {
+        LIST* r;
+        string_new( buf );
+        string_append_range( buf, inp, end );
+
+        r = list_new( l, newstr( buf->value) );
+        string_free( buf );
+        return r;
+    }
+
+expand:
+    string_new( buf );
+    string_append_range( buf, inp, in - 1); /* copy the part before '$'. */
+    /*
+     * Input so far (ignore blanks):
+     *
+     *	stuff-in-outbuf $(variable) remainder
+     *			 ^	             ^
+     *			 in		     end
+     * Output so far:
+     *
+     *	stuff-in-outbuf $
+     *	^	         ^
+     *	out_buf          out
+     *
+     *
+     * We just copied the $ of $(...), so back up one on the output.
+     * We now find the matching close paren, copying the variable and
+     * modifiers between the $( and ) temporarily into out_buf, so that
+     * we can replace :'s with MAGIC_COLON.  This is necessary to avoid
+     * being confused by modifier values that are variables containing
+     * :'s.  Ugly.
+     */
+
+    depth = 1;
+    inp = ++in; /* skip over the '(' */
+
+    while( in < end && depth )
+    {
+        switch( *in++ )
+        {
+        case '(': depth++; break;
+        case ')': depth--; break;
+        }
+    }
+
+    /*
+     * Input so far (ignore blanks):
+     *
+     *	stuff-in-outbuf $(variable) remainder
+     *			  ^	   ^         ^
+     *			  inp      in        end
+     */
+    prefix_length = buf->size;
+    string_append_range( buf, inp, in - 1 );
+
+    out = buf->value + prefix_length;
+    for ( ov = out; ov < buf->value + buf->size; ++ov )
+    {
+        switch( *ov )
+        {
+        case ':': *ov = MAGIC_COLON; break;
+        case '[': *ov = MAGIC_LEFT; break;
+        case ']': *ov = MAGIC_RIGHT; break;
+        }
+    }
+
+    /*
+     * Input so far (ignore blanks):
+     *
+     *	stuff-in-outbuf $(variable) remainder
+     *			            ^        ^
+     *			            in       end
+     * Output so far:
+     *
+     *	stuff-in-outbuf variable
+     *	^	        ^       ^
+     *	out_buf         out	ov
+     *
+     * Later we will overwrite 'variable' in out_buf, but we'll be
+     * done with it by then.  'variable' may be a multi-element list, 
+     * so may each value for '$(variable element)', and so may 'remainder'.
+     * Thus we produce a product of three lists.
+     */
+
+    {
+        LIST *variables = 0;
+        LIST *remainder = 0;
+        LIST *vars;
+
+        /* Recursively expand variable name & rest of input */
+
+        if( out < ov )
+            variables = var_expand( L0, out, ov, lol, 0 );
+        if( in < end )
+            remainder = var_expand( L0, in, end, lol, 0 );
+
+        /* Now produce the result chain */
+
+        /* For each variable name */
+
+        for( vars = variables; vars; vars = list_next( vars ) )
+        {
+            LIST *value, *evalue = 0;
+            char *colon;
+            char *bracket;
+            string variable[1];
+            char *varname;
+            int sub1 = 0, sub2 = -1;
+            VAR_EDITS edits;
+
+            /* Look for a : modifier in the variable name */
+            /* Must copy into varname so we can modify it */
+
+            string_copy( variable, vars->string );
+            varname = variable->value;
+
+            if( colon = strchr( varname, MAGIC_COLON ) )
+            {
+                string_truncate( variable, colon - varname );
+                var_edit_parse( colon + 1, &edits );
+            }
+
+            /* Look for [x-y] subscripting */
+            /* sub1 and sub2 are x and y. */
+
+            if ( bracket = strchr( varname, MAGIC_LEFT ) )
+            {
+                /*
+                ** Make all syntax errors in [] subscripting
+                ** result in the same behavior: silenty return an empty
+                ** expansion (by setting sub2 = 0). Brute force parsing;
+                ** May get moved into yacc someday.
+                */
+
+                char *s = bracket + 1;
+
+                string_truncate( variable, bracket - varname );
+
+                do  /* so we can use "break" */
+                {
+                    /* Allow negative indexes. */
+                    if (! isdigit( *s ) && ! ( *s == '-') )
+                    {
+                        sub2 = 0;
+                        break;
+                    }
+                    sub1 = atoi(s);
+
+                    /* Skip over the first symbol, which is either a digit or dash. */
+                    s++;
+                    while ( isdigit( *s ) ) s++;
+
+                    if ( *s == MAGIC_RIGHT )
+                    {
+                        sub2 = sub1;
+                        break;
+                    }
+
+                    if ( *s != '-')
+                    {
+                        sub2 = 0;
+                        break;
+                    }
+
+                    s++;
+
+                    if ( *s == MAGIC_RIGHT )
+                    {
+                        sub2 = -1;
+                        break;
+                    }
+
+                    if (! isdigit( *s ) && ! ( *s == '-') )
+                    {
+                        sub2 = 0;
+                        break;
+                    }
+
+                    /* First, compute the index of the last element. */
+                    sub2 = atoi(s);               
+                    s++;
+                    while ( isdigit( *s ) ) s++;
+
+                    if ( *s != MAGIC_RIGHT)
+                        sub2 = 0;
+
+                } while (0);
+
+                /*
+                ** Anything but the end of the string, or the colon
+                ** introducing a modifier is a syntax error.
+                */
+
+                s++;                
+                if (*s && *s != MAGIC_COLON)
+                    sub2 = 0;
+
+                *bracket = '\0';
+            }
+
+            /* Get variable value, specially handling $(<), $(>), $(n) */
+		
+            if( varname[0] == '<' && !varname[1] )
+                value = lol_get( lol, 0 );
+            else if( varname[0] == '>' && !varname[1] )
+                value = lol_get( lol, 1 );
+            else if( varname[0] >= '1' && varname[0] <= '9' && !varname[1] )
+                value = lol_get( lol, varname[0] - '1' );
+            else 
+                value = var_get( varname );
+
+            /* Handle negitive indexes: part two. */
+            {
+                int length = list_length( value );
+
+                if (sub1 < 0)
+                    sub1 = length + sub1;
+                else
+                    sub1 -= 1;
+
+                if (sub2 < 0)
+                    sub2 = length + 1 + sub2 - sub1;
+                else
+                    sub2 -= sub1;
+                /*
+                ** The "sub2 < 0" test handles the semantic error
+                ** of sub2 < sub1.
+                */
+                if ( sub2 < 0 )
+                    sub2 = 0;
+            }
+
+
+
+            /* The fast path: $(x) - just copy the variable value. */
+            /* This is only an optimization */
+
+            if( out == out_buf && !bracket && !colon && in == end )
+            {
+                string_free( variable );
+                l = list_copy( l, value );
+                continue;
+            }
+
+            /* Handle start subscript */
+
+            while( sub1 > 0 && value )
+                --sub1, value = list_next( value );
+
+            /* Empty w/ :E=default? */
+
+            if( !value && colon && edits.empty.ptr )
+                evalue = value = list_new( L0, newstr( edits.empty.ptr ) );
+
+            /* For each variable value */
+
+            string_new( out1 );
+            for( ; value; value = list_next( value ) )
+            {
+                LIST *rem;
+                size_t postfix_start;
+
+                /* Handle end subscript (length actually) */
+
+                if( sub2 >= 0 && --sub2 < 0 )
+                    break;
+
+                string_truncate( buf, prefix_length );
+
+                /* Apply : mods, if present */
+
+                if( colon && edits.filemods )
+                    var_edit_file( value->string, out1, &edits );
+                else
+                    string_append( out1, value->string );
+
+                if( colon && ( edits.upshift || edits.downshift || edits.to_slashes || edits.to_windows ) )
+                    var_edit_shift( out1, &edits );
+
+                /* Handle :J=joinval */
+                /* If we have more values for this var, just */
+                /* keep appending them (with the join value) */
+                /* rather than creating separate LIST elements. */
+
+                if( colon && edits.join.ptr && 
+                    ( list_next( value ) || list_next( vars ) ) )
+                {
+                    string_append( out1, edits.join.ptr );
+                    continue;
+                }
+
+                string_append( buf, out1->value );
+                string_free( out1 );
+                string_new( out1 );
+
+                /* If no remainder, append result to output chain. */
+
+                if( in == end )
+                {
+                    l = list_new( l, newstr( buf->value ) );
+                    continue;
+                }
+
+                /* For each remainder, append the complete string */
+                /* to the output chain. */
+                /* Remember the end of the variable expansion so */
+                /* we can just tack on each instance of 'remainder' */
+
+                postfix_start = buf->size;
+
+                for( rem = remainder; rem; rem = list_next( rem ) )
+                {
+                    string_truncate( buf, postfix_start );
+                    string_append( buf, rem->string );
+                    l = list_new( l, newstr( buf->value ) );
+                }
+            }
+            string_free( out1 );
+
+            /* Toss used empty */
+
+            if( evalue )
+                list_free( evalue );
+
+            string_free( variable );
+        }
+
+        /* variables & remainder were gifts from var_expand */
+        /* and must be freed */
+
+        if( variables )
+            list_free( variables );
+        if( remainder)
+            list_free( remainder );
+
+        if( DEBUG_VAREXP )
+        {
+            printf( "expanded to " );
+            list_print( l );
+            printf( "\n" );
+        }
+
+        string_free( buf );
+        return l;
+    }
+}
+
+/*
+ * var_edit_parse() - parse : modifiers into PATHNAME structure
+ *
+ * The : modifiers in a $(varname:modifier) currently support replacing
+ * or omitting elements of a filename, and so they are parsed into a 
+ * PATHNAME structure (which contains pointers into the original string).
+ *
+ * Modifiers of the form "X=value" replace the component X with
+ * the given value.  Modifiers without the "=value" cause everything 
+ * but the component X to be omitted.  X is one of:
+ *
+ *	G <grist>
+ *	D directory name
+ *	B base name
+ *	S .suffix
+ *	M (member)
+ *	R root directory - prepended to whole path
+ *
+ * This routine sets:
+ *
+ *	f->f_xxx.ptr = 0
+ *	f->f_xxx.len = 0
+ *		-> leave the original component xxx
+ *
+ *	f->f_xxx.ptr = string
+ *	f->f_xxx.len = strlen( string )
+ *		-> replace component xxx with string
+ *
+ *	f->f_xxx.ptr = ""
+ *	f->f_xxx.len = 0
+ *		-> omit component xxx
+ *
+ * var_edit_file() below and path_build() obligingly follow this convention.
+ */
+
+static void
+var_edit_parse(
+	char		*mods,
+	VAR_EDITS	*edits )
+{
+	int havezeroed = 0;
+	memset( (char *)edits, 0, sizeof( *edits ) );
+
+	while( *mods )
+	{
+	    char *p;
+	    PATHPART *fp;
+
+	    switch( *mods++ )
+	    {
+	    case 'L': edits->downshift = 1; continue;
+	    case 'U': edits->upshift = 1; continue;
+	    case 'P': edits->parent = edits->filemods = 1; continue;
+	    case 'E': fp = &edits->empty; goto strval;
+	    case 'J': fp = &edits->join; goto strval;
+	    case 'G': fp = &edits->f.f_grist; goto fileval;
+	    case 'R': fp = &edits->f.f_root; goto fileval;
+	    case 'D': fp = &edits->f.f_dir; goto fileval;
+	    case 'B': fp = &edits->f.f_base; goto fileval;
+	    case 'S': fp = &edits->f.f_suffix; goto fileval;
+	    case 'M': fp = &edits->f.f_member; goto fileval;
+            case 'T': edits->to_slashes = 1; continue;
+            case 'W': edits->to_windows = 1; continue;
+
+	    default: return; /* should complain, but so what... */
+	    }
+
+	fileval:
+
+	    /* Handle :CHARS, where each char (without a following =) */
+	    /* selects a particular file path element.  On the first such */
+	    /* char, we deselect all others (by setting ptr = "", len = 0) */
+	    /* and for each char we select that element (by setting ptr = 0) */
+
+	    edits->filemods = 1;
+
+	    if( *mods != '=' )
+	    {
+		int i;
+
+		if( !havezeroed++ )
+		    for( i = 0; i < 6; i++ )
+		{
+		    edits->f.part[ i ].len = 0;
+		    edits->f.part[ i ].ptr = "";
+		}
+
+		fp->ptr = 0;
+		continue;
+	    }
+
+	strval:
+
+	    /* Handle :X=value, or :X */
+
+	    if( *mods != '=' )
+	    {
+		fp->ptr = "";
+		fp->len = 0;
+	    }
+	    else if( p = strchr( mods, MAGIC_COLON ) )
+	    {
+		*p = 0;
+		fp->ptr = ++mods;
+		fp->len = p - mods;
+		mods = p + 1;
+	    }
+	    else
+	    {
+		fp->ptr = ++mods;
+		fp->len = strlen( mods );
+		mods += fp->len;
+	    }
+	}
+}
+
+/*
+ * var_edit_file() - copy input target name to output, modifying filename
+ */
+	
+static void
+var_edit_file( 
+	char	*in,
+	string	*out,
+	VAR_EDITS *edits )
+{
+	PATHNAME pathname;
+
+	/* Parse apart original filename, putting parts into "pathname" */
+
+	path_parse( in, &pathname );
+
+	/* Replace any pathname with edits->f */
+
+	if( edits->f.f_grist.ptr )
+	    pathname.f_grist = edits->f.f_grist;
+
+	if( edits->f.f_root.ptr )
+	    pathname.f_root = edits->f.f_root;
+
+	if( edits->f.f_dir.ptr )
+	    pathname.f_dir = edits->f.f_dir;
+
+	if( edits->f.f_base.ptr )
+	    pathname.f_base = edits->f.f_base;
+
+	if( edits->f.f_suffix.ptr )
+	    pathname.f_suffix = edits->f.f_suffix;
+
+	if( edits->f.f_member.ptr )
+	    pathname.f_member = edits->f.f_member;
+
+	/* If requested, modify pathname to point to parent */
+
+	if( edits->parent )
+	    path_parent( &pathname );
+
+	/* Put filename back together */
+
+    path_build( &pathname, out, 0 );
+}
+
+/*
+ * var_edit_shift() - do upshift/downshift mods
+ */
+
+static void
+var_edit_shift( 
+	string	*out,
+	VAR_EDITS *edits )
+{
+	/* Handle upshifting, downshifting and slash translation now */
+
+    char *p;
+    for ( p = out->value; *p; ++p)
+    {
+        if (edits->upshift)
+        {
+            *p = toupper( *p );
+        }
+        else if ( edits->downshift )
+        {
+            *p = tolower( *p );
+        } 
+        if ( edits->to_slashes )
+        {
+            if ( *p == '\\')
+                *p = '/';
+        }
+# ifdef OS_CYGWIN
+        if ( edits->to_windows )
+        {
+            char result[MAX_PATH + 1];
+            cygwin_conv_to_win32_path(out->value, result);
+            assert(strlen(result) <= MAX_PATH);
+            string_free( out );
+            string_copy( out, result );
+        }
+# endif
+    }
+    out->size = p - out->value;
+}
+
+#ifndef NDEBUG
+void var_expand_unit_test()
+{
+    LOL lol[1];
+    LIST* l, *l2;
+    LIST *expected = list_new( list_new( L0, newstr( "axb" ) ), newstr( "ayb" ) );
+    LIST *e2;
+    char axyb[] = "a$(xy)b";
+    char azb[] = "a$($(z))b";
+    char path[] = "$(p:W)";
+        
+    lol_init(lol);
+    var_set("xy", list_new( list_new( L0, newstr( "x" ) ), newstr( "y" ) ), VAR_SET );
+    var_set("z", list_new( L0, newstr( "xy" ) ), VAR_SET );
+    var_set("p", list_new( L0, newstr( "/cygdrive/c/foo/bar" ) ), VAR_SET );
+
+    l = var_expand( 0, axyb, axyb + sizeof(axyb) - 1, lol, 0 );
+    for ( l2 = l, e2 = expected; l2 && e2; l2 = list_next(l2), e2 = list_next(e2) )
+        assert( !strcmp( e2->string, l2->string ) );
+    assert(l2 == 0 && e2 == 0);
+    list_free(l);
+    
+    l = var_expand( 0, azb, azb + sizeof(azb) - 1, lol, 0 );
+    for ( l2 = l, e2 = expected; l2 && e2; l2 = list_next(l2), e2 = list_next(e2) )
+        assert( !strcmp( e2->string, l2->string ) );
+    assert(l2 == 0 && e2 == 0);
+    list_free(l);
+
+    l = var_expand( 0, path, path + sizeof(path) - 1, lol, 0 );
+    assert(l != 0);
+    assert(list_next(l) == 0);
+# ifdef OS_CYGWIN
+    assert( !strcmp( l->string, "c:\\foo\\bar" ) );
+# else 
+    assert( !strcmp( l->string, "/cygdrive/c/foo/bar" ) );
+# endif   
+    list_free(l);
+
+    list_free(expected);
+    
+    lol_free(lol);
+}
+#endif

Added: boost-jam/boost-build/branches/upstream/current/jam_src/expand.h
===================================================================
--- boost-jam/boost-build/branches/upstream/current/jam_src/expand.h	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/jam_src/expand.h	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,14 @@
+/*
+ * Copyright 1993, 1995 Christopher Seiwald.
+ *
+ * This file is part of Jam - see jam.c for Copyright information.
+ */
+
+/*
+ * expand.h - expand a buffer, given variable values
+ */
+
+#include "lists.h"
+
+LIST *var_expand( LIST	*l, char *in, char *end, LOL *lol, int cancopyin );
+void var_expand_unit_test();

Added: boost-jam/boost-build/branches/upstream/current/jam_src/filemac.c
===================================================================
--- boost-jam/boost-build/branches/upstream/current/jam_src/filemac.c	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/jam_src/filemac.c	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,173 @@
+/*
+ * Copyright 1993-2002 Christopher Seiwald and Perforce Software, Inc.
+ *
+ * This file is part of Jam - see jam.c for Copyright information.
+ */
+ 
+/*  This file is ALSO:
+ *  Copyright 2001-2004 David Abrahams.
+ *  Distributed under the Boost Software License, Version 1.0.
+ *  (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+ */
+
+# include "jam.h"
+# include "filesys.h"
+# include "pathsys.h"
+
+# ifdef OS_MAC
+
+#include <Files.h>
+#include <Folders.h>
+
+# include <:sys:stat.h>
+
+/*
+ * filemac.c - manipulate file names and scan directories on macintosh
+ *
+ * External routines:
+ *
+ *	file_dirscan() - scan a directory for files
+ *	file_time() - get timestamp of file, if not done by file_dirscan()
+ *	file_archscan() - scan an archive for files
+ *
+ * File_dirscan() and file_archscan() call back a caller provided function
+ * for each file found.  A flag to this callback function lets file_dirscan()
+ * and file_archscan() indicate that a timestamp is being provided with the
+ * file.   If file_dirscan() or file_archscan() do not provide the file's
+ * timestamp, interested parties may later call file_time().
+ *
+ * 04/08/94 (seiwald) - Coherent/386 support added.
+ * 12/19/94 (mikem) - solaris string table insanity support
+ * 02/14/95 (seiwald) - parse and build /xxx properly
+ * 05/03/96 (seiwald) - split into pathunix.c
+ * 11/21/96 (peterk) - BEOS does not have Unix-style archives
+ */
+
+void CopyC2PStr(const char * cstr, StringPtr pstr)
+{
+	int	len;
+	
+	for (len = 0; *cstr && len<255; pstr[++len] = *cstr++)
+		;
+	
+	pstr[0] = len;
+}
+
+/*
+ * file_dirscan() - scan a directory for files
+ */
+
+void
+file_dirscan( 
+	char	*dir,
+	scanback func,
+	void	*closure )
+{
+    PATHNAME f;
+    string filename[1];
+    unsigned char fullPath[ 512 ];
+
+    FSSpec spec;
+    WDPBRec vol;
+    Str63 volName;	
+    CInfoPBRec lastInfo;
+    int index = 1;
+	
+    /* First enter directory itself */
+
+    memset( (char *)&f, '\0', sizeof( f ) );
+
+    f.f_dir.ptr = dir;
+    f.f_dir.len = strlen(dir);
+
+    if( DEBUG_BINDSCAN )
+        printf( "scan directory %s\n", dir );
+		
+    /* Special case ":" - enter it */
+
+    if( f.f_dir.len == 1 && f.f_dir.ptr[0] == ':' )
+	    (*func)( closure, dir, 0 /* not stat()'ed */, (time_t)0 );
+
+    /* Now enter contents of directory */
+
+    vol.ioNamePtr = volName;
+	
+    if( PBHGetVolSync( &vol ) )
+        return;
+
+    CopyC2PStr( dir, fullPath );
+	
+    if( FSMakeFSSpec( vol.ioWDVRefNum, vol.ioWDDirID, fullPath, &spec ) )
+        return;
+	
+    lastInfo.dirInfo.ioVRefNum 	= spec.vRefNum;
+    lastInfo.dirInfo.ioDrDirID 	= spec.parID;
+    lastInfo.dirInfo.ioNamePtr 	= spec.name;
+    lastInfo.dirInfo.ioFDirIndex 	= 0;
+    lastInfo.dirInfo.ioACUser 	= 0;
+			
+    if( PBGetCatInfoSync(&lastInfo) )
+        return;
+
+    if (!(lastInfo.dirInfo.ioFlAttrib & 0x10))
+        return;
+
+    // ioDrDirID must be reset each time.
+	
+    spec.parID = lastInfo.dirInfo.ioDrDirID;
+
+    string_new( filename );
+    for( ;; )
+    {
+        lastInfo.dirInfo.ioVRefNum 	= spec.vRefNum;
+        lastInfo.dirInfo.ioDrDirID	= spec.parID;
+        lastInfo.dirInfo.ioNamePtr 	= fullPath;
+        lastInfo.dirInfo.ioFDirIndex = index++;
+	   		
+        if( PBGetCatInfoSync(&lastInfo) )
+            return;
+			
+        f.f_base.ptr = (char *)fullPath + 1;
+        f.f_base.len = *fullPath;
+
+        string_truncate( filename, 0 );
+        path_build( &f, filename, 0 );
+        (*func)( closure, filename->value, 0 /* not stat()'ed */, (time_t)0 );
+    }
+    string_free( filename );
+}
+
+/*
+ * file_time() - get timestamp of file, if not done by file_dirscan()
+ */
+
+int
+file_time( 
+	char	*filename,
+	time_t	*time )
+{
+	struct stat statbuf;
+
+	if( stat( filename, &statbuf ) < 0 )
+	    return -1;
+
+	*time = statbuf.st_mtime;
+	
+	return 0;
+}
+
+/*
+ * file_archscan() - scan an archive for files
+ */
+
+void
+file_archscan(
+	char 	*archive,
+	scanback func,
+	void	*closure )
+{
+}
+
+
+# endif /* macintosh */
+

Added: boost-jam/boost-build/branches/upstream/current/jam_src/filent.c
===================================================================
--- boost-jam/boost-build/branches/upstream/current/jam_src/filent.c	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/jam_src/filent.c	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,287 @@
+/*
+ * Copyright 1993, 1995 Christopher Seiwald.
+ *
+ * This file is part of Jam - see jam.c for Copyright information.
+ */
+
+/*  This file is ALSO:
+ *  Copyright 2001-2004 David Abrahams.
+ *  Distributed under the Boost Software License, Version 1.0.
+ *  (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+ */
+
+# include "jam.h"
+# include "filesys.h"
+# include "pathsys.h"
+# include "strings.h"
+
+# ifdef OS_NT
+
+# ifdef __BORLANDC__
+# if __BORLANDC__ < 0x550
+# include <dir.h>
+# include <dos.h>
+# endif
+# undef FILENAME	/* cpp namespace collision */
+# define _finddata_t ffblk
+# endif
+
+# include <io.h>
+# include <sys/stat.h>
+# include <ctype.h>
+
+/*
+ * filent.c - scan directories and archives on NT
+ *
+ * External routines:
+ *
+ *	file_dirscan() - scan a directory for files
+ *	file_time() - get timestamp of file, if not done by file_dirscan()
+ *	file_archscan() - scan an archive for files
+ *
+ * File_dirscan() and file_archscan() call back a caller provided function
+ * for each file found.  A flag to this callback function lets file_dirscan()
+ * and file_archscan() indicate that a timestamp is being provided with the
+ * file.   If file_dirscan() or file_archscan() do not provide the file's
+ * timestamp, interested parties may later call file_time().
+ *
+ * 07/10/95 (taylor)  Findfirst() returns the first file on NT.
+ * 05/03/96 (seiwald) split apart into pathnt.c
+ */
+
+/*
+ * file_dirscan() - scan a directory for files
+ */
+
+void
+file_dirscan( 
+	char *dir,
+	scanback func,
+	void *closure )
+{
+    PATHNAME f;
+    string filespec[1];
+    string filename[1];
+    long handle;
+    int ret;
+    struct _finddata_t finfo[1];
+
+    dir = short_path_to_long_path( dir );
+	
+    /* First enter directory itself */
+
+    memset( (char *)&f, '\0', sizeof( f ) );
+
+    f.f_dir.ptr = dir;
+    f.f_dir.len = strlen(dir);
+
+    dir = *dir ? dir : ".";
+
+    /* Special case \ or d:\ : enter it */
+ 
+    if( f.f_dir.len == 1 && f.f_dir.ptr[0] == '\\' )
+        (*func)( closure, dir, 0 /* not stat()'ed */, (time_t)0 );
+    else if( f.f_dir.len == 3 && f.f_dir.ptr[1] == ':' )
+        (*func)( closure, dir, 0 /* not stat()'ed */, (time_t)0 );
+
+    /* Now enter contents of directory */
+
+    string_copy( filespec, dir );
+    string_append( filespec, "/*" );
+
+    if( DEBUG_BINDSCAN )
+        printf( "scan directory %s\n", dir );
+
+# if defined(__BORLANDC__) && __BORLANDC__ < 0x550
+    if ( ret = findfirst( filespec->value, finfo, FA_NORMAL | FA_DIREC ) )
+    {
+        string_free( filespec );
+        return;
+    }
+
+    string_new( filename );
+    while( !ret )
+    {
+        time_t time_write = finfo->ff_fdate;
+
+        time_write = (time_write << 16) | finfo->ff_ftime;
+        f.f_base.ptr = finfo->ff_name;
+        f.f_base.len = strlen( finfo->ff_name );
+
+        string_truncate( filename, 0 );
+        path_build( &f, filename );
+
+        (*func)( closure, filename->value, 1 /* stat()'ed */, time_write );
+
+        ret = findnext( finfo );
+    }
+# else
+    handle = _findfirst( filespec->value, finfo );
+
+    if( ret = ( handle < 0L ) )
+    {
+        string_free( filespec );
+        return;
+    }
+        
+    string_new( filename );
+    while( !ret )
+    {
+        f.f_base.ptr = finfo->name;
+        f.f_base.len = strlen( finfo->name );
+
+        string_truncate( filename, 0 );
+        path_build( &f, filename, 0 );
+
+        (*func)( closure, filename->value, 1 /* stat()'ed */, finfo->time_write );
+ 
+        ret = _findnext( handle, finfo );
+    }
+
+    _findclose( handle );
+# endif
+    string_free( filename );
+    string_free( filespec );
+}
+
+/*
+ * file_time() - get timestamp of file, if not done by file_dirscan()
+ */
+
+int
+file_time(
+	char	*filename,
+	time_t	*time )
+{
+	/* On NT this is called only for C:/ */
+
+	struct stat statbuf;
+
+	if( stat( filename, &statbuf ) < 0 )
+	    return -1;
+
+	*time = statbuf.st_mtime;
+
+	return 0;
+}
+
+/*
+ * file_archscan() - scan an archive for files
+ */
+
+/* Straight from SunOS */
+
+#define	ARMAG	"!<arch>\n"
+#define	SARMAG	8
+
+#define	ARFMAG	"`\n"
+
+struct ar_hdr {
+	char	ar_name[16];
+	char	ar_date[12];
+	char	ar_uid[6];
+	char	ar_gid[6];
+	char	ar_mode[8];
+	char	ar_size[10];
+	char	ar_fmag[2];
+};
+
+# define SARFMAG 2
+# define SARHDR sizeof( struct ar_hdr )
+
+void
+file_archscan(
+	char *archive,
+	scanback func,
+	void *closure )
+{
+	struct ar_hdr ar_hdr;
+	char *string_table = 0;
+	char buf[ MAXJPATH ];
+	long offset;
+	int fd;
+
+	if( ( fd = open( archive, O_RDONLY | O_BINARY, 0 ) ) < 0 )
+	    return;
+
+	if( read( fd, buf, SARMAG ) != SARMAG ||
+	    strncmp( ARMAG, buf, SARMAG ) )
+	{
+	    close( fd );
+	    return;
+	}
+
+	offset = SARMAG;
+
+	if( DEBUG_BINDSCAN )
+	    printf( "scan archive %s\n", archive );
+
+	while( read( fd, &ar_hdr, SARHDR ) == SARHDR &&
+	       !memcmp( ar_hdr.ar_fmag, ARFMAG, SARFMAG ) )
+	{
+	    long    lar_date;
+	    long    lar_size;
+	    char    *name = 0;
+ 	    char    *endname;
+	    char    *c;
+
+	    sscanf( ar_hdr.ar_date, "%ld", &lar_date );
+	    sscanf( ar_hdr.ar_size, "%ld", &lar_size );
+
+	    lar_size = ( lar_size + 1 ) & ~1;
+
+	    if (ar_hdr.ar_name[0] == '/' && ar_hdr.ar_name[1] == '/' )
+	    {
+		/* this is the "string table" entry of the symbol table,
+		** which holds strings of filenames that are longer than
+		** 15 characters (ie. don't fit into a ar_name
+		*/
+
+		string_table = malloc(lar_size);
+		if (read(fd, string_table, lar_size) != lar_size)
+		    printf("error reading string table\n");
+		offset += SARHDR + lar_size;
+		continue;
+	    }
+	    else if (ar_hdr.ar_name[0] == '/' && ar_hdr.ar_name[1] != ' ')
+	    {
+		/* Long filenames are recognized by "/nnnn" where nnnn is
+		** the offset of the string in the string table represented
+		** in ASCII decimals.
+		*/
+
+		name = string_table + atoi( ar_hdr.ar_name + 1 );
+		endname = name + strlen( name );
+	    }
+	    else
+	    {
+		/* normal name */
+		name = ar_hdr.ar_name;
+		endname = name + sizeof( ar_hdr.ar_name );
+	    }
+
+	    /* strip trailing white-space, slashes, and backslashes */
+
+	    while( endname-- > name )
+		if( !isspace(*endname) && *endname != '\\' && *endname != '/' )
+		    break;
+	    *++endname = 0;
+
+	    /* strip leading directory names, an NT specialty */
+
+	    if( c = strrchr( name, '/' ) )
+		name = c + 1;
+	    if( c = strrchr( name, '\\' ) )
+		name = c + 1;
+
+	    sprintf( buf, "%s(%.*s)", archive, endname - name, name );
+	    (*func)( closure, buf, 1 /* time valid */, (time_t)lar_date );
+
+	    offset += SARHDR + lar_size;
+	    lseek( fd, offset, 0 );
+	}
+
+	close( fd );
+}
+
+# endif /* NT */

Added: boost-jam/boost-build/branches/upstream/current/jam_src/fileos2.c
===================================================================
--- boost-jam/boost-build/branches/upstream/current/jam_src/fileos2.c	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/jam_src/fileos2.c	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,139 @@
+/*
+ * Copyright 1993-2002 Christopher Seiwald and Perforce Software, Inc.
+ *
+ * This file is part of Jam - see jam.c for Copyright information.
+ */
+
+/*  This file is ALSO:
+ *  Copyright 2001-2004 David Abrahams.
+ *  Distributed under the Boost Software License, Version 1.0.
+ *  (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+ */
+
+# include "jam.h"
+# include "filesys.h"
+# include "pathsys.h"
+
+/* note that we use "fileunix.c" when compiling with EMX on OS/2 */
+# if defined(OS_OS2) && !defined(__EMX__)
+
+# include <io.h>
+# include <dos.h>
+
+/*
+ * fileos2.c - scan directories and archives on NT
+ *
+ * External routines:
+ *
+ *	file_dirscan() - scan a directory for files
+ *	file_time() - get timestamp of file, if not done by file_dirscan()
+ *	file_archscan() - scan an archive for files
+ *
+ * File_dirscan() and file_archscan() call back a caller provided function
+ * for each file found.  A flag to this callback function lets file_dirscan()
+ * and file_archscan() indicate that a timestamp is being provided with the
+ * file.   If file_dirscan() or file_archscan() do not provide the file's
+ * timestamp, interested parties may later call file_time().
+ *
+ * 07/10/95 (taylor)  Findfirst() returns the first file on NT.
+ * 05/03/96 (seiwald) split apart into pathnt.c
+ * 09/22/00 (seiwald) handle \ and c:\ specially: don't add extra /
+ */
+
+/*
+ * file_dirscan() - scan a directory for files
+ */
+
+void
+file_dirscan( 
+	char *dir,
+	scanback func,
+	void	*closure )
+{
+    PATHNAME f;
+    string filespec[1];
+    long handle;
+    int ret;
+    struct _find_t finfo[1];
+
+    /* First enter directory itself */
+
+    memset( (char *)&f, '\0', sizeof( f ) );
+
+    f.f_dir.ptr = dir;
+    f.f_dir.len = strlen(dir);
+
+    dir = *dir ? dir : ".";
+
+    /* Special case \ or d:\ : enter it */
+    string_copy( filespec, dir );
+
+    if( f.f_dir.len == 1 && f.f_dir.ptr[0] == '\\' )
+ 	    (*func)( closure, dir, 0 /* not stat()'ed */, (time_t)0 );
+    else if( f.f_dir.len == 3 && f.f_dir.ptr[1] == ':' )
+ 	    (*func)( closure, dir, 0 /* not stat()'ed */, (time_t)0 );
+    else
+        string_push_back( filespec, '/' );
+
+    string_push_back( filespec, '*' );
+
+    /* Now enter contents of directory */
+
+    if( DEBUG_BINDSCAN )
+        printf( "scan directory %s\n", filespec->value );
+
+    /* Time info in dos find_t is not very useful.  It consists */
+    /* of a separate date and time, and putting them together is */
+    /* not easy.  So we leave that to a later stat() call. */
+
+    if( !_dos_findfirst( filespec->value, _A_NORMAL|_A_RDONLY|_A_SUBDIR, finfo ) )
+    {
+        string filename[1];
+        string_new( filename );
+        do
+        {
+            
+            f.f_base.ptr = finfo->name;
+            f.f_base.len = strlen( finfo->name );
+
+            string_truncate( filename, 0 );
+            path_build( &f, filename, 0 );
+            (*func)( closure, filename->value, 0 /* not stat()'ed */, (time_t)0 );
+        }
+        while( !_dos_findnext( finfo ) );
+        string_free( filename );
+    }
+}
+
+/*
+ * file_time() - get timestamp of file, if not done by file_dirscan()
+ */
+
+int
+file_time(
+	char	*filename,
+	time_t	*time )
+{
+	/* This is called on OS2, not NT.  */
+	/* NT fills in the time in the dirscan. */
+
+	struct stat statbuf;
+
+	if( stat( filename, &statbuf ) < 0 )
+	    return -1;
+
+	*time = statbuf.st_mtime;
+
+	return 0;
+}
+
+void
+file_archscan(
+	char *archive,
+	scanback func,
+	void	*closure )
+{
+}
+
+# endif /* OS2 && !__EMX__ */
+

Added: boost-jam/boost-build/branches/upstream/current/jam_src/filesys.c
===================================================================
--- boost-jam/boost-build/branches/upstream/current/jam_src/filesys.c	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/jam_src/filesys.c	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,33 @@
+# include "jam.h"
+# include "pathsys.h"
+# include "strings.h"
+
+void
+file_build1(
+    PATHNAME *f,
+    string* file)
+{
+    if( DEBUG_SEARCH )
+    {
+	printf("build file: ");
+	if( f->f_root.len )
+            printf( "root = '%.*s' ", f->f_root.len, f->f_root.ptr );
+	if( f->f_dir.len )
+            printf( "dir = '%.*s' ", f->f_dir.len, f->f_dir.ptr );
+	if( f->f_base.len )
+            printf( "base = '%.*s' ", f->f_base.len, f->f_base.ptr );
+    }
+	
+    /* Start with the grist.  If the current grist isn't */
+    /* surrounded by <>'s, add them. */
+
+    if( f->f_grist.len )
+    {
+        if( f->f_grist.ptr[0] != '<' )
+            string_push_back( file, '<' );
+        string_append_range(
+            file, f->f_grist.ptr, f->f_grist.ptr + f->f_grist.len );
+        if( file->value[file->size - 1] != '>' )
+            string_push_back( file, '>' );
+    }
+}

Added: boost-jam/boost-build/branches/upstream/current/jam_src/filesys.h
===================================================================
--- boost-jam/boost-build/branches/upstream/current/jam_src/filesys.h	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/jam_src/filesys.h	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,31 @@
+/*
+ * Copyright 1993-2002 Christopher Seiwald and Perforce Software, Inc.
+ *
+ * This file is part of Jam - see jam.c for Copyright information.
+ */
+
+/*  This file is ALSO:
+ *  Copyright 2001-2004 David Abrahams.
+ *  Distributed under the Boost Software License, Version 1.0.
+ *  (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+ */
+
+/*
+ * filesys.h - OS specific file routines 
+ */
+
+#ifndef FILESYS_DWA20011025_H
+# define FILESYS_DWA20011025_H
+
+# include "pathsys.h"
+
+typedef void (*scanback)( void *closure, char *file, int found, time_t t );
+
+void file_dirscan( char *dir, scanback func, void *closure );
+void file_archscan( char *arch, scanback func, void *closure );
+
+int file_time( char *filename, time_t *time );
+
+void file_build1(PATHNAME *f, string* file) ;
+
+#endif

Added: boost-jam/boost-build/branches/upstream/current/jam_src/fileunix.c
===================================================================
--- boost-jam/boost-build/branches/upstream/current/jam_src/fileunix.c	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/jam_src/fileunix.c	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,441 @@
+/*
+ * Copyright 1993-2002 Christopher Seiwald and Perforce Software, Inc.
+ *
+ * This file is part of Jam - see jam.c for Copyright information.
+ */
+
+/*  This file is ALSO:
+ *  Copyright 2001-2004 David Abrahams.
+ *  Distributed under the Boost Software License, Version 1.0.
+ *  (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+ */
+
+# include "jam.h"
+# include "filesys.h"
+# include "strings.h"
+# include "pathsys.h"
+# include <stdio.h>
+
+#if defined(sun) || defined(__sun)
+# include <unistd.h> /* needed for read and close prototype */
+#endif
+
+# ifdef USE_FILEUNIX
+
+#if defined(sun) || defined(__sun)
+# include <unistd.h> /* needed for read and close prototype */
+#endif
+
+# if defined( OS_SEQUENT ) || \
+     defined( OS_DGUX ) || \
+     defined( OS_SCO ) || \
+     defined( OS_ISC ) 
+# define PORTAR 1
+# endif
+
+# ifdef __EMX__
+# include <sys/types.h>
+# include <sys/stat.h>
+# endif
+
+# if defined( OS_RHAPSODY ) || \
+     defined( OS_MACOSX ) || \
+     defined( OS_NEXT )
+/* need unistd for rhapsody's proper lseek */
+# include <sys/dir.h>
+# include <unistd.h>
+# define STRUCT_DIRENT struct direct 
+# else
+# include <dirent.h>
+# define STRUCT_DIRENT struct dirent 
+# endif
+
+# ifdef OS_COHERENT
+# include <arcoff.h>
+# define HAVE_AR
+# endif
+
+# if defined( OS_MVS ) || \
+		 defined( OS_INTERIX )
+
+#define	ARMAG	"!<arch>\n"
+#define	SARMAG	8
+#define	ARFMAG	"`\n"
+
+struct ar_hdr		/* archive file member header - printable ascii */
+{
+	char	ar_name[16];	/* file member name - `/' terminated */
+	char	ar_date[12];	/* file member date - decimal */
+	char	ar_uid[6];	/* file member user id - decimal */
+	char	ar_gid[6];	/* file member group id - decimal */
+	char	ar_mode[8];	/* file member mode - octal */
+	char	ar_size[10];	/* file member size - decimal */
+	char	ar_fmag[2];	/* ARFMAG - string to end header */
+};
+
+# define HAVE_AR
+# endif
+
+# if defined( OS_QNX ) || \
+     defined( OS_BEOS ) || \
+     defined( OS_MPEIX )
+# define NO_AR
+# define HAVE_AR
+# endif
+
+# ifndef HAVE_AR
+
+# ifdef OS_AIX
+/* Define those for AIX to get the definitions for both the small and the
+ * big variant of the archive file format. */
+#	 define __AR_SMALL__
+#	 define __AR_BIG__
+# endif
+
+# include <ar.h>
+# endif	
+
+/*
+ * fileunix.c - manipulate file names and scan directories on UNIX/AmigaOS
+ *
+ * External routines:
+ *
+ *	file_dirscan() - scan a directory for files
+ *	file_time() - get timestamp of file, if not done by file_dirscan()
+ *	file_archscan() - scan an archive for files
+ *
+ * File_dirscan() and file_archscan() call back a caller provided function
+ * for each file found.  A flag to this callback function lets file_dirscan()
+ * and file_archscan() indicate that a timestamp is being provided with the
+ * file.   If file_dirscan() or file_archscan() do not provide the file's
+ * timestamp, interested parties may later call file_time().
+ *
+ * 04/08/94 (seiwald) - Coherent/386 support added.
+ * 12/19/94 (mikem) - solaris string table insanity support
+ * 02/14/95 (seiwald) - parse and build /xxx properly
+ * 05/03/96 (seiwald) - split into pathunix.c
+ * 11/21/96 (peterk) - BEOS does not have Unix-style archives
+ */
+
+/*
+ * file_dirscan() - scan a directory for files
+ */
+
+void
+file_dirscan( 
+	char *dir,
+	scanback func,
+	void *closure )
+{
+	PATHNAME f;
+	DIR *d;
+	STRUCT_DIRENT *dirent;
+        string filename[1];
+
+	/* First enter directory itself */
+
+	memset( (char *)&f, '\0', sizeof( f ) );
+
+	f.f_dir.ptr = dir;
+	f.f_dir.len = strlen(dir);
+
+	dir = *dir ? dir : ".";
+
+	/* Special case / : enter it */
+
+	if( f.f_dir.len == 1 && f.f_dir.ptr[0] == '/' )
+	    (*func)( closure, dir, 0 /* not stat()'ed */, (time_t)0 );
+
+	/* Now enter contents of directory */
+
+	if( !( d = opendir( dir ) ) )
+	    return;
+
+	if( DEBUG_BINDSCAN )
+	    printf( "scan directory %s\n", dir );
+
+        string_new( filename );
+	while( dirent = readdir( d ) )
+	{
+# ifdef old_sinix
+	    /* Broken structure definition on sinix. */
+	    f.f_base.ptr = dirent->d_name - 2;
+# else
+	    f.f_base.ptr = dirent->d_name;
+# endif
+	    f.f_base.len = strlen( f.f_base.ptr );
+
+            string_truncate( filename, 0 );
+	    path_build( &f, filename, 0 );
+
+	    (*func)( closure, filename->value, 0 /* not stat()'ed */, (time_t)0 );
+	}
+        string_free( filename );
+
+	closedir( d );
+}
+
+/*
+ * file_time() - get timestamp of file, if not done by file_dirscan()
+ */
+
+int
+file_time(
+	char	*filename,
+	time_t	*time )
+{
+	struct stat statbuf;
+
+	if( stat( filename, &statbuf ) < 0 )
+	    return -1;
+
+    /* Technically, existing files can have 0 as statbuf.st_mtime 
+       --- in particular, the /cygdrive directory under cygwin. However, 
+       though all the code jam assumes that timestamp of 0 means
+       "does not exist" and will try to create the "missing" target, causing
+       problems. Work around this problem by chanding 0 to 1.
+    */
+	*time = statbuf.st_mtime ? statbuf.st_mtime : 1 ;
+	return 0;
+}
+
+/*
+ * file_archscan() - scan an archive for files
+ */
+
+# ifndef AIAMAG	/* God-fearing UNIX */
+
+# define SARFMAG 2
+# define SARHDR sizeof( struct ar_hdr )
+
+void
+file_archscan(
+	char *archive,
+	scanback func,
+	void *closure )
+{
+# ifndef NO_AR
+	struct ar_hdr ar_hdr;
+	char buf[ MAXJPATH ];
+	long offset;
+	char    *string_table = 0;
+	int fd;
+
+	if( ( fd = open( archive, O_RDONLY, 0 ) ) < 0 )
+	    return;
+
+	if( read( fd, buf, SARMAG ) != SARMAG ||
+	    strncmp( ARMAG, buf, SARMAG ) )
+	{
+	    close( fd );
+	    return;
+	}
+
+	offset = SARMAG;
+
+	if( DEBUG_BINDSCAN )
+	    printf( "scan archive %s\n", archive );
+
+	while( read( fd, &ar_hdr, SARHDR ) == SARHDR
+	       && ! ( memcmp( ar_hdr.ar_fmag, ARFMAG, SARFMAG )
+#ifdef ARFZMAG
+		      /* OSF also has a compressed format */
+		      && memcmp( ar_hdr.ar_fmag, ARFZMAG, SARFMAG )
+#endif
+	      ) )
+	{
+	    char    lar_name_[257];
+            char*   lar_name = lar_name_ + 1;
+	    long    lar_date;
+	    long    lar_size;
+	    long    lar_offset;
+	    char *c;
+	    char    *src, *dest;
+
+	    strncpy( lar_name, ar_hdr.ar_name, sizeof(ar_hdr.ar_name) );
+
+	    sscanf( ar_hdr.ar_date, "%ld", &lar_date );
+	    sscanf( ar_hdr.ar_size, "%ld", &lar_size );
+
+	    if (ar_hdr.ar_name[0] == '/')
+	    {
+		if (ar_hdr.ar_name[1] == '/')
+		{
+		    /* this is the "string table" entry of the symbol table,
+		    ** which holds strings of filenames that are longer than
+		    ** 15 characters (ie. don't fit into a ar_name
+		    */
+
+		    string_table = (char *)malloc(lar_size);
+		    lseek(fd, offset + SARHDR, 0);
+		    if (read(fd, string_table, lar_size) != lar_size)
+			printf("error reading string table\n");
+		}
+		else if (string_table && ar_hdr.ar_name[1] != ' ')
+		{
+		    /* Long filenames are recognized by "/nnnn" where nnnn is
+		    ** the offset of the string in the string table represented
+		    ** in ASCII decimals.
+		    */
+		    dest = lar_name;
+		    lar_offset = atoi(lar_name + 1);
+		    src = &string_table[lar_offset];
+		    while (*src != '/')
+			*dest++ = *src++;
+		    *dest = '/';
+		}
+	    }
+
+	    c = lar_name - 1;
+	    while( *++c != ' ' && *c != '/' )
+		;
+	    *c = '\0';
+
+	    if ( DEBUG_BINDSCAN )
+		printf( "archive name %s found\n", lar_name );
+
+	    sprintf( buf, "%s(%s)", archive, lar_name );
+
+	    (*func)( closure, buf, 1 /* time valid */, (time_t)lar_date );
+
+	    offset += SARHDR + ( ( lar_size + 1 ) & ~1 );
+	    lseek( fd, offset, 0 );
+	}
+
+	if (string_table)
+	    free(string_table);
+
+	close( fd );
+
+# endif /* NO_AR */
+
+}
+
+# else /* AIAMAG - RS6000 AIX */
+
+static void file_archscan_small(
+    int fd, char const *archive, scanback func, void *closure)
+{
+    struct fl_hdr fl_hdr;
+
+    struct {
+        struct ar_hdr hdr;
+        char pad[ 256 ];
+    } ar_hdr ;
+
+    char buf[ MAXJPATH ];
+    long offset;
+
+    if( read( fd, (char *)&fl_hdr, FL_HSZ ) != FL_HSZ)
+        return;
+
+    sscanf( fl_hdr.fl_fstmoff, "%ld", &offset );
+  
+    if( DEBUG_BINDSCAN )
+        printf( "scan archive %s\n", archive );
+  
+    while( offset > 0
+           && lseek( fd, offset, 0 ) >= 0
+           && read( fd, &ar_hdr, sizeof( ar_hdr ) ) >= sizeof( ar_hdr.hdr ) )
+    {
+        long    lar_date;
+        int     lar_namlen;
+    
+        sscanf( ar_hdr.hdr.ar_namlen, "%d", &lar_namlen );
+        sscanf( ar_hdr.hdr.ar_date, "%ld", &lar_date );
+        sscanf( ar_hdr.hdr.ar_nxtmem, "%ld", &offset );
+    
+        if( !lar_namlen )
+            continue;
+      
+        ar_hdr.hdr._ar_name.ar_name[ lar_namlen ] = '\0';
+
+        sprintf( buf, "%s(%s)", archive, ar_hdr.hdr._ar_name.ar_name );
+
+        (*func)( closure, buf, 1 /* time valid */, (time_t)lar_date );
+    }
+}
+
+/* Check for OS version which supports the big variant. */
+#ifdef AR_HSZ_BIG
+
+static void file_archscan_big(
+    int fd, char const *archive, scanback func, void *closure)
+{
+    struct fl_hdr_big fl_hdr;
+
+    struct {
+        struct ar_hdr_big hdr;
+        char pad[ 256 ];
+    } ar_hdr ;
+
+    char buf[ MAXJPATH ];
+    long long offset;
+
+    if( read( fd, (char *)&fl_hdr, FL_HSZ_BIG) != FL_HSZ_BIG)
+        return;
+
+    sscanf( fl_hdr.fl_fstmoff, "%lld", &offset );
+
+    if( DEBUG_BINDSCAN )
+        printf( "scan archive %s\n", archive );
+
+    while( offset > 0
+           && lseek( fd, offset, 0 ) >= 0
+           && read( fd, &ar_hdr, sizeof( ar_hdr ) ) >= sizeof( ar_hdr.hdr ) )
+    {
+        long    lar_date;
+        int     lar_namlen;
+
+        sscanf( ar_hdr.hdr.ar_namlen, "%d", &lar_namlen );
+        sscanf( ar_hdr.hdr.ar_date, "%ld", &lar_date );
+        sscanf( ar_hdr.hdr.ar_nxtmem, "%lld", &offset );
+
+        if( !lar_namlen )
+            continue;
+
+        ar_hdr.hdr._ar_name.ar_name[ lar_namlen ] = '\0';
+
+        sprintf( buf, "%s(%s)", archive, ar_hdr.hdr._ar_name.ar_name );
+
+        (*func)( closure, buf, 1 /* time valid */, (time_t)lar_date );
+    }
+
+}
+
+#endif /* AR_HSZ_BIG */
+
+void file_archscan(char *archive, scanback func, void *closure)
+{
+    int fd;
+    char fl_magic[SAIAMAG];
+
+    if(( fd = open(archive, O_RDONLY, 0)) < 0)
+        return;
+  
+    if(read( fd, fl_magic, SAIAMAG) != SAIAMAG
+       || lseek(fd, 0, SEEK_SET) == -1)
+    {
+        close(fd);
+        return;
+    }
+
+    if (strncmp(AIAMAG, fl_magic, SAIAMAG) == 0)
+    {
+        /* read small variant */
+        file_archscan_small(fd, archive, func, closure);
+    }
+#ifdef AR_HSZ_BIG
+    else if (strncmp(AIAMAGBIG, fl_magic, SAIAMAG) == 0)
+    {
+        /* read big variant */
+        file_archscan_big(fd, archive, func, closure);
+    }
+#endif
+  
+    close( fd );
+}
+
+# endif /* AIAMAG - RS6000 AIX */
+
+# endif /* USE_FILEUNIX */

Added: boost-jam/boost-build/branches/upstream/current/jam_src/filevms.c
===================================================================
--- boost-jam/boost-build/branches/upstream/current/jam_src/filevms.c	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/jam_src/filevms.c	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,331 @@
+/*
+ * Copyright 1993-2002 Christopher Seiwald and Perforce Software, Inc.
+ *
+ * This file is part of Jam - see jam.c for Copyright information.
+ */
+
+/*  This file is ALSO:
+ *  Copyright 2001-2004 David Abrahams.
+ *  Distributed under the Boost Software License, Version 1.0.
+ *  (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+ */
+
+# include "jam.h"
+# include "filesys.h"
+# include "pathsys.h"
+
+# ifdef OS_VMS
+
+/*
+ * filevms.c - scan directories and libaries on VMS
+ *
+ * External routines:
+ *
+ *	file_dirscan() - scan a directory for files
+ *	file_time() - get timestamp of file, if not done by file_dirscan()
+ *	file_archscan() - scan an archive for files
+ *
+ * File_dirscan() and file_archscan() call back a caller provided function
+ * for each file found.  A flag to this callback function lets file_dirscan()
+ * and file_archscan() indicate that a timestamp is being provided with the
+ * file.   If file_dirscan() or file_archscan() do not provide the file's
+ * timestamp, interested parties may later call file_time().
+ *
+ * 02/09/95 (seiwald) - bungled R=[xxx] - was using directory length!
+ * 05/03/96 (seiwald) - split into pathvms.c
+ */
+
+# include <rms.h>
+# include <iodef.h>
+# include <ssdef.h>
+# include <string.h>
+# include <stdlib.h>
+# include <stdio.h>
+# include <descrip.h>
+
+#include <lbrdef.h>
+#include <credef.h>
+#include <mhddef.h>
+#include <lhidef.h>
+#include <lib$routines.h>
+#include <starlet.h>
+
+/* Supply missing prototypes for lbr$-routines*/
+
+#ifdef __cplusplus
+extern "C" { 
+#endif /* __cplusplus */
+
+int lbr$set_module( 
+	void **,
+	unsigned long *,
+	struct dsc$descriptor_s *,
+	unsigned short *, 
+	void * );
+
+int lbr$open( void **,
+	struct dsc$descriptor_s *,
+	void *,
+	void *, 
+	void *,
+	void *,
+	void * );
+
+int lbr$ini_control(
+	void **,
+	unsigned long *,
+	unsigned long *,
+	void * );
+
+int lbr$get_index(
+	void **,
+	unsigned long *,
+	int (*func)( struct dsc$descriptor_s *, unsigned long *),
+	void * );
+
+int lbr$close(
+	void ** );
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+static void
+file_cvttime( 
+    unsigned int *curtime,
+    time_t *unixtime )
+{
+    static const size_t divisor = 10000000;
+    static unsigned int bastim[2] = { 0x4BEB4000, 0x007C9567 }; /* 1/1/1970 */
+    int delta[2], remainder;
+
+    lib$subx( curtime, bastim, delta );
+    lib$ediv( &divisor, delta, unixtime, &remainder );
+}
+
+# define DEFAULT_FILE_SPECIFICATION "[]*.*;0"
+
+# define min( a,b ) ((a)<(b)?(a):(b))
+
+void
+file_dirscan( 
+	char *dir,
+	scanback func,
+	void	*closure )
+{
+
+    struct FAB xfab;
+    struct NAM xnam;
+    struct XABDAT xab;
+    char esa[256];
+    char filename[256];
+    string filename2[1];
+    char dirname[256];
+    register int status;
+    PATHNAME f;
+
+    memset( (char *)&f, '\0', sizeof( f ) );
+
+    f.f_root.ptr = dir;
+    f.f_root.len = strlen( dir );
+
+	/* get the input file specification
+	 */
+    xnam = cc$rms_nam;
+    xnam.nam$l_esa = esa;
+    xnam.nam$b_ess = sizeof( esa ) - 1;
+    xnam.nam$l_rsa = filename;
+    xnam.nam$b_rss = min( sizeof( filename ) - 1, NAM$C_MAXRSS );
+
+    xab = cc$rms_xabdat;                /* initialize extended attributes */
+    xab.xab$b_cod = XAB$C_DAT;		/* ask for date */
+    xab.xab$l_nxt = NULL;               /* terminate XAB chain      */
+
+    xfab = cc$rms_fab;
+    xfab.fab$l_dna = DEFAULT_FILE_SPECIFICATION;
+    xfab.fab$b_dns = sizeof( DEFAULT_FILE_SPECIFICATION ) - 1;
+    xfab.fab$l_fop = FAB$M_NAM;
+    xfab.fab$l_fna = dir;			/* address of file name	    */
+    xfab.fab$b_fns = strlen( dir );		/* length of file name	    */
+    xfab.fab$l_nam = &xnam;			/* address of NAB block	    */
+    xfab.fab$l_xab = (char *)&xab;       /* address of XAB block     */
+
+
+    status = sys$parse( &xfab );
+
+    if( DEBUG_BINDSCAN )
+	printf( "scan directory %s\n", dir );
+
+    if ( !( status & 1 ) )
+	return;
+
+
+
+    /* Add bogus directory for [000000] */
+
+    if( !strcmp( dir, "[000000]" ) )
+    {
+	(*func)( closure, "[000000]", 1 /* time valid */, 1 /* old but true */ );
+    }
+
+    /* Add bogus directory for [] */
+
+    if( !strcmp( dir, "[]" ) )
+    {
+	(*func)( closure, "[]", 1 /* time valid */, 1 /* old but true */ );
+	(*func)( closure, "[-]", 1 /* time valid */, 1 /* old but true */ );
+    }
+
+    string_new( filename2 );
+    while ( (status = sys$search( &xfab )) & 1 )
+    {
+	char *s;
+	time_t time;
+
+	/* "I think that might work" - eml */
+
+	sys$open( &xfab );
+	sys$close( &xfab );
+
+	file_cvttime( (unsigned int *)&xab.xab$q_rdt, &time );
+
+	filename[xnam.nam$b_rsl] = '\0';
+
+	/* What we do with the name depends on the suffix: */
+	/* .dir is a directory */
+	/* .xxx is a file with a suffix */
+	/* . is no suffix at all */
+
+	if( xnam.nam$b_type == 4 && !strncmp( xnam.nam$l_type, ".DIR", 4 ) )
+	{
+	    /* directory */
+	    sprintf( dirname, "[.%.*s]", xnam.nam$b_name, xnam.nam$l_name );
+	    f.f_dir.ptr = dirname;
+	    f.f_dir.len = strlen( dirname );
+	    f.f_base.ptr = 0;
+	    f.f_base.len = 0;
+	    f.f_suffix.ptr = 0;
+	    f.f_suffix.len = 0;
+	}
+	else
+	{
+	    /* normal file with a suffix */
+	    f.f_dir.ptr = 0;
+	    f.f_dir.len = 0;
+	    f.f_base.ptr = xnam.nam$l_name;
+	    f.f_base.len = xnam.nam$b_name;
+	    f.f_suffix.ptr = xnam.nam$l_type;
+	    f.f_suffix.len = xnam.nam$b_type;
+	}
+
+        string_truncate( filename2, 0 );
+	path_build( &f, filename2, 0 );
+
+	/*
+	if( DEBUG_SEARCH )
+	    printf("root '%s' base %.*s suf %.*s = %s\n",
+		    dir,
+		    xnam.nam$b_name, xnam.nam$l_name, 
+		    xnam.nam$b_type, xnam.nam$l_type,
+		    filename2);
+	*/
+
+	(*func)( closure, filename2->value, 1 /* time valid */, time );
+    }
+    string_free( filename2 );
+}    
+
+int
+file_time(
+	char	*filename,
+	time_t	*time )
+{
+	/* This should never be called, as all files are */
+	/* timestampped in file_dirscan() and file_archscan() */
+	return -1;
+}
+
+static char *VMS_archive = 0;
+static scanback VMS_func;
+static void *VMS_closure;
+static void *context;
+
+static int
+file_archmember( 
+    struct dsc$descriptor_s *module,
+    unsigned long *rfa )
+{
+    static struct dsc$descriptor_s bufdsc =
+		  {0, DSC$K_DTYPE_T, DSC$K_CLASS_S, NULL};
+
+    struct mhddef *mhd;
+    char filename[128];
+    char buf[ MAXJPATH ];
+
+    int status;
+    time_t library_date;
+
+    register int i;
+    register char *p;
+
+    bufdsc.dsc$a_pointer = filename;
+    bufdsc.dsc$w_length = sizeof( filename );
+    status = lbr$set_module( &context, rfa, &bufdsc,
+			     &bufdsc.dsc$w_length, NULL );
+
+    if ( !(status & 1) )
+	return ( 1 );
+
+    mhd = (struct mhddef *)filename;
+
+    file_cvttime( &mhd->mhd$l_datim, &library_date );
+
+    for ( i = 0, p = module->dsc$a_pointer; i < module->dsc$w_length; i++, p++ )
+	filename[i] = *p;
+
+    filename[i] = '\0';
+
+    sprintf( buf, "%s(%s.obj)", VMS_archive, filename );
+
+    (*VMS_func)( VMS_closure, buf, 1 /* time valid */, (time_t)library_date );
+
+    return ( 1 );
+}
+
+void
+file_archscan(
+	char *archive,
+	scanback func,
+	void	*closure )
+{
+    static struct dsc$descriptor_s library =
+		  {0, DSC$K_DTYPE_T, DSC$K_CLASS_S, NULL};
+
+    unsigned long lfunc = LBR$C_READ;
+    unsigned long typ = LBR$C_TYP_UNK;
+    unsigned long index = 1;
+
+    register int status;
+
+    VMS_archive = archive;
+    VMS_func = func;
+    VMS_closure = closure;
+
+    status = lbr$ini_control( &context, &lfunc, &typ, NULL );
+    if ( !( status & 1 ) )
+	return;
+
+    library.dsc$a_pointer = archive;
+    library.dsc$w_length = strlen( archive );
+
+    status = lbr$open( &context, &library, NULL, NULL, NULL, NULL, NULL );
+    if ( !( status & 1 ) )
+	return;
+
+    (void) lbr$get_index( &context, &index, file_archmember, NULL );
+
+    (void) lbr$close( &context );
+}
+
+# endif /* VMS */
+

Added: boost-jam/boost-build/branches/upstream/current/jam_src/frames.c
===================================================================
--- boost-jam/boost-build/branches/upstream/current/jam_src/frames.c	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/jam_src/frames.c	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,23 @@
+/*  
+ *  Copyright 2001-2004 David Abrahams.
+ *  Distributed under the Boost Software License, Version 1.0.
+ *  (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+ */
+
+# include "frames.h"
+# include "lists.h"
+
+
+void frame_init( FRAME* frame )
+{
+    frame->prev = 0;
+    lol_init(frame->args);
+    frame->module = root_module();
+    frame->rulename = "module scope";
+    frame->procedure = 0;
+}
+
+void frame_free( FRAME* frame )
+{
+    lol_free( frame->args );
+}

Added: boost-jam/boost-build/branches/upstream/current/jam_src/frames.h
===================================================================
--- boost-jam/boost-build/branches/upstream/current/jam_src/frames.h	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/jam_src/frames.h	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,28 @@
+/*  
+ *  Copyright 2001-2004 David Abrahams.
+ *  Distributed under the Boost Software License, Version 1.0.
+ *  (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+ */
+#ifndef FRAMES_DWA20011021_H
+# define FRAMES_DWA20011021_H
+
+# include "lists.h"
+# include "modules.h"
+
+typedef struct _PARSE PARSE;
+typedef struct frame FRAME;
+
+struct frame
+{
+    FRAME* prev;
+    LOL args[1];
+    module_t* module;
+    PARSE* procedure;
+    char*  rulename;
+};
+
+void frame_init( FRAME* ); /* implemented in compile.c */
+void frame_free( FRAME* ); /* implemented in compile.c */
+
+#endif
+

Added: boost-jam/boost-build/branches/upstream/current/jam_src/glob.c
===================================================================
--- boost-jam/boost-build/branches/upstream/current/jam_src/glob.c	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/jam_src/glob.c	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,157 @@
+/*
+ * Copyright 1994 Christopher Seiwald.  All rights reserved. 
+ *
+ * This file is part of Jam - see jam.c for Copyright information.
+ */
+
+/*
+ * glob.c - match a string against a simple pattern
+ *
+ * Understands the following patterns:
+ *
+ *	*	any number of characters
+ *	?	any single character
+ *	[a-z]	any single character in the range a-z
+ *	[^a-z]	any single character not in the range a-z
+ *	\x	match x
+ *	
+ * External functions:
+ *
+ *	glob() - match a string against a simple pattern
+ *
+ * Internal functions:
+ *
+ *	globchars() - build a bitlist to check for character group match
+ */
+
+# include "jam.h"
+
+# define CHECK_BIT( tab, bit ) ( tab[ (bit)/8 ] & (1<<( (bit)%8 )) )
+# define BITLISTSIZE 16	/* bytes used for [chars] in compiled expr */
+
+static void globchars( char *s, char *e, char *b );
+
+/*
+ * glob() - match a string against a simple pattern
+ */
+
+int
+glob(
+	register char *c,
+	register char *s )
+{
+	char bitlist[ BITLISTSIZE ];
+	char *here;
+
+	for( ;; )
+	    switch( *c++ )
+	{
+	case '\0':
+		return *s ? -1 : 0;
+
+	case '?':
+		if( !*s++ )
+		    return 1;
+		break;
+
+	case '[':
+		/* scan for matching ] */
+
+		here = c;
+		do if( !*c++ )
+			return 1;
+		while( here == c || *c != ']' );
+		c++;
+
+		/* build character class bitlist */
+
+		globchars( here, c, bitlist );
+
+		if( !CHECK_BIT( bitlist, *(unsigned char *)s ) )
+			return 1;
+		s++;
+		break;
+
+	case '*':
+		here = s;
+
+		while( *s ) 
+			s++;
+
+		/* Try to match the rest of the pattern in a recursive */
+		/* call.  If the match fails we'll back up chars, retrying. */
+
+		while( s != here )
+		{
+			int r;
+
+			/* A fast path for the last token in a pattern */
+
+			r = *c ? glob( c, s ) : *s ? -1 : 0;
+
+			if( !r )
+				return 0;
+			else if( r < 0 )
+				return 1;
+
+			--s;
+		}
+		break;
+
+	case '\\':
+		/* Force literal match of next char. */
+
+		if( !*c || *s++ != *c++ )
+		    return 1;
+		break;
+
+	default:
+		if( *s++ != c[-1] )
+		    return 1;
+		break;
+	}
+}
+
+/*
+ * globchars() - build a bitlist to check for character group match
+ */
+
+static void
+globchars( 
+	char *s, 
+	char *e, 
+	char *b )
+{
+	int neg = 0;
+
+	memset( b, '\0', BITLISTSIZE  );
+
+	if( *s == '^') 
+		neg++, s++;
+
+	while( s < e )
+	{
+		int c;
+
+		if( s+2 < e && s[1] == '-' )
+		{
+			for( c = s[0]; c <= s[2]; c++ )
+				b[ c/8 ] |= (1<<(c%8));
+			s += 3;
+		} else {
+			c = *s++;
+			b[ c/8 ] |= (1<<(c%8));
+		}
+	}
+			
+	if( neg )
+	{
+		int i;
+		for( i = 0; i < BITLISTSIZE; i++ )
+			b[ i ] ^= 0377;
+	}
+
+	/* Don't include \0 in either $[chars] or $[^chars] */
+
+	b[0] &= 0376;
+}

Added: boost-jam/boost-build/branches/upstream/current/jam_src/hash.c
===================================================================
--- boost-jam/boost-build/branches/upstream/current/jam_src/hash.c	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/jam_src/hash.c	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,337 @@
+/*
+ * Copyright 1993, 1995 Christopher Seiwald.
+ *
+ * This file is part of Jam - see jam.c for Copyright information.
+ */
+
+# include "jam.h"
+# include "hash.h"
+# include <assert.h>
+
+/* 
+ * hash.c - simple in-memory hashing routines 
+ *
+ * External routines:
+ *
+ *     hashinit() - initialize a hash table, returning a handle
+ *     hashitem() - find a record in the table, and optionally enter a new one
+ *     hashdone() - free a hash table, given its handle
+ *
+ * Internal routines:
+ *
+ *     hashrehash() - resize and rebuild hp->tab, the hash table
+ *
+ * 4/29/93 - ensure ITEM's are aligned
+ */
+
+char 	*hashsccssid="@(#)hash.c	1.14  ()  6/20/88";
+
+/* Header attached to all data items entered into a hash table. */
+
+struct hashhdr {
+	struct item *next;
+	unsigned int keyval;			/* for quick comparisons */
+} ;
+
+/* This structure overlays the one handed to hashenter(). */
+/* It's actual size is given to hashinit(). */
+
+struct hashdata {
+	char	*key;
+	/* rest of user data */
+} ;
+
+typedef struct item {
+	struct hashhdr hdr;
+	struct hashdata data;
+} ITEM ;
+
+# define MAX_LISTS 32
+
+struct hash 
+{
+	/*
+	 * the hash table, just an array of item pointers
+	 */
+	struct {
+		int nel;
+		ITEM **base;
+	} tab;
+
+	int bloat;	/* tab.nel / items.nel */
+	int inel; 	/* initial number of elements */
+
+	/*
+	 * the array of records, maintained by these routines
+	 * essentially a microallocator
+	 */ 
+	struct {
+		int more;	/* how many more ITEMs fit in lists[ list ] */
+        ITEM *free; /* free list of items */
+		char *next;	/* where to put more ITEMs in lists[ list ] */
+		int datalen;	/* length of records in this hash table */
+		int size;	/* sizeof( ITEM ) + aligned datalen */
+		int nel;	/* total ITEMs held by all lists[] */
+		int list;	/* index into lists[] */
+
+		struct {
+			int nel;	/* total ITEMs held by this list */
+			char *base;	/* base of ITEMs array */
+		} lists[ MAX_LISTS ];
+	} items;
+
+	char *name;	/* just for hashstats() */
+} ;
+
+static void hashrehash( struct hash *hp );
+static void hashstat( struct hash *hp );
+
+/*
+ * hash_free() - remove the given item from the table if it's there.
+ * Returns 1 if found, 0 otherwise.
+ *
+ * NOTE: 2nd argument is HASHDATA*, not HASHDATA** as elsewhere.
+ */
+int
+hash_free(
+	register struct hash *hp,
+	HASHDATA *data)
+{
+	ITEM **prev;
+	register ITEM **i;
+	unsigned char *b = (unsigned char*)data->key;
+	unsigned int keyval;
+
+	keyval = *b;
+
+	while( *b )
+		keyval = keyval * 2147059363 + *b++;
+
+    prev = hp->tab.base + ( keyval % hp->tab.nel );
+	while(*prev )
+    {
+        register ITEM* i = *prev;
+	    if( keyval == i->hdr.keyval && 
+            !strcmp( i->data.key, data->key ) )
+        {
+            /* unlink the record from the hash chain */
+            *prev = i->hdr.next;
+            /* link it into the freelist */
+            i->hdr.next = hp->items.free;
+            hp->items.free = i;
+            /* mark it free so we skip it during enumeration */
+            i->data.key = 0;
+            /* we have another item */
+            hp->items.more++;
+            return 1;
+        }
+        prev = &i->hdr.next;
+    }
+    return 0;
+}
+
+/*
+ * hashitem() - find a record in the table, and optionally enter a new one
+ */
+
+int
+hashitem(
+	register struct hash *hp,
+	HASHDATA **data,
+	int enter )
+{
+	ITEM **base;
+	register ITEM *i;
+	unsigned char *b = (unsigned char*)(*data)->key;
+	unsigned int keyval;
+
+	if( enter && !hp->items.more )
+	    hashrehash( hp );
+
+	if( !enter && !hp->items.nel )
+	    return 0;
+
+	keyval = *b;
+
+	while( *b )
+		keyval = keyval * 2147059363 + *b++;
+
+	base = hp->tab.base + ( keyval % hp->tab.nel );
+
+	for( i = *base; i; i = i->hdr.next )
+	    if( keyval == i->hdr.keyval && 
+		!strcmp( i->data.key, (*data)->key ) )
+	{
+		*data = &i->data;
+		return !0;
+	}
+
+	if( enter ) 
+	{
+        /* try to grab one from the free list */
+        if ( hp->items.free )
+        {
+            i = hp->items.free;
+            hp->items.free = i->hdr.next;
+            assert( i->data.key == 0 );
+        }
+        else
+        {
+            i = (ITEM *)hp->items.next;
+            hp->items.next += hp->items.size;
+        }
+		hp->items.more--;
+		memcpy( (char *)&i->data, (char *)*data, hp->items.datalen );
+		i->hdr.keyval = keyval;
+		i->hdr.next = *base;
+		*base = i;
+		*data = &i->data;
+	}
+
+	return 0;
+}
+
+/*
+ * hashrehash() - resize and rebuild hp->tab, the hash table
+ */
+
+static void hashrehash( register struct hash *hp )
+{
+	int i = ++hp->items.list;
+
+	hp->items.more = i ? 2 * hp->items.nel : hp->inel;
+	hp->items.next = (char *)malloc( hp->items.more * hp->items.size );
+    hp->items.free = 0;
+    
+	hp->items.lists[i].nel = hp->items.more;
+	hp->items.lists[i].base = hp->items.next;
+	hp->items.nel += hp->items.more;
+
+	if( hp->tab.base )
+		free( (char *)hp->tab.base );
+
+	hp->tab.nel = hp->items.nel * hp->bloat;
+	hp->tab.base = (ITEM **)malloc( hp->tab.nel * sizeof(ITEM **) );
+
+	memset( (char *)hp->tab.base, '\0', hp->tab.nel * sizeof( ITEM * ) );
+
+	for( i = 0; i < hp->items.list; i++ )
+	{
+		int nel = hp->items.lists[i].nel;
+		char *next = hp->items.lists[i].base;
+
+		for( ; nel--; next += hp->items.size )
+		{
+			register ITEM *i = (ITEM *)next;
+			ITEM **ip = hp->tab.base + i->hdr.keyval % hp->tab.nel;
+            /* code currently assumes rehashing only when there are no free items */
+            assert( i->data.key != 0 ); 
+            
+			i->hdr.next = *ip;
+			*ip = i;
+		}
+	}
+}
+
+void hashenumerate( struct hash *hp, void (*f)(void*,void*), void* data )
+{
+    int i;
+    for( i = 0; i <= hp->items.list; i++ )
+    {
+        char *next = hp->items.lists[i].base;
+        int nel = hp->items.lists[i].nel;
+        if ( i == hp->items.list )
+            nel -= hp->items.more;
+
+        for( ; nel--; next += hp->items.size )
+        {
+            register ITEM *i = (ITEM *)next;
+            
+            if ( i->data.key != 0 ) /* don't enumerate freed items */
+                f(&i->data, data);
+        }
+    }
+}
+
+/* --- */
+
+# define ALIGNED(x) ( ( x + sizeof( ITEM ) - 1 ) & ~( sizeof( ITEM ) - 1 ) )
+
+/*
+ * hashinit() - initialize a hash table, returning a handle
+ */
+
+struct hash *
+hashinit( 
+	int datalen,
+	char *name )
+{
+	struct hash *hp = (struct hash *)malloc( sizeof( *hp ) );
+
+	hp->bloat = 3;
+	hp->tab.nel = 0;
+	hp->tab.base = (ITEM **)0;
+	hp->items.more = 0;
+    hp->items.free = 0;
+	hp->items.datalen = datalen;
+	hp->items.size = sizeof( struct hashhdr ) + ALIGNED( datalen );
+	hp->items.list = -1;
+	hp->items.nel = 0;
+	hp->inel = 11;
+	hp->name = name;
+
+	return hp;
+}
+
+/*
+ * hashdone() - free a hash table, given its handle
+ */
+
+void
+hashdone( struct hash *hp )
+{
+	int i;
+
+	if( !hp )
+	    return;
+
+	if( DEBUG_MEM )
+	    hashstat( hp );
+
+	if( hp->tab.base )
+		free( (char *)hp->tab.base );
+	for( i = 0; i <= hp->items.list; i++ )
+		free( hp->items.lists[i].base );
+	free( (char *)hp );
+}
+
+/* ---- */
+
+static void
+hashstat( struct hash *hp )
+{
+	ITEM **tab = hp->tab.base;
+	int nel = hp->tab.nel;
+	int count = 0;
+	int sets = 0;
+	int run = ( tab[ nel - 1 ] != (ITEM *)0 );
+	int i, here;
+
+	for( i = nel; i > 0; i-- )
+	{
+		if( here = ( *tab++ != (ITEM *)0 ) )
+			count++;
+		if( here && !run )
+			sets++;
+		run = here;
+	}
+
+	printf( "%s table: %d+%d+%d (%dK+%dK) items+table+hash, %f density\n",
+		hp->name, 
+		count, 
+		hp->items.nel,
+		hp->tab.nel,
+		hp->items.nel * hp->items.size / 1024,
+		hp->tab.nel * sizeof( ITEM ** ) / 1024,
+		(float)count / (float)sets );
+}

Added: boost-jam/boost-build/branches/upstream/current/jam_src/hash.h
===================================================================
--- boost-jam/boost-build/branches/upstream/current/jam_src/hash.h	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/jam_src/hash.h	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,20 @@
+/*
+ * Copyright 1993, 1995 Christopher Seiwald.
+ *
+ * This file is part of Jam - see jam.c for Copyright information.
+ */
+
+/*
+ * hash.h - simple in-memory hashing routines 
+ */
+
+typedef struct hashdata HASHDATA;
+
+struct hash *	hashinit( int datalen, char *name );
+int 		hashitem( struct hash *hp, HASHDATA **data, int enter );
+void 		hashdone( struct hash *hp );
+void        hashenumerate( struct hash *hp, void (*f)(void*,void*), void* data );
+int         hash_free( struct hash *hp, HASHDATA *data);
+
+# define	hashenter( hp, data ) (!hashitem( hp, data, !0 ))
+# define	hashcheck( hp, data ) hashitem( hp, data, 0 )

Added: boost-jam/boost-build/branches/upstream/current/jam_src/hcache.c
===================================================================
--- boost-jam/boost-build/branches/upstream/current/jam_src/hcache.c	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/jam_src/hcache.c	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,423 @@
+/*
+ * This file has been donated to Jam.
+ */
+
+# include "jam.h"
+# include "lists.h"
+# include "parse.h"
+# include "rules.h"
+# include "regexp.h"
+# include "headers.h"
+# include "newstr.h"
+# include "hash.h"
+# include "hcache.h"
+# include "variable.h"
+# include "search.h"
+
+#ifdef OPT_HEADER_CACHE_EXT
+
+/*
+ * Craig W. McPheeters, Alias|Wavefront.
+ *
+ * hcache.c hcache.h - handle cacheing of #includes in source files
+ *
+ * Create a cache of files scanned for headers.  When starting jam,
+ * look for the cache file and load it if present.  When finished the
+ * binding phase, create a new header cache.  The cache contains
+ * files, their timestamps and the header files found in their scan.
+ * During the binding phase of jam, look in the header cache first for
+ * the headers contained in a file.  If the cache is present and
+ * valid, use its contents.  This results in dramatic speedups with
+ * large projects (eg. 3min -> 1min startup for one project.)
+ *
+ * External routines:
+ *    hcache_init() - read and parse the local .jamdeps file.
+ *    hcache_done() - write a new .jamdeps file
+ *    hcache() - return list of headers on target.  Use cache or do a scan.
+ *    
+ * The dependency file format is an ascii file with 1 line per target.
+ * Each line has the following fields:
+ * @boundname@ timestamp @file@ @file@ @file@ ... \n
+ * */
+
+struct hcachedata {
+    char		*boundname;
+    time_t		time;
+    LIST		*includes;
+    LIST		*hdrscan; /* the HDRSCAN value for this target */
+    int			age;	/* if too old, we'll remove it from cache */
+    struct hcachedata	*next;
+} ;
+
+typedef struct hcachedata HCACHEDATA ;
+
+
+static struct hash *hcachehash = 0;
+static HCACHEDATA  *hcachelist = 0; 
+
+static int queries = 0;
+static int hits = 0;
+
+#define CACHE_FILE_VERSION "version 4"
+#define CACHE_RECORD_HEADER "header"
+#define CACHE_RECORD_END "end"
+
+/*
+ * Return the name of the header cache file.  May return NULL.
+ *
+ * The user sets this by setting the HCACHEFILE variable in a Jamfile.
+ * We cache the result so the user can't change the cache file during
+ * header scanning.
+ */
+static char*
+cache_name(void)
+{
+    static char* name = 0;
+    if (!name) {
+	LIST *hcachevar = var_get("HCACHEFILE");
+
+	if (hcachevar) {
+	    TARGET *t = bindtarget( hcachevar->string );
+
+	    pushsettings( t->settings );
+        /* Don't expect cache file to be generated, so pass 0
+           as third argument to search. */
+	    t->boundname = search( t->name, &t->time, 0 );
+	    popsettings( t->settings );
+
+	    if (hcachevar) {
+		name = copystr(t->boundname);
+	    }
+	}
+    }
+    return name;
+}
+
+/*
+ * Return the maximum age a cache entry can have before it is purged
+ * from the cache.
+ */
+static int
+cache_maxage(void)
+{
+    int age = 100;
+    LIST *var = var_get("HCACHEMAXAGE");
+
+    if (var) {
+	age = atoi(var->string);
+	if (age < 0)
+	    age = 0;
+    }
+
+    return age;
+}
+
+/*
+ * Read a netstring.  The caveat is that the string can't contain
+ * ASCII 0.  The returned value is as returned by newstr(), so it need
+ * not be freed.
+ */
+char*
+read_netstring(FILE* f)
+{
+    unsigned long len;
+    static char* buf = NULL;
+    static unsigned long buf_len = 0;
+
+    if (fscanf(f, " %9lu", &len) != 1)
+	return NULL;
+    if (fgetc(f) != (int)'\t')
+	return NULL;
+
+    if (len > 1024 * 64)
+	return NULL;		/* sanity check */
+
+    if (len > buf_len)
+    {
+	unsigned long new_len = buf_len * 2;
+	if (new_len < len)
+	    new_len = len;
+	buf = (char*)realloc(buf, new_len + 1);
+	if (buf)
+	    buf_len = new_len;
+    }
+
+    if (!buf)
+	return NULL;
+
+    if (fread(buf, 1, len, f) != len)
+	return NULL;
+    if (fgetc(f) != (int)'\n')
+	return NULL;
+
+    buf[len] = 0;
+    return newstr(buf);
+}
+
+/*
+ * Write a netstring.
+ */
+void
+write_netstring(FILE* f, const char* s)
+{
+    if (!s)
+	s = "";
+    fprintf(f, "%lu\t%s\n", strlen(s), s);
+}
+
+void
+hcache_init()
+{
+    HCACHEDATA  cachedata, *c;
+    FILE	*f;
+    char	*version;
+    int		header_count = 0;
+    char*	hcachename;
+
+    hcachehash = hashinit (sizeof (HCACHEDATA), "hcache");
+
+    if (! (hcachename = cache_name()))
+	return;
+
+    if (! (f = fopen (hcachename, "rb" )))
+	return;
+    
+    version = read_netstring(f);
+    if (!version || strcmp(version, CACHE_FILE_VERSION)) {
+	fclose(f);
+	return;
+    }
+
+    while (1)
+    {
+	char* record_type;
+	char *time_str;
+	char *age_str;
+	char *includes_count_str;
+	char *hdrscan_count_str;
+	int i, count;
+	LIST *l;
+
+	record_type = read_netstring(f);
+	if (!record_type) {
+	    fprintf(stderr, "invalid %s\n", hcachename);
+	    goto bail;
+	}
+	if (!strcmp(record_type, CACHE_RECORD_END)) {
+	    break;
+	}
+	if (strcmp(record_type, CACHE_RECORD_HEADER)) {
+	    fprintf(stderr, "invalid %s with record separator <%s>\n",
+		    hcachename, record_type ? record_type : "<null>");
+	    goto bail;
+	}
+	
+	c = &cachedata;
+	    
+	c->boundname = read_netstring(f);
+	time_str = read_netstring(f);
+	age_str = read_netstring(f);
+	includes_count_str = read_netstring(f);
+	
+	if (!c->boundname || !time_str || !age_str
+	    || !includes_count_str)
+	{
+	    fprintf(stderr, "invalid %s\n", hcachename);
+	    goto bail;
+	}
+
+	c->time = atoi(time_str);
+	c->age = atoi(age_str) + 1;
+
+	count = atoi(includes_count_str);
+	for (l = 0, i = 0; i < count; i++) {
+	    char* s = read_netstring(f);
+	    if (!s) {
+		fprintf(stderr, "invalid %s\n", hcachename);
+		goto bail;
+	    }
+	    l = list_new(l, s);
+	}
+	c->includes = l;
+
+	hdrscan_count_str = read_netstring(f);
+	if (!includes_count_str) {
+	    list_free(c->includes);
+	    fprintf(stderr, "invalid %s\n", hcachename);
+	    goto bail;
+	}
+
+	count = atoi(hdrscan_count_str);
+	for (l = 0, i = 0; i < count; i++) {
+	    char* s = read_netstring(f);
+	    if (!s) {
+		fprintf(stderr, "invalid %s\n", hcachename);
+		goto bail;
+	    }
+	    l = list_new(l, s);
+	}
+	c->hdrscan = l;
+
+	if (!hashenter(hcachehash, (HASHDATA **)&c)) {
+	    fprintf(stderr, "can't insert header cache item, bailing on %s\n",
+		    hcachename);
+	    goto bail;
+	}
+
+	c->next = hcachelist;
+	hcachelist = c;
+
+	header_count++;
+    }
+
+    if (DEBUG_HEADER) {
+	printf("hcache read from file %s\n", hcachename);
+    }
+    
+ bail:
+    fclose(f);
+}
+
+void
+hcache_done()
+{
+    FILE	*f;
+    HCACHEDATA  *c;
+    int 	header_count = 0;
+    char*	hcachename;
+    int		maxage;
+    
+    if (!hcachehash)
+	return;
+
+    if (! (hcachename = cache_name()))
+	return;
+
+    if (! (f = fopen (hcachename, "wb" )))
+	return;
+
+    maxage = cache_maxage();
+
+    /* print out the version */
+    write_netstring(f, CACHE_FILE_VERSION);
+
+    c = hcachelist;
+    for (c = hcachelist; c; c = c->next) {
+	LIST	*l;
+	char time_str[30];
+	char age_str[30];
+	char includes_count_str[30];
+	char hdrscan_count_str[30];
+
+	if (maxage == 0)
+	    c->age = 0;
+	else if (c->age > maxage)
+	    continue;
+
+	sprintf(includes_count_str, "%lu", list_length(c->includes));
+	sprintf(hdrscan_count_str, "%lu", list_length(c->hdrscan));
+	sprintf(time_str, "%lu", c->time);
+	sprintf(age_str, "%lu", c->age);
+
+	write_netstring(f, CACHE_RECORD_HEADER);
+	write_netstring(f, c->boundname);
+	write_netstring(f, time_str);
+	write_netstring(f, age_str);
+	write_netstring(f, includes_count_str);
+	for (l = c->includes; l; l = list_next(l)) {
+	    write_netstring(f, l->string);
+	}
+	write_netstring(f, hdrscan_count_str);
+	for (l = c->hdrscan; l; l = list_next(l)) {
+	    write_netstring(f, l->string);
+	}
+	fputs("\n", f);
+	header_count++;
+    }
+    write_netstring(f, CACHE_RECORD_END);
+
+    if (DEBUG_HEADER) {
+	printf("hcache written to %s.   %d dependencies, %.0f%% hit rate\n",
+	       hcachename, header_count,
+	       queries ? 100.0 * hits / queries : 0);
+    }
+
+    fclose (f);
+}
+
+LIST *
+hcache (TARGET *t, int rec, regexp *re[], LIST *hdrscan)
+{
+    HCACHEDATA  cachedata, *c = &cachedata;
+    LIST 	*l = 0;
+
+    ++queries;
+
+    c->boundname = t->boundname;
+
+    if (hashcheck (hcachehash, (HASHDATA **) &c))
+    {
+	if (c->time == t->time)
+	{
+	    LIST *l1 = hdrscan, *l2 = c->hdrscan;
+	    while (l1 && l2) {
+		if (l1->string != l2->string) {
+		    l1 = NULL;
+		} else {
+		    l1 = list_next(l1);
+		    l2 = list_next(l2);
+		}
+	    }
+	    if (l1 || l2) {
+		if (DEBUG_HEADER)
+		    printf("HDRSCAN out of date in cache for %s\n",
+			   t->boundname);
+
+		printf("HDRSCAN out of date for %s\n", t->boundname);
+		printf(" real  : ");
+		list_print(hdrscan);
+		printf("\n cached: ");
+		list_print(c->hdrscan);
+		printf("\n");
+
+		list_free(c->includes);
+		list_free(c->hdrscan);
+		c->includes = 0;
+		c->hdrscan = 0;
+	    } else {
+		if (DEBUG_HEADER)
+		    printf ("using header cache for %s\n", t->boundname);
+		c->age = 0;
+		++hits;
+		l = list_copy (0, c->includes);
+		return l;
+	    }
+	} else {
+	    if (DEBUG_HEADER)
+	        printf ("header cache out of date for %s\n", t->boundname);
+	    list_free (c->includes);
+	    list_free(c->hdrscan);
+	    c->includes = 0;
+	    c->hdrscan = 0;
+	}
+    } else {
+	if (hashenter (hcachehash, (HASHDATA **)&c)) {
+	    c->boundname = newstr (c->boundname);
+	    c->next = hcachelist;
+	    hcachelist = c;
+	}
+    }
+
+    /* 'c' points at the cache entry.  Its out of date. */
+
+    l = headers1 (0, t->boundname, rec, re);
+
+    c->time = t->time;
+    c->age = 0;
+    c->includes = list_copy (0, l);
+    c->hdrscan = list_copy(0, hdrscan);
+
+    return l;
+}
+
+#endif

Added: boost-jam/boost-build/branches/upstream/current/jam_src/hcache.h
===================================================================
--- boost-jam/boost-build/branches/upstream/current/jam_src/hcache.h	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/jam_src/hcache.h	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,18 @@
+/*
+ * This file is not part of Jam
+ */
+
+/*
+ * hcache.h - handle #includes in source files
+ */
+#ifndef HCACHE_H
+# define HCACHE_H
+
+# include "regexp.h"
+# include "lists.h"
+
+void hcache_init(void);
+void hcache_done(void);
+LIST *hcache(TARGET *t, int rec, regexp *re[], LIST *hdrscan);
+
+#endif

Added: boost-jam/boost-build/branches/upstream/current/jam_src/hdrmacro.c
===================================================================
--- boost-jam/boost-build/branches/upstream/current/jam_src/hdrmacro.c	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/jam_src/hdrmacro.c	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,139 @@
+/*
+ * Copyright 1993, 2000 Christopher Seiwald.
+ *
+ * This file is part of Jam - see jam.c for Copyright information.
+ */
+
+/*  This file is ALSO:
+ *  Copyright 2001-2004 David Abrahams.
+ *  Distributed under the Boost Software License, Version 1.0.
+ *  (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+ */
+
+# include "jam.h"
+# include "lists.h"
+# include "parse.h"
+# include "compile.h"
+# include "rules.h"
+# include "variable.h"
+# include "regexp.h"
+# include "hdrmacro.h"
+# include "hash.h"
+# include "newstr.h"
+# include "strings.h"
+
+/*
+ * hdrmacro.c - handle header files that define macros used in
+ *              #include statements.
+ *
+ *  we look for lines like "#define MACRO  <....>" or '#define MACRO  "    "'
+ *  in the target file. When found, we 
+ *
+ *  we then phony up a rule invocation like:
+ *
+ *	$(HDRRULE) <target> : <resolved included files> ;
+ *
+ * External routines:
+ *    headers1() - scan a target for "#include MACRO" lines and try
+ *                 to resolve them when needed
+ *
+ * Internal routines:
+ *    headers1() - using regexp, scan a file and build include LIST
+ *
+ * 04/13/94 (seiwald) - added shorthand L0 for null list pointer
+ * 09/10/00 (seiwald) - replaced call to compile_rule with evaluate_rule,
+ *		so that headers() doesn't have to mock up a parse structure
+ *		just to invoke a rule.
+ */
+
+static LIST *header_macros1( LIST *l, char *file, int rec, regexp *re[] );
+
+/* this type is used to store a dictionary of file header macros */
+typedef struct header_macro
+{
+  char*  symbol;
+  char*  filename;  /* we could maybe use a LIST here ?? */
+  
+} HEADER_MACRO;
+ 
+static struct hash*   header_macros_hash = 0;
+
+/*
+ * headers() - scan a target for include files and call HDRRULE
+ */
+
+# define MAXINC 10
+
+void
+macro_headers( TARGET *t )
+{
+    static regexp *re = 0;
+    FILE	*f;
+    char	buf[ 1024 ];
+    
+    if ( DEBUG_HEADER )
+        printf( "macro header scan for %s\n", t->name );
+
+    /* this regexp is used to detect lines of the form       */
+    /* "#define  MACRO  <....>" or "#define  MACRO  "....."  */
+    /* in the header macro files..                           */
+    if ( re == 0 )
+    {
+        re = regex_compile(
+            "^[ 	]*#[ 	]*define[ 	]*([A-Za-z][A-Za-z0-9_]*)[ 	]*"
+            "[<\"]([^\">]*)[\">].*$" );
+    }
+    
+    if( !( f = fopen( t->boundname, "r" ) ) )
+        return;
+
+    while( fgets( buf, sizeof( buf ), f ) )
+    {
+        HEADER_MACRO  var, *v = &var;
+
+        if ( regexec( re, buf ) && re->startp[1] )
+        {
+            /* we detected a line that looks like "#define  MACRO  filename */
+            re->endp[1][0] = '\0';
+            re->endp[2][0] = '\0';
+        
+            if ( DEBUG_HEADER )
+                printf( "macro '%s' used to define filename '%s' in '%s'\n",
+                        re->startp[1], re->startp[2], t->boundname );
+
+            /* add macro definition to hash table */
+            if ( !header_macros_hash )
+                header_macros_hash = hashinit( sizeof( HEADER_MACRO ), "hdrmacros" );
+
+            v->symbol   = re->startp[1];
+            v->filename = 0;
+            if ( hashenter( header_macros_hash, (HASHDATA **)&v ) )
+            {
+                v->symbol   = newstr( re->startp[1] );  /* never freed */
+                v->filename = newstr( re->startp[2] );  /* never freed */
+            }
+            /* XXXX: FOR NOW, WE IGNORE MULTIPLE MACRO DEFINITIONS !! */
+            /*       WE MIGHT AS WELL USE A LIST TO STORE THEM..      */
+        }
+    }
+
+    fclose( f );
+}
+
+
+char*
+macro_header_get( const char*  macro_name )
+{
+  HEADER_MACRO  var, *v = &var;
+
+  v->symbol = (char*)macro_name;
+
+  if( header_macros_hash && hashcheck( header_macros_hash, (HASHDATA **)&v ) )
+  {
+    if ( DEBUG_HEADER )
+      printf( "### macro '%s' evaluated to '%s'\n", macro_name, v->filename );
+    return v->filename;
+  }
+  return 0;  
+}
+

Added: boost-jam/boost-build/branches/upstream/current/jam_src/hdrmacro.h
===================================================================
--- boost-jam/boost-build/branches/upstream/current/jam_src/hdrmacro.h	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/jam_src/hdrmacro.h	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,14 @@
+/*
+ * Copyright 1993, 1995 Christopher Seiwald.
+ *
+ * This file is part of Jam - see jam.c for Copyright information.
+ */
+
+/*
+ * hdrmacro.h - parses header files for #define MACRO  <filename> or
+ *              #define MACRO  "filename" definitions
+ */
+
+void   macro_headers( TARGET *t );
+
+char*  macro_header_get( const char*  macro_name );

Added: boost-jam/boost-build/branches/upstream/current/jam_src/headers.c
===================================================================
--- boost-jam/boost-build/branches/upstream/current/jam_src/headers.c	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/jam_src/headers.c	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,196 @@
+/*
+ * Copyright 1993, 2000 Christopher Seiwald.
+ *
+ * This file is part of Jam - see jam.c for Copyright information.
+ */
+/*  This file is ALSO:
+ *  Copyright 2001-2004 David Abrahams.
+ *  Distributed under the Boost Software License, Version 1.0.
+ *  (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+ */
+
+# include "jam.h"
+# include "lists.h"
+# include "parse.h"
+# include "compile.h"
+# include "rules.h"
+# include "variable.h"
+# include "regexp.h"
+# include "headers.h"
+# include "hdrmacro.h"
+# include "newstr.h"
+
+#ifdef OPT_HEADER_CACHE_EXT
+# include "hcache.h"
+#endif
+
+/*
+ * headers.c - handle #includes in source files
+ *
+ * Using regular expressions provided as the variable $(HDRSCAN), 
+ * headers() searches a file for #include files and phonies up a
+ * rule invocation:
+ * 
+ *	$(HDRRULE) <target> : <include files> ;
+ *
+ * External routines:
+ *    headers() - scan a target for include files and call HDRRULE
+ *
+ * Internal routines:
+ *    headers1() - using regexp, scan a file and build include LIST
+ *
+ * 04/13/94 (seiwald) - added shorthand L0 for null list pointer
+ * 09/10/00 (seiwald) - replaced call to compile_rule with evaluate_rule,
+ *		so that headers() doesn't have to mock up a parse structure
+ *		just to invoke a rule.
+ */
+
+#ifndef OPT_HEADER_CACHE_EXT
+static LIST *headers1( LIST *l, char *file, int rec, regexp *re[]);
+#endif
+
+/*
+ * headers() - scan a target for include files and call HDRRULE
+ */
+
+# define MAXINC 10
+
+void
+headers( TARGET *t )
+{
+    LIST	*hdrscan;
+    LIST	*hdrrule;
+    LIST	*headlist = 0;
+    regexp	*re[ MAXINC ];
+    int	rec = 0;
+        
+    if( !( hdrscan = var_get( "HDRSCAN" ) ) || 
+        !( hdrrule = var_get( "HDRRULE" ) ) )
+        return;
+
+    if( DEBUG_HEADER )
+        printf( "header scan %s\n", t->name );
+
+    /* Compile all regular expressions in HDRSCAN */
+
+    while( rec < MAXINC && hdrscan )
+    {
+        re[rec++] = regex_compile( hdrscan->string );
+        hdrscan = list_next( hdrscan );
+    }
+
+    /* Doctor up call to HDRRULE rule */
+    /* Call headers1() to get LIST of included files. */
+    {
+        FRAME	frame[1];
+        frame_init( frame );
+        lol_add( frame->args, list_new( L0, t->name ) );
+#ifdef OPT_HEADER_CACHE_EXT
+        lol_add( frame->args, hcache( t, rec, re, hdrscan ) );
+#else
+        lol_add( frame->args, headers1( headlist, t->boundname, rec, re ) );
+#endif
+
+        if( lol_get( frame->args, 1 ) )
+        {
+            /* The third argument to HDRRULE is the bound name of
+             * $(<) */
+            lol_add( frame->args, list_new( L0, t->boundname ) );
+
+            list_free( evaluate_rule( hdrrule->string, frame ) );
+        }
+
+        /* Clean up */
+
+        frame_free( frame );
+    }
+}
+
+/*
+ * headers1() - using regexp, scan a file and build include LIST
+ */
+
+#ifdef OPT_HEADER_CACHE_EXT
+LIST *
+#else
+static LIST *
+#endif
+headers1( 
+	LIST	*l,
+	char	*file,
+	int	rec,
+	regexp	*re[] )
+{
+	FILE	*f;
+	char	buf[ 1024 ];
+	int		i;
+        static regexp *re_macros = 0;
+
+        
+#ifdef OPT_IMPROVED_PATIENCE_EXT
+	static int count = 0;
+	++count;
+	if ( ((count == 100) || !( count % 1000 )) && DEBUG_MAKE )
+	    printf("...patience...\n");
+#endif
+        
+        /* the following regexp is used to detect cases where a  */
+        /* file is included through a line line "#include MACRO" */
+        if ( re_macros == 0 )
+        {
+            re_macros = regex_compile(
+                "^[ 	]*#[ 	]*include[ 	]*([A-Za-z][A-Za-z0-9_]*).*$" );
+        }
+
+
+	if( !( f = fopen( file, "r" ) ) )
+	    return l;
+
+	while( fgets( buf, sizeof( buf ), f ) )
+	{
+	    for( i = 0; i < rec; i++ )
+		if( regexec( re[i], buf ) && re[i]->startp[1] )
+	    {
+		re[i]->endp[1][0] = '\0';
+
+		if( DEBUG_HEADER )
+		    printf( "header found: %s\n", re[i]->startp[1] );
+
+		l = list_new( l, newstr( re[i]->startp[1] ) );
+	    }
+            
+            /* special treatment for #include MACRO */
+            if ( regexec( re_macros, buf ) && re_macros->startp[1] )
+            {
+              char*  header_filename;
+              
+              re_macros->endp[1][0] = '\0';
+              
+              if ( DEBUG_HEADER )
+                printf( "macro header found: %s", re_macros->startp[1] );
+                
+              header_filename = macro_header_get( re_macros->startp[1] );
+              if (header_filename)
+              {
+	        if ( DEBUG_HEADER )
+                  printf( " resolved to '%s'\n", header_filename );
+                l = list_new( l, newstr( header_filename ) );
+              }
+              else
+              {
+	        if ( DEBUG_HEADER )
+                  printf( " ignored !!\n" );
+              }
+            }
+	}
+
+	fclose( f );
+
+	return l;
+}
+
+void
+regerror( char *s )
+{
+	printf( "re error %s\n", s );
+}

Added: boost-jam/boost-build/branches/upstream/current/jam_src/headers.h
===================================================================
--- boost-jam/boost-build/branches/upstream/current/jam_src/headers.h	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/jam_src/headers.h	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,16 @@
+/*
+ * Copyright 1993, 1995 Christopher Seiwald.
+ *
+ * This file is part of Jam - see jam.c for Copyright information.
+ */
+
+/*
+ * headers.h - handle #includes in source files
+ */
+
+void headers( TARGET *t );
+
+#ifdef OPT_HEADER_CACHE_EXT
+struct regexp;
+LIST *headers1( LIST *l, char *file, int rec, struct regexp *re[] );
+#endif

Added: boost-jam/boost-build/branches/upstream/current/jam_src/index.html
===================================================================
--- boost-jam/boost-build/branches/upstream/current/jam_src/index.html	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/jam_src/index.html	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,1220 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+
+<html>
+<head>
+  <meta name="generator" content=
+  "HTML Tidy for Linux/x86 (vers 1st September 2003), see www.w3.org">
+  <meta http-equiv="Content-Type" content="text/html; charset=us-ascii">
+  <link rel="stylesheet" type="text/css" href="../../../../boost.css">
+
+  <title>Boost.Jam</title>
+  <meta name="author" content="Rene Rivera">
+  <meta name="description" content=
+  "Boost.Jam (bjam) is the core build tool for using the Boost.Build system. BJam is based on Perforce's Jam/MR.">
+  </head>
+
+<body link="#0000FF" vlink="#800080">
+  <table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
+  "header">
+    <tbody>
+      <tr>
+        <td valign="top" width="300">
+          <h3><a href="../../../index.htm"><img height="86" width="277" alt=
+          "C++ Boost" src="../../../c++boost.gif" border="0"></a></h3>
+        </td>
+
+        <td valign="top">
+          <h1 align="center">Boost.Jam</h1>
+
+          <h2 align="center"></h2>
+        </td>
+      </tr>
+    </tbody>
+  </table>
+  <hr>
+
+  <dl class="index">
+    <dt><a href="#introduction">Introduction</a></dt>
+
+    <dt><a href="#features">Features</a></dt>
+
+    <dt><a href="#contents">Contents</a></dt>
+
+    <dt><a href="#building_bjam">Building Boost.Jam</a></dt>
+
+    <dt><a href="#core_extensions">Core Jam Extensions</a></dt>
+
+    <dd>
+      <dl class="index">
+        <dt><a href="#variable_quoting">Command-line and Environment Variable
+        Quoting</a></dt>
+
+        <dt><a href="#jambase_replacement">Startup Behavior</a></dt>
+
+        <dt><a href="#rule_indirection">Rule Indirection</a></dt>
+
+        <dt><a href="#argument_lists">Argument Lists</a></dt>
+
+        <dt><a href="#module_support">Module Support</a></dt>
+
+        <dd>
+          <dl class="index">
+            <dt><a href="#module_declaration">Declaration</a></dt>
+
+            <dt><a href="#module_locals">Variable Scope</a></dt>
+
+            <dt><a href="#local_rules">Local Rules</a></dt>
+
+            <dt><a href="#RULENAMES_rule">The <tt>RULENAMES</tt>
+            rule</a></dt>
+
+            <dt><a href="#VARNAMES_rule">The <tt>VARNAMES</tt> rule</a></dt>
+
+            <dt><a href="#IMPORT_rule">The <tt>IMPORT</tt> rule</a></dt>
+
+            <dt><a href="#EXPORT_rule">The <tt>EXPORT</tt> rule</a></dt>
+
+            <dt><a href="#CALLER_MODULE_rule">The
+            <tt>CALLER_MODULE</tt></a></dt>
+
+            <dt><a href="#DELETE_MODULE_rule">The <tt>DELETE_MODULE</tt>
+            rule</a></dt>
+          </dl>
+        </dd>
+
+        <dt><a href="#local_foreach">Local for Loop Variables</a></dt>
+
+        <dt><a href="#negative_indexing">Negative Indexing</a></dt>
+
+        <dt><a href="#cygwin_support">Support for Cygwin</a></dt>
+
+        <dt><a href="#BINDRULE">Target Binding Detection</a></dt>
+
+        <dt><a href="#FAIL_EXPECTED">Return Code Inversion</a></dt>
+
+        <dt><a href="#NOCARE">Ignoring Return Codes</a></dt>
+
+        <dt><a href="#RMOLD">Removing outdated targets</a></dt>
+
+        <dt><a href="#SUBST_rule">The <tt>SUBST</tt> Rule</a></dt>
+
+        <dt><a href="#JAM_VERSION">The <tt>JAM_VERSION</tt> global
+        variable</a></dt>
+
+        <dt><a href="#debugging_support">Debugging Support</a></dt>
+
+        <dd>
+          <dl class="index">
+            <dt><a href="#BACKTRACE_rule">The BACKTRACE rule</a></dt>
+
+            <dt><a href="#profiling">Profiling</a></dt>
+
+            <dt><a href="#parse_debugging">Parser Debugging</a></dt>
+
+            <dt><a href="#dependency_graph">Dependency Graph Output</a></dt>
+          </dl>
+        </dd>
+
+        <dt><a href="#UPDATE">The <tt>UPDATE</tt> rule and changes to command
+        line handling</a></dt>
+
+        <dt><a href="#semaphores">Semaphores</a></dt>
+
+        <dt><a href="#semaphores">The W32_GETREG rule</a></dt>
+      </dl>
+    </dd>
+
+    <dt><a href="#jam_fundamentals">Jam Fundamentals</a></dt>
+  </dl>
+
+  <h2><a name="introduction"></a>Introduction</h2>
+
+  <p>Boost.Jam (BJam) &nbsp;is a build tool based on FTJam, which in turn is
+  based on Perforce Jam. It contains significant improvements made to
+  facilitate its use in the Boost Build System, but should be backward
+  compatible with Perforce Jam.</p>
+
+  <p>This is version 3.1.10 of BJam and is based on version 2.4 of Jam/MR:</p>
+  <pre>
+/+\
++\  Copyright 1993-2002 Christopher Seiwald and Perforce Software, Inc.
+\+/
+This is Release 2.4 of Jam/MR, a make-like program.
+License is hereby granted to use this software and distribute it
+freely, as long as this copyright notice is retained and modifications
+are clearly marked.
+ALL WARRANTIES ARE HEREBY DISCLAIMED.
+</pre>
+
+  <h2><a name="features"></a>Features</h2>
+
+  <p>Jam is a make(1) replacement that makes building simple things simple
+  and building complicated things manageable.</p>
+
+  <p>Jam's language is expressive, making Jamfiles (c.f. Makefiles) compact.
+  Here's a sample:</p>
+  <pre>
+Main smail : main.c map.c resolve.c deliver.c
+     misc.c parser.y alias.c pw.c headers.c
+     scanner.l getpath.c str.c ;
+</pre>
+
+  <p>This builds "smail" from a dozen source files. Jam handles header file
+  dependencies automatically and on-the-fly.</p>
+
+  <p>Jam is very portable: it runs on UNIX, VMS, Mac, and NT. Most Jamfiles
+  themselves are portable, like the sample above.</p>
+
+  <p>Jam is unintrusive: it is small, it has negligible CPU overhead, and it
+  doesn't create any of its own funny files (c.f. Odin, nmake, SunOS
+  make).</p>
+
+  <p>Jam can build large projects spread across many directories in one pass,
+  without recursing, tracking the relationships among all files. Jam can do
+  this with multiple, concurrent processes.</p>
+
+  <p>Jam isn't under the blinkin GNU copyright, so you can incorporate it
+  into commercial products.</p>
+
+  <h2><a name="contents"></a>Contents</h2>
+
+  <table cellpadding="2" cellspacing="2" border="0" summary=
+  "Contents of Jam documents.">
+    <tr>
+      <td valign="top"><a href="Jam.html">Jam.html</a></td>
+
+      <td valign="top">Jam and language reference.</td>
+    </tr>
+
+    <tr>
+      <td valign="top"><a href="Porting">Porting</a></td>
+
+      <td valign="top">Notes on porting jam to wildcat platforms.</td>
+    </tr>
+  </table>
+
+  <h2><a name="building_bjam"></a>Building Boost.Jam</h2>
+
+  <p>Installing BJam after building it is simply a matter of copying the
+  generated executables someplace in your <tt>PATH</tt>. For building the
+  executables there are a set of <tt>build</tt> bootstrap scripts to
+  accomodate particular environments. The scripts take one optional argument,
+  the name of the toolset to build with. When the toolset is not given an
+  attempt is made to detect an available toolset and use that. The build
+  scripts accept these areguments:</p>
+  <pre>
+&lt;build script name&gt; [toolset]
+</pre>
+
+  <p>Running the scripts without arguments will give you the best chance of
+  success. On Windows platforms from a command console do:</p>
+  <pre>
+cd &lt;jam source location&gt;
+.\build.bat
+</pre>
+
+  <p>On Unix type platforms do:</p>
+  <pre>
+cd &lt;jam source location&gt;
+sh ./build.sh
+</pre>
+
+  <p>For the Boost.Jam source included with the Boost distribution the
+  <tt>&lt;jam source location&gt;</tt> is
+  <tt>BOOST_ROOT/tools/build/jam_src.</tt></p>
+
+  <p>If the scripts fail to detect an appropriate toolset to build with your
+  particular toolset may not be auto-detectable. In that case, you can
+  specify the toolset as the first argument, this assumes that the toolset is
+  readily available in the <tt>PATH</tt>. NOTE: The toolset used to build
+  Boost.Jam is independent of the toolsets used for Boost.Build. Only one
+  version of Boost.Jam is needed to use Boost.Build. The supported toolsets,
+  and wether they are auto-detected, are:</p>
+
+  <table cellpadding="2" cellspacing="2" border="1" summary=
+  "Bootstrap supported platforms and toolsets.">
+    <tr>
+      <th valign="top">Script</th>
+
+      <th valign="top">Platforms</th>
+
+      <th valign="top">Toolsets</th>
+
+      <th valign="top">Detection</th>
+    </tr>
+
+    <tr>
+      <td valign="top" rowspan="9" colspan="1"><tt>build.bat</tt></td>
+
+      <td valign="top" rowspan="9" colspan="1">Windows NT, 2000, and XP</td>
+
+      <td valign="top"><a href=
+      "http://www.comeaucomputing.com"><tt>como</tt></a>, Comeau.Computing
+      C/C++</td>
+
+      <td valign="top"></td>
+    </tr>
+
+    <tr>
+      <td valign="top"><a href=
+      "http://www.borland.com/bcppbuilder/freecompiler"><tt>borland</tt></a>,
+      <a href="http://www.borland.com/">Borland</a> C++Builder (BCC 5.5)</td>
+
+      <td valign="top">* Common install location:
+      <tt>"C:\Borland\BCC55"</tt><br>
+      * <tt>BCC32.EXE</tt> in <tt>PATH</tt></td>
+    </tr>
+
+    <tr>
+      <td valign="top"><a href="http://gcc.gnu.org">gcc</a>, GNU GCC</td>
+
+      <td valign="top"></td>
+    </tr>
+
+    <tr>
+      <td valign="top"><a href="http://gcc.gnu.org">gcc-nocygwin</a>, GNU
+      GCC</td>
+
+      <td valign="top"></td>
+    </tr>
+
+    <tr>
+      <td valign="top"><a href=
+      "http://www.intel.com/software/products/compilers/c60"><tt>intel-win32</tt></a>,
+      Intel C++ Compiler for Windows</td>
+
+      <td valign="top">* <tt>ICL.EXE</tt> in <tt>PATH</tt></td>
+    </tr>
+
+    <tr>
+      <td valign="top"><a href=
+      "http://www.metrowerks.com"><tt>metrowerks</tt></a>, MetroWerks
+      CodeWarrior C/C++ 7.x, 8.x</td>
+
+      <td valign="top">* <tt>CWFolder</tt> variable configured<br>
+      * <tt>MWCC.EXE</tt> in <tt>PATH</tt></td>
+    </tr>
+
+    <tr>
+      <td valign="top"><a href="http://www.mingw.org">mingw</a>, GNU <a href=
+      "http://gcc.gnu.org">GCC</a> as the <a href=
+      "http://www.mingw.org">MinGW</a> configuration</td>
+
+      <td valign="top">* Common install location: <tt>"C:\MinGW"</tt></td>
+    </tr>
+
+    <tr>
+      <td valign="top"><a href="http://msdn.microsoft.com/visualc/">msvc</a>,
+      Microsoft Visual C++ 6.x</td>
+
+      <td valign="top">* <tt>VCVARS32.BAT</tt> already configured<br>
+      * Common install locations: <tt>"C:\Program Files\Microsoft Visual
+      Studio"</tt>, <tt>"C:\Program Files\Microsoft Visual C++"<br></tt> *
+      <tt>CL.EXE</tt> in <tt>PATH</tt></td>
+    </tr>
+
+    <tr>
+      <td valign="top"><a href="http://msdn.microsoft.com/visualc/">vc7</a>,
+      Microsoft Visual C++ 7.x</td>
+
+      <td valign="top">* <tt>VCVARS32.BAT</tt> or <tt>VSVARS32.BAT</tt>
+      already configured<br>
+      * Common install location: <tt>"C:\Program Files\Microsoft Visual
+      Studio .NET"</tt><br>
+      * Common install location: <tt>"C:\Program Files\Microsoft Visual
+      Studio .NET 2003"</tt></td>
+    </tr>
+
+    <tr>
+      <td valign="top" rowspan="11" colspan="1"><tt>build.sh</tt></td>
+
+      <td valign="top" rowspan="10" colspan="1">Unix, Linux, Cygwin,
+      etc.</td>
+
+      <td valign="top"><a href="http://www.hp.com/go/c++">acc</a>, HP-UX
+      aCC</td>
+
+      <td valign="top">* <tt>aCC</tt> in <tt>PATH</tt><br>
+      * <tt>uname</tt> is "HP-UX"</td>
+    </tr>
+
+    <tr>
+      <td valign="top"><a href="http://www.comeaucomputing.com">como</a>,
+      Comeau.Computing C/C++</td>
+
+      <td valign="top">* <tt>como</tt> in <tt>PATH</tt></td>
+    </tr>
+
+    <tr>
+      <td valign="top"><a href="http://gcc.gnu.org">gcc</a>, GNU GCC</td>
+
+      <td valign="top">* <tt>gcc</tt> in <tt>PATH</tt></td>
+    </tr>
+
+    <tr>
+      <td valign="top"><a href=
+      "http://www.intel.com/software/products/compilers/c60l/">intel-linux</a>,
+      Intel C++ for Linux</td>
+
+      <td valign="top">* <tt>icc</tt> in <tt>PATH</tt><br>
+      * Common install locations: <tt>"/opt/intel/compiler70"</tt>,
+      <tt>"/opt/intel/compiler60"</tt>, <tt>"/opt/intel/compiler50"</tt></td>
+    </tr>
+
+    <tr>
+      <td valign="top"><a href=
+      "http://developer.intel.com/software/products/kcc/">kcc</a>, Intel KAI
+      C++</td>
+
+      <td valign="top">* <tt>KCC</tt> in <tt>PATH</tt></td>
+    </tr>
+
+    <tr>
+      <td valign="top"><a href=
+      "http://www.borland.com/bcppbuilder/freecompiler"><tt>kylix</tt></a>,
+      <a href="http://www.borland.com/">Borland</a> C++Builder</td>
+
+      <td valign="top">* <tt>bc++</tt> in <tt>PATH</tt></td>
+    </tr>
+
+    <tr>
+      <td valign="top"><a href=
+      "http://www.sgi.com/developers/devtools/languages/mipspro.html">mipspro</a>,
+      SGI MIPSpro C</td>
+
+      <td valign="top"></td>
+    </tr>
+
+    <tr>
+      <td valign="top">sunpro, Sun Workshop 6 C++</td>
+
+      <td valign="top">* Standard install location:
+      <tt>"/opt/SUNWspro"</tt></td>
+    </tr>
+
+    <tr>
+      <td valign="top"><a href=
+      "http://www.tru64unix.compaq.com/cplus/">true64cxx</a>, Compaq C++
+      Compiler for True64 UNIX</td>
+
+      <td valign="top"></td>
+    </tr>
+
+    <tr>
+      <td valign="top"><a href=
+      "http://www-3.ibm.com/software/ad/vacpp/">vacpp</a>, IBM VisualAge
+      C++</td>
+
+      <td valign="top">* <tt>xlc</tt> in <tt>PATH</tt></td>
+    </tr>
+
+    <tr>
+      <td valign="top">MacOS X<br></td>
+
+      <td valign="top"><a href=
+      "http://developer.apple.com/tools/compilers.html">darwin</a>, Apple
+      MacOS X GCC</td>
+
+      <td valign="top">* <tt>uname</tt> is <tt>"Darwin"</tt></td>
+    </tr>
+  </table>
+
+  <p>The built executables are placed in a subdirectory specific to your
+  platform. For example, in Linux running on an Intel x86 compatible chip,
+  the executables are placed in: <tt>"bin.linuxx86"</tt>. There are two
+  executables generated: <tt>jam[.exe]</tt>, and <tt>bjam[.exe]</tt>, both
+  are the same binary but with different names. The "jam" invocation is used
+  for compatability with the Perforce Jam/MR functionality, whereas "bjam" is
+  used for the extended Boost.Build functionality.</p>
+
+  <p>The <tt>build</tt> scripts support additional invocation arguments for
+  use by developers of Boost.Jam. The extra arguments come after the toolset,
+  and can take the form of <tt>"--option"</tt> or targets for the
+  <tt>build.jam</tt> script:</p>
+  <pre>
+&lt;build script name&gt; [toolset] [--option+ target*]
+</pre>
+
+  <p>There is current only one available option, <tt>"--debug"</tt>, which
+  builds debugging versions of the executable. When built they are placed in
+  their own directory <tt>"bin.&lt;platform&gt;.debug"</tt>. To specify
+  targets without options, one can suply a special ignore option
+  <tt>"---"</tt>.</p>
+
+  <p>Currently there are two targets supported: <tt>dist</tt>, and
+  <tt>clean</tt>. Respectively they: generate packages (compressed archives)
+  as appropriate for distribution in the platform, or remove all the built
+  executables and objects.</p>
+
+  <h2><a name="core_extensions">Core Jam Extensions</a></h2>
+
+  <p>A number of enhancements have been made to the core language of Classic
+  Jam. These changes were aimed primarily at making it easier to manage the
+  complexity of a large system such as Boost.Build.</p>
+
+  <h3><a name="variable_quoting"></a>Command-line and Environment Variable
+  Quoting</h3>
+
+  <p>Classic Jam had an <a href="#variable_splitting">odd behavior</a> with
+  respect to command-line variable ( <tt>-s...</tt>) and environment variable
+  settings which made it impossible to define an arbitrary variable with
+  spaces in the value. Boost Jam remedies that by treating all such settings
+  as a single string if they are surrounded by double-quotes. Uses of this
+  feature can look interesting, since shells require quotes to keep
+  characters separated by whitespace from being treated as separate
+  arguments:</p>
+  <pre>
+jam -sMSVCNT="\"\"C:\Program Files\Microsoft Visual C++\VC98\"\"" ...
+</pre>
+
+  <p>The outer quote is for the shell. The middle quote is for Jam, to tell
+  it to take everything within those quotes literally, and the inner quotes
+  are for the shell again when paths are passed as arguments to build
+  actions. Under NT, it looks a lot more sane to use environment variables
+  before invoking jam when you have to do this sort of quoting:</p>
+  <pre>
+set MSVCNT=""C:\Program Files\Microsoft Visual C++\VC98\""
+</pre>
+
+  <h3><a name="jambase_replacement">Startup Behavior</a></h3>
+
+  <p>The Boost.Build v2 initialization behavior has been implemented. This
+  behavior only applies when the executable being invoked is called
+  "<code>bjam</code>" or, for backward-compatibility, when the
+  <code>BOOST_ROOT</code> variable is set.</p>
+
+  <ol>
+    <li>We attempt to load "boost-build.jam" by searching from the current
+    invocation directory up to the root of the file-system. This file is
+    expected to invoke the <tt>boost-build</tt> rule to indicate where the
+    Boost.Build system files are, and to load them.</li>
+
+    <li>If boost-build.jam is not found we error and exit, giving brief
+    instructions on possible errors.
+
+      <blockquote>
+        As a backward-compatibility measure for older versions of
+        Boost.Build, when the <code>BOOST_ROOT</code> variable is set, we
+        first search for <code>boost-build.jam</code> in
+        <code>$(BOOST_ROOT)/tools/build</code> and
+        <code>$(BOOST_BUILD_PATH)</code>. If found, it is loaded and
+        initialization is complete.
+      </blockquote>
+    </li>
+
+    <li>The <code>boost-build</code> rule adds its (optional) argument to the
+    front of <code>BOOST_BUILD_PATH</code>, and attempts to load
+    <code>bootstrap.jam</code> from those directories. If a relative path is
+    specified as an argument, it is treated as though it was relative to the
+    <code>boost-build.jam</code> file.</li>
+
+    <li>If the bootstrap.jam file was not found, we print a likely error
+    message and exit.</li>
+  </ol>
+
+  <h3><a name="rule_indirection">Rule Indirection</a></h3>
+
+  <p>Boost Jam allows you to call a rule whose name is held in a variable or
+  computed as the result of an expression:</p>
+  <pre>
+x = foo ;
+rule foobar { ECHO foobar ; }   # a trivial rule
+$(x)bar ;                       # invokes foobar
+</pre>
+
+  <p>Furthermore, if the first expression expands to more than one list item,
+  everything after the first item becomes part of the first argument. This
+  allows a crude form of argument binding:</p>
+  <pre>
+# return the elements of sequence for which predicate returns non-nil
+rule filter ( sequence * : predicate + )
+{
+    local result ;
+    for local x in $(sequence)
+    {
+        if [ $(predicate) $(x) ] { result += $(x); }
+    }
+    return $(result);
+}
+# true iff x == y
+rule equal ( x y )
+{
+    if $(x) = $(y) { return true; }
+}
+# bind 3 to the first argument of equal
+ECHO [ filter 1 2 3 4 5 4 3 : equal 3 ] ; # prints "3 3"
+</pre>
+
+  <h3><a name="argument_lists">Argument lists</a></h3>
+
+  <p>You can now describe the arguments accepted by a rule, and refer to them
+  by name within the rule. For example, the following prints ``I'm sorry,
+  Dave'' to the console:</p>
+  <pre>
+rule report ( pronoun index ? : state : names + )
+{
+    local he.suffix she.suffix it.suffix = s ;
+    local I.suffix = m ;
+    local they.suffix you.suffix = re ;
+    ECHO $(pronoun)'$($(pronoun).suffix) $(state), $(names[$(index)]) ;
+}
+report I 2 : sorry : Joe Dave Pete ;
+</pre>
+
+  <p>Each name in a list of formal arguments (separated by ``<tt>:</tt>'' in
+  the rule declaration) is bound to a single element of the corresponding
+  actual argument unless followed by one of these modifiers:</p>
+
+  <table border="1" summary="Argument modifiers">
+    <tr>
+      <th>Symbol</th>
+
+      <th>Semantics of preceding symbol</th>
+    </tr>
+
+    <tr>
+      <td><tt>?</tt></td>
+
+      <td>optional</td>
+    </tr>
+
+    <tr>
+      <td><tt>*</tt></td>
+
+      <td>Bind to zero or more unbound elements of the actual argument. When
+      ``<tt>*</tt>'' appears where an argument name is expected, any number
+      of additional arguments are accepted. This feature can be used to
+      implement "varargs" rules.</td>
+    </tr>
+
+    <tr>
+      <td><tt>+</tt></td>
+
+      <td>Bind to one or more unbound elements of the actual argument.</td>
+    </tr>
+  </table>
+
+  <p>The actual and formal arguments are checked for inconsistencies, which
+  cause Jam to exit with an error code:</p>
+  <pre>
+### argument error
+# rule report ( pronoun index ?  : state  : names + )
+# called with: ( I 2 foo  : sorry  : Joe Dave Pete )
+# extra argument foo
+### argument error
+# rule report ( pronoun index ?  : state  : names + )
+# called with: ( I 2  : sorry )
+# missing argument names
+</pre>
+
+  <p>If you omit the list of formal arguments, all checking is bypassed as in
+  ``classic'' Jam. Argument lists drastically improve the reliability and
+  readability of your rules, however, and are <b>strongly recommended</b> for
+  any new Jam code you write.</p>
+
+  <h3><a name="module_support">Module Support</a></h3>
+
+  <p>Boost Jam introduces support for modules, which provide some rudimentary
+  namespace protection for rules and variables. A new keyword,
+  ``<tt>module</tt>'' was also introduced. The features described in this
+  section are <i>primitives</i>, meaning that they are meant to provide the
+  operations needed to write Jam rules which provide a more elegant module
+  interface.</p>
+
+  <h4><a name="module_declaration">Declaration</a></h4>
+  <pre>
+module <i>expression</i> { ... }
+</pre>
+
+  <p>Code within the <tt>{</tt> ... <tt>}</tt> executes within the module
+  named by evaluating <i>expression</i>. Rule definitions can be found in the
+  module's own namespace, and in the namespace of the global module as
+  <i>module-name</i><tt>.</tt><i>rule-name</i>, so within a module, other
+  rules in that module may always be invoked without qualification:</p>
+  <pre>
+<b>module my_module
+{</b>
+    rule salute ( x ) { ECHO $(x), world ; }
+    rule greet ( ) { salute hello ; }
+    greet ;
+<b>}
+my_module.salute</b> goodbye ;
+</pre>
+
+  <p>When an invoked rule is not found in the current module's namespace, it
+  is looked up in the namespace of the global module, so qualified calls work
+  across modules:</p>
+  <pre>
+module your_module
+{
+    rule bedtime ( ) { <b>my_module.salute</b> goodnight ; }
+}
+</pre>
+
+  <h4><a name="module_locals">Variable Scope</a></h4>
+
+  <p>Each module has its own set of dynamically nested variable scopes. When
+  execution passes from module A to module B, all the variable bindings from
+  A become unavailable, and are replaced by the bindings that belong to B.
+  This applies equally to local and global variables:</p>
+  <pre>
+module A
+{
+    x = 1 ;
+    rule f ( )
+    {
+        local y = 999 ; # becomes visible again when B.f calls A.g
+        B.f ;
+    }
+    rule g ( )
+    {
+        ECHO $(y) ;     # prints "999"
+    }
+}
+module B
+{
+    y = 2 ;
+    rule f ( )
+    {
+        ECHO $(y) ; # always prints "2"
+        A.g ;
+    }
+}
+</pre>
+
+  <p>The only way to access another module's variables is by entering that
+  module:</p>
+  <pre>
+rule peek ( module-name ? : variables + )
+{
+    module $(module-name)
+    {
+        return $($(&gt;)) ;
+    }
+}
+</pre>Note that because existing variable bindings change whenever a new
+module scope is entered, argument bindings become unavailable. That explains
+the use of "<code>$(&gt;)</code>" in the <code>peek</code> rule above.
+
+  <h4><a name="local_rules">Local Rules</a></h4>
+  <pre>
+local rule <i>rulename...</i>
+</pre>
+
+  <p>The rule is declared locally to the current module. It is not entered in
+  the global module with qualification, and its name will not appear in the
+  result of:</p>
+  <pre>
+[ RULENAMES <i>module-name</i> ]
+</pre>
+
+  <h4><a name="RULENAMES_rule">The <tt>RULENAMES</tt> Rule</a></h4>
+  <pre>
+rule RULENAMES ( module ? )
+</pre>
+
+  <p>Returns a list of the names of all non-local rules in the given module.
+  If <tt>module</tt> is omitted, the names of all non-local rules in the
+  global module are returned.</p>
+
+  <h4><a name="VARNAMES_rule">The <tt>VARNAMES</tt> Rule</a></h4>
+  <pre>
+rule VARNAMES ( module ? )
+</pre>
+
+  <p>Returns a list of the names of all variable bindings in the given
+  module. If <tt>module</tt> is omitted, the names of all variable bindings
+  in the global module are returned. <b>Note:</b>this includes any local
+  variables in rules from the call stack which have not returned at the time
+  of the <code>VARNAMES</code> invocation.</p>
+
+  <h4><a name="IMPORT_rule">The <tt>IMPORT</tt> Rule</a></h4>
+
+  <p><tt>IMPORT</tt> allows rule name aliasing across modules:</p>
+  <pre>
+rule IMPORT ( source_module ? : source_rules *
+            : target_module ? : target_rules * )
+</pre>
+
+  <p>The <tt>IMPORT</tt> rule copies rules from the <tt>source_module</tt>
+  into the <tt>target_module</tt> as <tt>local</tt> rules. If either
+  <tt>source_module</tt> or <tt>target_module</tt> is not supplied, it refers
+  to the global module. <tt>source_rules</tt> specifies which rules from the
+  <tt>source_module</tt> to import; <tt>TARGET_RULES</tt> specifies the names
+  to give those rules in <tt>target_module</tt>. If <tt>source_rules</tt>
+  contains a name which doesn't correspond to a rule in
+  <tt>source_module</tt>, or if it contains a different number of items than
+  <tt>target_rules</tt>, an error is issued. For example,</p>
+  <pre>
+# import m1.rule1 into m2 as local rule m1-rule1.
+IMPORT m1 : rule1 : m2 : m1-rule1 ;
+# import all non-local rules from m1 into m2
+IMPORT m1 : [ RULENAMES m1 ] : m2 : [ RULENAMES m1 ] ;
+</pre>
+
+  <h4><a name="EXPORT_rule">The <tt>EXPORT</tt> Rule</a></h4>
+
+  <p><tt>EXPORT</tt> allows rule name aliasing across modules:</p>
+  <pre>
+rule EXPORT ( module ? : rules * )
+</pre>
+
+  <p>The <tt>EXPORT</tt> rule marks <tt>rules</tt> from the
+  <tt>source_module</tt> as non-local (and thus exportable). If an element of
+  <tt>rules</tt> does not name a rule in <tt>module</tt>, an error is issued.
+  For example,</p>
+  <pre>
+module X {
+  local rule r { ECHO X.r ; }
+}
+IMPORT X : r : : r ; # error - r is local in X
+EXPORT X : r ;
+IMPORT X : r : : r ; # OK.
+</pre>
+
+  <h4><a name="CALLER_MODULE_rule">The <tt>CALLER_MODULE</tt> Rule</a></h4>
+  <pre>
+rule CALLER_MODULE ( levels ? )
+</pre>
+
+  <p><tt>CALLER_MODULE</tt> returns the name of the module scope enclosing
+  the call to its caller (if levels is supplied, it is interpreted as an
+  integer number of additional levels of call stack to traverse to locate the
+  module). If the scope belongs to the global module, or if no such module
+  exists, returns the empty list. For example, the following prints "{Y}
+  {X}":</p>
+  <pre>
+module X {
+    rule get-caller { return [ CALLER_MODULE ] ; }
+    rule get-caller's-caller { return [ CALLER_MODULE 1 ] ; }
+    rule call-Y { return Y.call-X2 ; }
+}
+module Y {
+    rule call-X { return X.get-caller ; }
+    rule call-X2 { return X.get-caller's-caller ; }
+}
+callers = [ X.get-caller ] [ Y.call-X ] [ X.call-Y ] ;
+ECHO {$(callers)} ;
+</pre>
+
+  <h4><a name="DELETE_MODULE_rule">The <tt>DELETE_MODULE</tt> Rule</a></h4>
+  <pre>
+rule DELETE_MODULE ( module ? )
+</pre>
+
+  <p><tt>DELETE_MODULE</tt> removes all of the variable bindings and
+  otherwise-unreferenced rules from the given module (or the global module,
+  if no module is supplied), and returns their memory to the system.
+  <b>Note:</b> though it won't affect rules that are currently executing
+  until they complete, <code>DELETE_MODULE</code> should be used with extreme
+  care because it will wipe out any others and all variable (including locals
+  in that module) immediately. Because of the way dynamic binding works,
+  variables which are shadowed by locals will not be destroyed, so the
+  results can be really unpredictable.</p>
+
+  <h3><a name="local_foreach">Local For Loop Variables</a></h3>
+
+  <p>Boost Jam allows you to declare a local <tt>for</tt> loop control
+  variable right in the loop:</p>
+  <pre>
+x = 1 2 3 ;
+y = 4 5 6 ;
+for <b>local</b> y in $(x)
+{
+    ECHO $(y) ; # prints "1", "2", or "3"
+}
+ECHO $(y) ;     # prints "4 5 6"
+</pre>
+
+  <h4><a name="negative_indexing">Negative Indexing</a></h4>
+
+  <p>Classic Jam supplies 1-based list indexing, and slicing on a closed
+  (inclusive) range:</p>
+  <pre>
+x = 1 2 3 4 5 ;
+ECHO $(x[3]) ;   # prints "3"
+ECHO $(x[2-4]) ; # prints "2 3 4"
+ECHO $(x[2-]) ;  # prints "2 3 4 5"
+</pre>
+
+  <p>Boost Jam adds Python-style negative indexing to access locations
+  relative to the <i>end</i> of the list.</p>
+  <pre>
+ECHO $(x[-1]) $(x[-3]) ; # prints "5 3"
+ECHO $(x[-3--1]) ;       # prints "3 4 5"
+ECHO $(x[-3-4]) ;        # prints "3 4"
+ECHO $(x[2--2]) ;        # prints "2 3 4"       
+</pre>
+
+  <p>Consistency with the 1-based, inclusive indexing of Classic Jam and the
+  use of ``<tt>-</tt>'' as the range separator make this feature a bit
+  clumsier than it would otherwise need to be, but it does work.</p>
+
+  <h4><a name="cygwin_support">Support for Cygwin</a></h4>
+
+  <p>When invoking Windows-based tools from <a href=
+  "www.cygwin.com">Cygwin</a> it can be important to pass them true
+  windows-style paths. Boost.Jam supplies the <code>:W</code> modifier which,
+  <em>under Cygwin only</em>, turns a cygwin path into a Win32 path using the
+  <a href=
+  "http://www.cygwin.com/cygwin-api/func-cygwin-conv-to-win32-path.html"><code>
+  cygwin_conv_to_win32_path</code></a> function. On other platforms, the
+  string is unchanged.</p>
+  <pre>
+x = /cygdrive/c/Program Files/Borland ;
+ECHO $(x:W) ; # prints "c:\Program Files\Borland" on Cygwin
+</pre>
+
+  <h4><a name="BINDRULE">Target Binding Detection</a></h4>
+
+  <p>Whenever a target is <a href="#binding">bound</a> to a location in the
+  filesystem, Boost Jam will look for a variable called <tt>BINDRULE</tt>
+  (first ``<tt>on</tt>'' the target being bound, then in the global module).
+  If non-empty, <tt>$(BINDRULE[1])</tt> names a rule which is called with the
+  name of the target and the path it is being bound to. The signature of the
+  rule named by <tt>$(BINDRULE[1])</tt> should match the following:</p>
+  <pre>
+rule bind-rule ( target : path )
+</pre>
+
+  <p>This facility is useful for correct header file scanning, since many
+  compilers will search for <tt>#include</tt>d files first in the directory
+  containing the file doing the <tt>#include</tt> directive.
+  <tt>$(BINDRULE)</tt> can be used to make a record of that directory.</p>
+
+  <h4><a name="FAIL_EXPECTED">Return Code Inversion</a></h4>
+
+  <p>For handling targets whose build actions are expected to fail (e.g. when
+  testing that assertions or compile-time type checkin work properly), Boost
+  Jam supplies a <tt>FAIL_EXPECTED</tt> rule in the same style as
+  <tt>NOCARE</tt>, et. al. During target updating, the return code of the
+  build actions for arguments to <tt>FAIL_EXPECTED</tt> is inverted: if it
+  fails, building of dependent targets continues as though it succeeded. If
+  it succeeds, dependent targets are skipped.</p>
+
+  <h4><a name="NOCARE">Ignoring Return Codes</a></h4>
+
+  <p>Perforce Jam supplied a <tt>NOCARE</tt> rule which is typically used for
+  header files to indicate that if they are not found, the dependent targets
+  should be built anyway. Boost Jam extends <tt>NOCARE</tt> to apply to
+  targets with build actions: if their build actions exit with a nonzero
+  return code, dependent targets will still be built.</p>
+
+  <h4><a name="RMOLD">Removing Outdated Targets</a></h4>
+  <pre>
+rule RMOLD ( targets * )
+</pre>
+
+  <p>Perforce Jam removes any target files that may exist on disk when the
+  rule used to build those targets fails. However, targets whose dependencies
+  fail to build are not removed by default. The <code>RMOLD</code> rule
+  causes its arguments to be removed if any of their dependencies fail to
+  build.</p>
+
+  <h3><a name="SUBST_rule">The <tt>SUBST</tt> Rule</a></h3>
+
+  <p><b>Note:</b> the <code>SUBST</code> rule is deprecated in favor of
+  Perforce Jam's built-in <code>MATCH</code> rule, which has been rolled into
+  Boost.Jam.</p>
+
+  <p>The behavior of the <tt>SUBST</tt> rule for regular-expression matching
+  and replacement (originally added in <a href=
+  "http://freetype.sourceforge.net/jam/index.html">FTJam</a>) has been
+  modified:</p>
+
+  <ul>
+    <li>One or more replacement patterns may be supplied. The new signature
+    for <tt>SUBST</tt> is:
+      <pre>
+SUBST ( source pattern replacements + )
+</pre>The return value is the concatenated results of applying each element
+of <tt>replacements</tt> in turn. For example, the following will print
+``<tt>[x] (y) {z}</tt>'':
+      <pre>
+ECHO [ SUBST xyz (.)(.)(.) [$1] ($2) {$3} ] ;
+</pre>
+    </li>
+
+    <li>If there is no match, <tt>SUBST</tt> now returns an empty list. In
+    FTJam, the original <tt>source</tt> string was returned, making it
+    awkward to check whether a pattern was matched.</li>
+
+    <li>Compiled regular expressions are now internally cached, making it
+    much faster to use <tt>SUBST</tt> multiple times with the same
+    string.</li>
+  </ul>
+
+  <h3><a name="JAM_VERSION">The <tt>JAM_VERSION</tt> global variable</a></h3>
+
+  <p>A predefined global variable with two elements indicates the version
+  number of Boost Jam. Boost Jam versions start at <tt>"03" "00"</tt>.
+  Earlier versions of Jam do not automatically define
+  <tt>JAM_VERSION</tt>.</p>
+
+  <h3><a name="debugging_support">Debugging Support</a></h3>
+
+  <h4><a name="BACKTRACE_rule">The BACKTRACE rule</a></h4>
+  <pre>
+rule BACKTRACE ( )
+</pre>
+
+  <p>Returns a list of quadruples: <i>filename line module rulename</i>...,
+  describing each shallower level of the call stack. This rule can be used to
+  generate useful diagnostic messages from Jam rules.</p>
+
+  <p>The <tt>-d</tt> command-line option admits new arguments:</p>
+
+  <ul>
+    <li><tt>-d+10</tt> - enables <a name="profiling"><b>profiling</b></a> of
+    rule invocations. When Jam exits, it dumps all rules invoked, their gross
+    and net times in platform-dependent units, and the number of times the
+    rule was invoked.</li>
+
+    <li><tt>-d+11</tt> - enables <a name="parse_debugging"><b>parser
+    debugging</b></a>, if Jam has been compiled with the "--debug" option to
+    the parser generator named by $(YACC).</li>
+
+    <li><tt>-d+12</tt> - enables <a name="dependency_graph"><b>dependency
+    graph output</b></a> . This feature was ``stolen'' from a version of Jam
+    modified by <a href="mailto:cmcpheeters at aw.sgi.com">Craig
+    McPheeters</a>.</li>
+  </ul>
+
+  <h3><a name="UPDATE">The <tt>UPDATE</tt> rule and changes to command line
+  handling</a></h3>
+
+  <p>Classic jam treats any non-option element of command line as a name of
+  target to be updated. This prevented more sophisticated handling of command
+  line. This is now enabled again but with additional changes to the
+  <tt>UPDATE&gt;</tt> rule to allow for the flexibility of changing the list
+  of targets to update. The <tt>UPDATE</tt> builtin rule is:</p>
+  <pre>
+rule UPDATE ( targets * )
+</pre>
+
+  <p>The rule has two effects: 1. it clears the list of targets to update,
+  and 2. causes the specified targets to be updated. If no target was
+  specified with the <tt>UPDATE</tt> rule, no targets will be updated. To
+  support changing of the update list in more usefull ways, the rule also
+  returns the targets previously in the update list. This makes it possible
+  to add targets as such:</p>
+  <pre>
+local previous-updates = [ UPDATE ] ;
+UPDATE $(previous-updates) a-new-target ;
+</pre>
+
+  <h3 id="semaphores">Semaphores</h3>
+
+  <p>It is sometimes desirable to disallow parallel execution of some
+  actions. For example:</p>
+
+  <ul>
+    <li>Old versions of <tt>yacc</tt> use files with fixed names. So, running
+    two yacc actions is dangerous.</li>
+
+    <li>One might want to perform parallel compiling, but not do parallel
+    linking, because linking is i/o bound and only gets slower.</li>
+  </ul>Craig McPeeters has extended Perforce Jam to solve such problems, and
+  that extension was integrated in Boost.Jam.
+
+  <p>Any target can be assigned a <em>semaphore</em>, by setting a variable
+  called <tt>SEMAPHORE</tt> on that target. The value of the variable is the
+  semaphore name. It must be different from names of any declared target, but
+  is arbitrary otherwise.</p>
+
+  <p>The semantic of semaphores is that in a group of targets which have the
+  same semaphore, only one can be updated at the moment, regardless of "-j"
+  option.</p>
+
+  <h3 id="w32_getreg">The W32_GETREG rule</h3>
+<pre>
+    rule W32_GETREG ( path : data ? )
+</pre>
+
+<p>    
+    Defined only for win32 platform. It reads the registry of Windows.
+    'path' is the location of the information, and 'data' is
+    the name of the value which we want to get. If 'data' is omitted,
+    the default value of 'path' will be returned. The 'path' value
+    must conform to MS key path format and must be prefixed with
+    one of the predefined root keys. As usual,
+
+<ul>    
+    <li>'HKLM' is equivalent to 'HKEY_LOCAL_MACHINE'.
+    <li>'HKCU' is equivalent to 'HKEY_CURRENT_USER'.
+    <li>'HKCR' is equivalent to 'HKEY_CLASSES_ROOT'.
+</ul>    
+    
+<p>    
+    Other predefined root keys are not supported.    
+<p>    
+    Currently supported data types : 'REG_DWORD', 'REG_SZ',
+    'REG_EXPAND_SZ', 'REG_MULTI_SZ'. The data with 'REG_DWORD' type
+    will be turned into a string, 'REG_MULTI_SZ' into a list of strings,
+    and for those with 'REG_EXPAND_SZ' type environment variables
+    in it will be replaced with their defined values.
+    The data with 'REG_SZ' type and other unsupported types
+    will be put into a string without modification. If it can't
+    receive the value of the data, it just return an empty list.
+    For example,
+
+<pre>
+    local PSDK-location =
+    [ PROFILE HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\MicrosoftSDK\\Directories : "Install Dir" ] ;
+</pre>
+
+  <h2><a name="jam_fundamentals">Jam Fundamentals</a></h2>
+
+  <p>This section is derived from the official Jam documentation and from my
+  experience using it and reading the Jambase rules. I repeat the information
+  here mostly because it is essential to understanding and using Jam, but is
+  not consolidated in a single place. Some of it is missing from the official
+  documentation altogether. I hope it will be useful to anyone wishing to
+  become familiar with Jam and the Boost build system.</p>
+
+  <p>&middot; Jam ``<b>rules</b>'' are actually simple procedural entities.
+  Think of them as functions. Arguments are separated by colons.</p>
+
+  <p>&middot; A Jam <b>target</b> is an abstract entity identified by an
+  arbitrary string. The build-in <tt>DEPENDS</tt> rule creates a link in the
+  dependency graph between the named targets.</p>
+
+  <p>&middot; Note that the documentation for the built-in <tt>INCLUDES</tt>
+  rule is incorrect: <tt>INCLUDES targets1 : targets2</tt> causes everything
+  that depends on a member of <i>targets1</i> to depend on all members of
+  <i>targets2</i>. It does this in an odd way, by tacking <i>targets2</i>
+  onto a special tail section in the dependency list of everything in
+  <i>targets1</i>. It seems to be OK to create circular dependencies this
+  way; in fact, it appears to be the ``right thing to do'' when a single
+  build action produces both <i>targets1</i> and <i>targets2</i>.</p>
+
+  <p>&middot; When a rule is invoked, if there are <b><tt>actions</tt></b>
+  declared with the same name as the rule, the <tt>actions</tt> are added to
+  the updating actions for the target identified by the rule's first
+  argument. It is actually possible to invoke an undeclared rule if
+  corresponding actions are declared: the rule is treated as empty.</p>
+
+  <p>&middot; <a name="binding">Targets</a> (other than <tt>NOTFILE</tt>
+  targets) are associated with paths in the file system through a process
+  called <a href="./Jam.html#binding">binding</a>. Binding is a process of
+  searching for a file with the same name as the target (sans grist), based
+  on the settings of the <a href="#target_specific">target-specific</a>
+  <tt>SEARCH</tt> and <tt>LOCATE</tt> variables.</p>
+
+  <p>&middot; <a name="target_specific">In addition to</a> local and global
+  variables, jam allows you to set a variable <tt><b>on</b></tt> a target.
+  Target-specific variable values can usually not be read, and take effect
+  <i>only</i> in the following contexts:</p>
+
+  <ul>
+    <li>In updating <tt>actions</tt>, variable values are first looked up
+    <tt><b>on</b></tt> the target named by the first argument (the target
+    being updated). Because Jam builds its entire dependency tree before
+    executing <tt>actions</tt>, Jam rules make target-specific variable
+    settings as a way of supplying parameters to the corresponding
+    <tt>actions</tt>.</li>
+
+    <li>Binding is controlled <i>entirely</i> by the target-specific setting
+    of the <tt>SEARCH</tt> and <tt>LOCATE</tt> variables, as described
+    <a href="./Jam.html#search">here</a>.</li>
+
+    <li>In the special rule used for <a href="./Jam.html#hdrscan">header file
+    scanning</a>, variable values are first looked up <tt><b>on</b></tt> the
+    target named by the rule's first argument (the source file being
+    scanned).</li>
+  </ul>
+
+  <p>&middot; The ``<b>bound value</b>'' of a variable is the path associated
+  with the target named by the variable. In build <tt>actions</tt>, the first
+  two arguments are automatically replaced with their bound values.
+  Target-specific variables can be selectively replaced by their bound values
+  using the <a href="./Jam.html#actionmods">bind</a> action modifier.</p>
+
+  <p>&middot; Note that the term ``binding'' as used in the Jam documentation
+  indicates a phase of processing that includes three sub-phases:
+  <i>binding</i> (yes!), update determination, and header file scanning. The
+  repetition of the term ``binding'' can lead to some confusion. In
+  particular, the <a href="./Jam.html#bindingmods">Modifying Binding</a>
+  section in the Jam documentation should probably be titled ``Modifying
+  Update Determination''.</p>
+
+  <p>&middot; ``Grist'' is just a string prefix of the form
+  <tt>&lt;</tt><i>characters</i><tt>&gt;</tt>. It is used in Jam to create
+  unique target names based on simpler names. For example, the file name
+  ``<tt>test.exe</tt>'' may be used by targets in separate subprojects, or
+  for the debug and release variants of the ``same'' abstract target. Each
+  distinct target bound to a file called ``<tt>test.exe</tt>'' has its own
+  unique grist prefix. The Boost build system also takes full advantage of
+  Jam's ability to divide strings on grist boundaries, sometimes
+  concatenating multiple gristed elements at the beginning of a string. Grist
+  is used instead of identifying targets with absolute paths for two
+  reasons:</p>
+
+  <ol>
+    <li>The location of targets cannot always be derived solely from what the
+    user puts in a Jamfile, but sometimes depends also on the <a href=
+    "#binding">binding</a> process. Some mechanism to distinctly identify
+    targets with the same name is still needed.</li>
+
+    <li>Grist allows us to use a uniform abstract identifier for each built
+    target, regardless of target file location (as allowed by setting
+    <tt>ALL_LOCATE_TARGET</tt>.</li>
+  </ol>
+
+  <p>When grist is extracted from a name with
+  <tt>$(</tt><i>var</i><tt>:G)</tt>, the result includes the leading and
+  trailing angle brackets. When grist is added to a name with
+  <tt>$(</tt><i>var</i><tt>:G=</tt><i>expr</i><tt>)</tt>, existing grist is
+  first stripped. Then, if <i>expr</i> is non-empty, leading <tt>&lt;</tt>s
+  and trailing <tt>&gt;</tt>s are added if necessary to form an expression of
+  the form <tt>&lt;</tt><i>expr2</i><tt>&gt;</tt>;
+  <tt>&lt;</tt><i>expr2</i><tt>&gt;</tt> is then prepended.</p>
+
+  <p>&middot; <a name="variable_splitting">When Jam</a> is invoked it imports
+  all environment variable settings into corresponding Jam variables,
+  followed by all command-line (<tt>-s...</tt>) variable settings. Variables
+  whose name ends in <tt>PATH</tt>, <tt>Path</tt>, or <tt>path</tt> are split
+  into string lists on OS-specific path-list separator boundaries (e.g.
+  "<tt>:</tt>" for UNIX and "<tt>;</tt>" for Windows). All other variables
+  are split on space (" ") boundaries. Boost Jam modifies that behavior by
+  allowing variables to be <a href="#variable_quoting">quoted</a>.</p>
+
+  <p>&middot; A variable whose value is an empty list <i>or</i> which
+  consists entirely of empty strings has a negative logical value. Thus, for
+  example, code like the following allows a sensible non-empty default which
+  can easily be overridden by the user:</p>
+  <pre>
+MESSAGE ?= starting jam... ;
+if $(MESSAGE) { ECHO The message is: $(MESSAGE) ; }
+</pre>
+
+  <p>If the user wants a specific message, he invokes jam with
+  <tt>"-sMESSAGE=</tt><i>message text</i><tt>"</tt>. If he wants no message,
+  he invokes jam with <tt>-sMESSAGE=</tt> and nothing at all is printed.</p>
+
+  <p>&middot; The parsing of command line options in Jam can be rather
+  unintuitive, with regards to how other Unix programs accept options. There
+  are two variants accepted as valid for an option:</p>
+
+  <ol>
+    <li><tt>-xvalue</tt>, and</li>
+
+    <li><tt>-x value</tt>.</li>
+  </ol>
+
+  <p>Please also read <a href="./Jam.html">The Jam language reference</a> for
+  the additional details.</p>
+  <hr>
+
+  <p>Revised 
+  <!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
+   18 November, 2003 
+  <!--webbot bot="Timestamp" endspan i-checksum="39359" --></p>
+
+  <p>Copyright 2003-2004 Rene Rivera, David Abrahams, Vladimir Prus.</p>
+
+  <p>Distributed under the Boost Software License, Version 1.0.
+  (See accompanying file LICENSE_1_0.txt or <a href="http://www.boost.org/LICENSE_1_0.txt">
+  http://www.boost.org/LICENSE_1_0.txt)</a></p>
+</body>
+</html>

Added: boost-jam/boost-build/branches/upstream/current/jam_src/jam.c
===================================================================
--- boost-jam/boost-build/branches/upstream/current/jam_src/jam.c	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/jam_src/jam.c	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,467 @@
+/*
+ * /+\
+ * +\	Copyright 1993-2002 Christopher Seiwald and Perforce Software, Inc.
+ * \+/
+ *
+ * This file is part of jam.
+ *
+ * License is hereby granted to use this software and distribute it
+ * freely, as long as this copyright notice is retained and modifications 
+ * are clearly marked.
+ *
+ * ALL WARRANTIES ARE HEREBY DISCLAIMED.
+ */
+
+/*  This file is ALSO:
+ *  Copyright 2001-2004 David Abrahams.
+ *  Distributed under the Boost Software License, Version 1.0.
+ *  (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+ */
+
+/*
+ * jam.c - make redux
+ *
+ * See Jam.html for usage information.
+ *
+ * These comments document the code.
+ *
+ * The top half of the code is structured such:
+ *
+ *                       jam 
+ *                      / | \ 
+ *                 +---+  |  \
+ *                /       |   \ 
+ *         jamgram     option  \ 
+ *        /  |   \              \
+ *       /   |    \              \
+ *      /    |     \             |
+ *  scan     |     compile      make
+ *   |       |    /  | \       / |  \
+ *   |       |   /   |  \     /  |   \
+ *   |       |  /    |   \   /   |    \
+ * jambase parse     |   rules  search make1
+ *                   |           |      |   \
+ *                   |           |      |    \
+ *                   |           |      |     \
+ *               builtins    timestamp command execute
+ *                               |
+ *                               |
+ *                               |
+ *                             filesys
+ *
+ *
+ * The support routines are called by all of the above, but themselves
+ * are layered thus:
+ *
+ *                     variable|expand
+ *                      /  |   |   |
+ *                     /   |   |   |
+ *                    /    |   |   |
+ *                 lists   |   |   pathsys
+ *                    \    |   |
+ *                     \   |   |
+ *                      \  |   |
+ *                     newstr  |
+ *                        \    |
+ *                         \   |
+ *                          \  |
+ *                          hash
+ *
+ * Roughly, the modules are:
+ *
+ *	builtins.c - jam's built-in rules
+ *	command.c - maintain lists of commands
+ *	compile.c - compile parsed jam statements
+ *	execunix.c - execute a shell script on UNIX
+ *	execvms.c - execute a shell script, ala VMS
+ *	expand.c - expand a buffer, given variable values
+ *	file*.c - scan directories and archives on *
+ *	hash.c - simple in-memory hashing routines 
+ *  hdrmacro.c - handle header file parsing for filename macro definitions
+ *	headers.c - handle #includes in source files
+ *	jambase.c - compilable copy of Jambase
+ *	jamgram.y - jam grammar
+ *	lists.c - maintain lists of strings
+ *	make.c - bring a target up to date, once rules are in place
+ *	make1.c - execute command to bring targets up to date
+ *	newstr.c - string manipulation routines
+ *	option.c - command line option processing
+ *	parse.c - make and destroy parse trees as driven by the parser
+ *	path*.c - manipulate file names on *
+ *	hash.c - simple in-memory hashing routines 
+ *	regexp.c - Henry Spencer's regexp
+ *	rules.c - access to RULEs, TARGETs, and ACTIONs
+ *	scan.c - the jam yacc scanner
+ *	search.c - find a target along $(SEARCH) or $(LOCATE) 
+ *	timestamp.c - get the timestamp of a file or archive member
+ *	variable.c - handle jam multi-element variables
+ *
+ * 05/04/94 (seiwald) - async multiprocess (-j) support
+ * 02/08/95 (seiwald) - -n implies -d2.
+ * 02/22/95 (seiwald) - -v for version info.
+ * 09/11/00 (seiwald) - PATCHLEVEL folded into VERSION.
+ * 01/10/01 (seiwald) - pathsys.h split from filesys.h
+ */
+
+# include "jam.h"
+# include "option.h"
+# include "patchlevel.h"
+
+/* These get various function declarations. */
+
+# include "lists.h"
+# include "parse.h"
+# include "variable.h"
+# include "compile.h"
+# include "builtins.h"
+# include "rules.h"
+# include "newstr.h"
+# include "scan.h"
+# include "timestamp.h"
+# include "make.h"
+# include "strings.h"
+# include "expand.h"
+
+/* Macintosh is "special" */
+
+# ifdef OS_MAC
+# include <QuickDraw.h>
+# endif
+
+/* And UNIX for this */
+
+# ifdef unix
+# include <sys/utsname.h>
+# endif
+
+struct globs globs = {
+	0,			/* noexec */
+	1,			/* jobs */
+	0,			/* quitquick */
+	0,			/* newestfirst */
+# ifdef OS_MAC
+	{ 0, 0 },		/* debug - suppress tracing output */
+# else
+	{ 0, 1 }, 		/* debug ... */
+# endif
+	0			/* output commands, not run them */
+} ;
+
+/* Symbols to be defined as true for use in Jambase */
+
+static char *othersyms[] = { OSMAJOR, OSMINOR, OSPLAT, JAMVERSYM, 0 } ;
+
+/* Known for sure: 
+ *	mac needs arg_enviro
+ *	OS2 needs extern environ
+ */
+
+# ifdef OS_MAC
+# define use_environ arg_environ
+# ifdef MPW
+QDGlobals qd;
+# endif
+# endif
+
+/* on Win32-LCC */
+# if defined( OS_NT ) && defined( __LCC__ )
+#   define  use_environ _environ
+# endif
+
+# if defined( __MWERKS__)
+# define use_environ _environ
+extern char **_environ;
+#endif
+
+# ifndef use_environ
+# define use_environ environ
+# if !defined( __WATCOM__ ) && !defined( OS_OS2 ) && !defined( OS_NT ) 
+extern char **environ;
+# endif
+# endif
+
+# if YYDEBUG != 0
+extern int yydebug;
+# endif
+
+#ifndef NDEBUG
+static void run_unit_tests()
+{
+# if defined( USE_EXECNT )
+    extern void execnt_unit_test();
+    execnt_unit_test();
+# endif 
+    string_unit_test();
+    var_expand_unit_test();
+}
+#endif
+
+int  main( int argc, char **argv, char **arg_environ )
+{
+    int		n;
+    char		*s;
+    struct option	optv[N_OPTS];
+    const char	*all = "all";
+    int		anyhow = 0;
+    int		status;
+    int arg_c = argc;
+    char ** arg_v = argv;
+
+# ifdef OS_MAC
+    InitGraf(&qd.thePort);
+# endif
+
+    argc--, argv++;
+
+	if( ( n = getoptions( argc, argv, "-:d:j:f:gs:t:ano:qv", optv ) ) < 0 )
+    {
+        printf( "\nusage: jam [ options ] targets...\n\n" );
+
+        printf( "-a      Build all targets, even if they are current.\n" );
+        printf( "-dx     Set the debug level to x (0-9).\n" );
+        printf( "-fx     Read x instead of Jambase.\n" );
+	    /* printf( "-g      Build from newest sources first.\n" ); */
+        printf( "-jx     Run up to x shell commands concurrently.\n" );
+        printf( "-n      Don't actually execute the updating actions.\n" );
+        printf( "-ox     Write the updating actions to file x.\n" );
+		printf( "-q      Quit quickly as soon as a target fails.\n" );
+        printf( "-sx=y   Set variable x=y, overriding environment.\n" );
+        printf( "-tx     Rebuild x, even if it is up-to-date.\n" );
+        printf( "-v      Print the version of jam and exit.\n" );
+        printf( "--x     Option is ignored.\n\n" );
+
+        exit( EXITBAD );
+    }
+
+    argc -= n, argv += n;
+
+    /* Version info. */
+
+    if( ( s = getoptval( optv, 'v', 0 ) ) )
+    {
+        printf( "Boost.Jam  " );
+        printf( "Version %s. %s.\n", VERSION, OSMINOR );
+	   printf( "   Copyright 1993-2002 Christopher Seiwald and Perforce Software, Inc.  \n" );
+        printf( "   Copyright 2001 David Turner.\n" );
+        printf( "   Copyright 2001-2004 David Abrahams.\n" );
+        printf( "   Copyright 2002-2004 Rene Rivera.\n" );
+
+        return EXITOK;
+    }
+
+    /* Pick up interesting options */
+
+    if( ( s = getoptval( optv, 'n', 0 ) ) )
+        globs.noexec++, globs.debug[2] = 1;
+
+	if( ( s = getoptval( optv, 'q', 0 ) ) )
+ 	    globs.quitquick = 1;
+    if( ( s = getoptval( optv, 'a', 0 ) ) )
+        anyhow++;
+
+    if( ( s = getoptval( optv, 'j', 0 ) ) )
+        globs.jobs = atoi( s );
+
+	if( ( s = getoptval( optv, 'g', 0 ) ) )
+	    globs.newestfirst = 1;
+
+    /* Turn on/off debugging */
+
+    for( n = 0; s = getoptval( optv, 'd', n ); n++ )
+    {
+        int i;
+
+        /* First -d, turn off defaults. */
+
+        if( !n )
+            for( i = 0; i < DEBUG_MAX; i++ )
+                globs.debug[i] = 0;
+
+        i = atoi( s );
+
+        if( i < 0 || i >= DEBUG_MAX )
+        {
+            printf( "Invalid debug level '%s'.\n", s );
+            continue;
+        }
+
+        /* n turns on levels 1-n */
+        /* +n turns on level n */
+
+        if( *s == '+' )
+            globs.debug[i] = 1;
+        else while( i )
+            globs.debug[i--] = 1;
+    }
+
+#ifndef NDEBUG
+    run_unit_tests();
+#endif
+#if YYDEBUG != 0
+    if ( DEBUG_PARSE )
+        yydebug = 1;
+#endif
+
+    /* Set JAMDATE first */
+
+    {
+        char *date;
+        time_t clock;
+        time( &clock );
+        date = newstr( ctime( &clock ) );
+
+        /* Trim newline from date */
+
+        if( strlen( date ) == 25 )
+            date[ 24 ] = 0;
+
+        var_set( "JAMDATE", list_new( L0, newstr( date ) ), VAR_SET );
+    }
+
+ 
+    {
+   /* Pleace don't change the following line. The 'bump_version.py' script
+       expect a specific format of it. */
+    char  *major_version = "03", *minor_version = "01", *changenum = "10";
+    var_set( "JAM_VERSION",
+             list_new( list_new( list_new( L0, newstr( major_version ) ), 
+                                 newstr( minor_version ) ), 
+                       newstr( changenum ) ),
+             VAR_SET );
+    }
+
+    /* And JAMUNAME */
+# ifdef unix
+    {
+        struct utsname u;
+
+        if( uname( &u ) >= 0 )
+        {
+            var_set( "JAMUNAME", 
+                     list_new( 
+                         list_new(
+                             list_new(
+                                 list_new(
+                                     list_new( L0, 
+                                               newstr( u.sysname ) ),
+                                     newstr( u.nodename ) ),
+                                 newstr( u.release ) ),
+                             newstr( u.version ) ),
+                         newstr( u.machine ) ), VAR_SET );
+        }
+    }
+# endif /* unix */
+
+    /* load up environment variables */
+
+    var_defines( use_environ );
+
+	/*
+	 * Jam defined variables OS, OSPLAT
+     * We load them after environment, so that
+     * setting OS in environment does not 
+     * change Jam notion of the current platform.
+	 */
+
+    var_defines( othersyms );
+
+
+    /* Load up variables set on command line. */
+
+    for( n = 0; s = getoptval( optv, 's', n ); n++ )
+    {
+        char *symv[2];
+        symv[0] = s;
+        symv[1] = 0;
+        var_defines( symv );
+    }
+
+    /* Set the ARGV to reflect the complete list of arguments of invocation. */
+
+    for ( n = 0; n < arg_c; ++n )
+    {
+        var_set( "ARGV", list_new( L0, newstr( arg_v[n] ) ), VAR_APPEND );
+    }
+
+	/* Initialize built-in rules */
+
+	load_builtins();
+
+    /* Add the targets in the command line to update list */
+
+    for ( n = 0; n < argc; ++n )
+    {
+        mark_target_for_updating(argv[n]);
+    }
+
+    /* Parse ruleset */
+
+    {
+        FRAME frame[1];
+        frame_init( frame );
+	for( n = 0; s = getoptval( optv, 'f', n ); n++ )
+	    parse_file( s, frame );
+
+	if( !n )
+	    parse_file( "+", frame );
+    }
+
+    status = yyanyerrors();
+
+    /* Manually touch -t targets */
+
+    for( n = 0; s = getoptval( optv, 't', n ); n++ )
+        touchtarget( s );
+
+    /* If an output file is specified, set globs.cmdout to that */
+
+    if( s = getoptval( optv, 'o', 0 ) )
+    {
+        if( !( globs.cmdout = fopen( s, "w" ) ) )
+        {
+            printf( "Failed to write to '%s'\n", s );
+            exit( EXITBAD );
+        }
+        globs.noexec++;
+    }
+
+    /* Now make target */
+
+    {
+        LIST* targets = targets_to_update();
+        if ( !targets )
+        {
+            status |= make( 1, &all, anyhow );
+        }
+        else 
+        {
+            int targets_count = list_length(targets);
+            const char **targets2 = (const char **)malloc(targets_count * sizeof(char *));
+            int n = 0;
+            for ( ; targets; targets = list_next(targets) )
+            {
+                targets2[n++] = targets->string;
+            }
+            status |= make( targets_count, targets2, anyhow );       
+            free(targets);
+        }
+    }
+
+
+    if ( DEBUG_PROFILE )
+        profile_dump();
+
+    /* Widely scattered cleanup */
+
+    var_done();
+    donerules();
+    donestamps();
+    donestr();
+
+    /* close cmdout */
+
+    if( globs.cmdout )
+        fclose( globs.cmdout );
+
+    return status ? EXITBAD : EXITOK;
+}

Added: boost-jam/boost-build/branches/upstream/current/jam_src/jam.h
===================================================================
--- boost-jam/boost-build/branches/upstream/current/jam_src/jam.h	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/jam_src/jam.h	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,531 @@
+/*
+ * Copyright 1993, 1995 Christopher Seiwald.
+ *
+ * This file is part of Jam - see jam.c for Copyright information.
+ */
+
+/*  This file is ALSO:
+ *  Copyright 2001-2004 David Abrahams.
+ *  Distributed under the Boost Software License, Version 1.0.
+ *  (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+ */
+
+/*
+ * jam.h - includes and globals for jam
+ *
+ * 04/08/94 (seiwald) - Coherent/386 support added.
+ * 04/21/94 (seiwald) - DGUX is __DGUX__, not just __DGUX.
+ * 05/04/94 (seiwald) - new globs.jobs (-j jobs)
+ * 11/01/94 (wingerd) - let us define path of Jambase at compile time.
+ * 12/30/94 (wingerd) - changed command buffer size for NT (MS-DOS shell).
+ * 02/22/95 (seiwald) - Jambase now in /usr/local/lib.
+ * 04/30/95 (seiwald) - FreeBSD added.  Live Free or Die.
+ * 05/10/95 (seiwald) - SPLITPATH character set up here.
+ * 08/20/95 (seiwald) - added LINUX.
+ * 08/21/95 (seiwald) - added NCR.
+ * 10/23/95 (seiwald) - added SCO.
+ * 01/03/96 (seiwald) - SINIX (nixdorf) added.
+ * 03/13/96 (seiwald) - Jambase now compiled in; remove JAMBASE variable.
+ * 04/29/96 (seiwald) - AIX now has 31 and 42 OSVERs.
+ * 11/21/96 (peterk)  - added BeOS with MW CW mwcc
+ * 12/21/96 (seiwald) - OSPLAT now defined for NT.
+ * 07/19/99 (sickel)  - Mac OS X Server and Client support added
+ * 02/18/00 (belmonte)- Support for Cygwin.
+ * 09/12/00 (seiwald) - OSSYMS split to OSMAJOR/OSMINOR/OSPLAT
+ * 12/29/00 (seiwald) - OSVER dropped.
+ */
+
+#ifndef JAM_H_VP_2003_08_01
+#define JAM_H_VP_2003_08_01
+/*
+ * VMS, OPENVMS
+ */
+
+# ifdef VMS
+
+# include <types.h>
+# include <file.h>
+# include <stat.h>
+# include <stdio.h>
+# include <ctype.h>
+# include <stdlib.h>
+# include <signal.h>
+# include <string.h>
+# include <time.h>
+# include <unistd.h>
+# include <unixlib.h>
+
+# define OSMINOR "OS=VMS"
+# define OSMAJOR "VMS=true"
+# define OS_VMS
+# define MAXLINE 1024 /* longest 'together' actions */
+# define SPLITPATH ','
+# define EXITOK 1
+# define EXITBAD 0
+# define DOWNSHIFT_PATHS
+
+/* This may be inaccurate */
+# ifndef __DECC
+# define OSPLAT "OSPLAT=VAX"
+# endif 
+
+# endif
+
+/*
+ * Windows NT
+ */
+
+# ifdef NT
+
+# include <fcntl.h>
+# include <stdlib.h>
+# include <stdio.h>
+# include <ctype.h>
+# include <malloc.h>
+# ifndef __MWERKS__
+# include <memory.h>
+#endif
+# include <signal.h>
+# include <string.h>
+# include <time.h>
+
+# define OSMAJOR "NT=true"
+# define OSMINOR "OS=NT"
+# define OS_NT
+# define SPLITPATH ';'
+/* Windows NT 3.51 only allows 996 chars per line, but we deal */
+/* with problem in "execnt.c".                                 */
+# define MAXLINE (maxline())	/* longest 'together' actions */
+# define USE_EXECNT
+# define USE_PATHUNIX
+# define PATH_DELIM '\\'
+# define DOWNSHIFT_PATHS
+
+/* AS400 cross-compile from NT */
+
+# ifdef AS400
+# undef OSMINOR
+# undef OSMAJOR
+# define OSMAJOR "AS400=true"
+# define OSMINOR "OS=AS400"
+# define OS_AS400
+# endif
+
+# endif
+
+/*
+ * Windows MingW32
+ */
+
+# ifdef MINGW
+
+# include <fcntl.h>
+# include <stdlib.h>
+# include <stdio.h>
+# include <ctype.h>
+# include <malloc.h>
+# include <memory.h>
+# include <signal.h>
+# include <string.h>
+# include <time.h>
+
+# define OSMAJOR "MINGW=true"
+# define OSMINOR "OS=MINGW"
+# define OS_NT
+# define SPLITPATH ';'
+# define MAXLINE 996	/* longest 'together' actions */
+# define USE_EXECUNIX
+# define USE_PATHUNIX
+# define PATH_DELIM '\\'
+# define DOWNSHIFT_PATHS
+
+# endif
+
+/*
+ * OS2
+ */
+
+# ifdef __OS2__
+
+# include <fcntl.h>
+# include <stdlib.h>
+# include <stdio.h>
+# include <ctype.h>
+# include <malloc.h>
+# include <signal.h>
+# include <string.h>
+# include <time.h>
+
+# define OSMAJOR "OS2=true"
+# define OSMINOR "OS=OS2"
+# define OS_OS2
+# define SPLITPATH ';'
+# define MAXLINE 996	/* longest 'together' actions */
+# define USE_EXECUNIX
+# define USE_PATHUNIX
+# define PATH_DELIM '\\'
+# define DOWNSHIFT_PATHS
+
+# ifdef __EMX__
+#   define USE_FILEUNIX
+# endif
+
+# endif
+
+/*
+ * Macintosh MPW
+ */
+
+# ifdef macintosh
+
+# include <time.h>
+# include <stdlib.h>
+# include <string.h>
+# include <stdio.h>
+
+# define OSMAJOR "MAC=true"
+# define OSMINOR "OS=MAC"
+# define OS_MAC
+# define SPLITPATH ','
+
+# endif
+
+/*
+ * God fearing UNIX
+ */
+
+# ifndef OSMINOR
+
+# define OSMAJOR "UNIX=true"
+# define USE_EXECUNIX
+# define USE_FILEUNIX
+# define USE_PATHUNIX
+# define PATH_DELIM '/'
+
+# ifdef _AIX
+# define unix
+# define OSMINOR "OS=AIX"
+# define OS_AIX
+# define NO_VFORK
+# endif
+# ifdef AMIGA
+# define OSMINOR "OS=AMIGA"
+# define OS_AMIGA
+# endif
+# ifdef __BEOS__
+# define unix
+# define OSMINOR "OS=BEOS"
+# define OS_BEOS
+# define NO_VFORK
+# endif
+# ifdef __bsdi__
+# define OSMINOR "OS=BSDI"
+# define OS_BSDI
+# endif
+# if defined (COHERENT) && defined (_I386)
+# define OSMINOR "OS=COHERENT"
+# define OS_COHERENT
+# define NO_VFORK
+# endif
+# if defined(__cygwin__) || defined(__CYGWIN__)
+# define OSMINOR "OS=CYGWIN"
+# define OS_CYGWIN
+# endif
+# ifdef __FreeBSD__
+# define OSMINOR "OS=FREEBSD"
+# define OS_FREEBSD
+# endif
+# ifdef __DGUX__
+# define OSMINOR "OS=DGUX"
+# define OS_DGUX
+# endif
+# ifdef __hpux
+# define OSMINOR "OS=HPUX"
+# define OS_HPUX
+# endif
+# ifdef __OPENNT
+# define unix
+# define OSMINOR "OS=INTERIX"
+# define OS_INTERIX
+# define NO_VFORK
+# endif
+# ifdef __sgi
+# define OSMINOR "OS=IRIX"
+# define OS_IRIX
+# define NO_VFORK
+# endif
+# ifdef __ISC
+# define OSMINOR "OS=ISC"
+# define OS_ISC
+# define NO_VFORK
+# endif
+# ifdef linux
+# define OSMINOR "OS=LINUX"
+# define OS_LINUX
+# endif
+# ifdef __Lynx__
+# define OSMINOR "OS=LYNX"
+# define OS_LYNX
+# define NO_VFORK
+# define unix
+# endif
+# ifdef __MACHTEN__
+# define OSMINOR "OS=MACHTEN"
+# define OS_MACHTEN
+# endif
+# ifdef mpeix
+# define unix
+# define OSMINOR "OS=MPEIX"
+# define OS_MPEIX
+# define NO_VFORK
+# endif
+# ifdef __MVS__
+# define unix
+# define OSMINOR "OS=MVS"
+# define OS_MVS
+# endif
+# ifdef _ATT4
+# define OSMINOR "OS=NCR"
+# define OS_NCR
+# endif
+# ifdef __NetBSD__
+# define unix
+# define OSMINOR "OS=NETBSD"
+# define OS_NETBSD
+# define NO_VFORK
+# endif
+# ifdef __QNX__
+# ifdef __QNXNTO__
+# define OSMINOR "OS=QNXNTO"
+# define OS_QNXNTO
+# else
+# define unix
+# define OSMINOR "OS=QNX"
+# define OS_QNX
+# define NO_VFORK
+# define MAXLINE 996
+# endif
+# endif
+# ifdef NeXT
+# ifdef __APPLE__
+# define OSMINOR "OS=RHAPSODY"
+# define OS_RHAPSODY
+# else
+# define OSMINOR "OS=NEXT"
+# define OS_NEXT
+# endif
+# endif
+# ifdef __APPLE__
+# define unix
+# define OSMINOR "OS=MACOSX"
+# define OS_MACOSX
+# endif
+# ifdef __osf__
+# define OSMINOR "OS=OSF"
+# define OS_OSF
+# endif
+# ifdef _SEQUENT_
+# define OSMINOR "OS=PTX"
+# define OS_PTX
+# endif
+# ifdef M_XENIX
+# define OSMINOR "OS=SCO"
+# define OS_SCO
+# define NO_VFORK
+# endif
+# ifdef sinix
+# define unix
+# define OSMINOR "OS=SINIX"
+# define OS_SINIX
+# endif
+# ifdef sun
+# if defined(__svr4__) || defined(__SVR4)
+# define OSMINOR "OS=SOLARIS"
+# define OS_SOLARIS
+# else
+# define OSMINOR "OS=SUNOS"
+# define OS_SUNOS
+# endif
+# endif
+# ifdef ultrix
+# define OSMINOR "OS=ULTRIX"
+# define OS_ULTRIX
+# endif
+# ifdef _UNICOS
+# define OSMINOR "OS=UNICOS"
+# define OS_UNICOS
+# endif
+# if defined(__USLC__) && !defined(M_XENIX)
+# define OSMINOR "OS=UNIXWARE"
+# define OS_UNIXWARE
+# endif
+# ifdef __OpenBSD__
+# define OSMINOR "OS=OPENBSD"
+# define OS_OPENBSD
+# define unix
+# endif
+# ifndef OSMINOR
+# define OSMINOR "OS=UNKNOWN"
+# endif
+
+/* All the UNIX includes */
+
+# include <sys/types.h>
+# include <sys/stat.h>
+
+# ifndef OS_MPEIX
+# include <sys/file.h>
+# endif
+
+# include <fcntl.h>
+# include <stdio.h>
+# include <ctype.h>
+# include <signal.h>
+# include <string.h>
+# include <time.h>
+
+# ifndef OS_QNX
+# include <memory.h>
+# endif
+
+# ifndef OS_ULTRIX
+# include <stdlib.h>
+# endif
+
+# if !defined(OS_BSDI) && \
+     !defined(OS_FREEBSD) && \
+     !defined(OS_NEXT) && \
+     !defined(OS_MACHTEN) && \
+     !defined(OS_MACOSX) && \
+     !defined(OS_RHAPSODY) && \
+     !defined(OS_MVS) && \
+     !defined(OS_OPENBSD)
+# include <malloc.h>
+# endif
+
+# endif 
+
+/* 
+ * OSPLAT definitions - suppressed when it's a one-of-a-kind
+ */
+
+# if defined( _M_PPC ) || \
+     defined( PPC ) || \
+     defined( ppc ) || \
+     defined( __powerpc__ ) || \
+     defined( __ppc__ )
+# define OSPLAT "OSPLAT=PPC"
+# endif
+
+# if defined( _ALPHA_ ) || \
+     defined( __alpha__ )
+# define OSPLAT "OSPLAT=AXP"
+# endif
+
+# if defined( _i386_ ) || \
+     defined( __i386__ ) || \
+     defined( _M_IX86 )
+# if !defined( OS_FREEBSD ) && \
+     !defined( OS_OS2 ) && \
+     !defined( OS_AS400 )
+# define OSPLAT "OSPLAT=X86"
+# endif
+# endif 
+
+# ifdef __sparc__
+# if !defined( OS_SUNOS ) && \
+     !defined( OS_SOLARIS )
+# define OSPLAT "OSPLAT=SPARC"
+# endif
+# endif
+
+# ifdef __mips__
+# if !defined( OS_SGI )
+# define OSPLAT "OSPLAT=MIPS"
+# endif
+# endif
+
+# ifdef __arm__
+# define OSPLAT "OSPLAT=ARM"
+# endif
+
+# if defined( __ia64__ ) || defined( __IA64__ )
+# define OSPLAT "OSPLAT=IA64"
+# endif
+
+# ifdef __s390__
+# define OSPLAT "OSPLAT=390"
+# endif
+
+# ifndef OSPLAT
+# define OSPLAT ""
+# endif
+
+/*
+ * Jam implementation misc.
+ */
+
+# ifndef MAXLINE
+# define MAXLINE 102400	/* longest 'together' actions' */
+# endif
+
+# ifndef EXITOK
+# define EXITOK 0
+# define EXITBAD 1
+# endif
+
+# ifndef SPLITPATH
+# define SPLITPATH ':'
+# endif
+
+/* You probably don't need to muck with these. */
+
+# define MAXSYM	1024	/* longest symbol in the environment */
+# define MAXJPATH 1024	/* longest filename */
+
+# define MAXJOBS 64	/* silently enforce -j limit */
+# define MAXARGC 32	/* words in $(JAMSHELL) */
+
+/* Jam private definitions below. */
+
+# define DEBUG_MAX	14
+
+struct globs {
+	int	noexec;
+	int	jobs;
+	int	quitquick;
+	int	newestfirst;		/* build newest sources first */
+	char	debug[DEBUG_MAX];
+	FILE	*cmdout;		/* print cmds, not run them */
+} ;
+
+extern struct globs globs;
+
+# define DEBUG_MAKE	( globs.debug[ 1 ] )	/* show actions when executed */
+# define DEBUG_MAKEQ	( globs.debug[ 2 ] )	/* show even quiet actions */
+# define DEBUG_EXEC	( globs.debug[ 2 ] )	/* show text of actons */
+# define DEBUG_MAKEPROG	( globs.debug[ 3 ] )	/* show progress of make0 */
+# define DEBUG_BIND	( globs.debug[ 3 ] )	/* show when files bound */
+
+# define DEBUG_EXECCMD	( globs.debug[ 4 ] )	/* show execcmds()'s work */
+
+# define DEBUG_COMPILE	( globs.debug[ 5 ] )	/* show rule invocations */
+
+# define DEBUG_HEADER	( globs.debug[ 6 ] )	/* show result of header scan */
+# define DEBUG_BINDSCAN	( globs.debug[ 6 ] )	/* show result of dir scan */
+# define DEBUG_SEARCH	( globs.debug[ 6 ] )	/* show attempts at binding */
+
+# define DEBUG_VARSET	( globs.debug[ 7 ] )	/* show variable settings */
+# define DEBUG_VARGET	( globs.debug[ 8 ] )	/* show variable fetches */
+# define DEBUG_VAREXP	( globs.debug[ 8 ] )	/* show variable expansions */
+# define DEBUG_IF	( globs.debug[ 8 ] )	/* show 'if' calculations */
+# define DEBUG_LISTS	( globs.debug[ 9 ] )	/* show list manipulation */
+# define DEBUG_SCAN	( globs.debug[ 9 ] )	/* show scanner tokens */
+# define DEBUG_MEM	( globs.debug[ 9 ] )	/* show memory use */
+
+# define DEBUG_PROFILE	( globs.debug[ 10 ] )	/* dump rule execution times */
+# define DEBUG_PARSE	( globs.debug[ 11 ] )	/* debug parsing */
+# define DEBUG_GRAPH	( globs.debug[ 12 ] )	/* debug dependencies */
+# define DEBUG_FATE ( globs.debug[ 13 ] )  /* show changes to fate in make0() */
+
+#endif

Added: boost-jam/boost-build/branches/upstream/current/jam_src/jambase.c
===================================================================
--- boost-jam/boost-build/branches/upstream/current/jam_src/jambase.c	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/jam_src/jambase.c	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,1678 @@
+/* Generated by mkjambase from Jambase */
+char *jambase[] = {
+/* Jambase */
+"if $(NT)\n",
+"{\n",
+"SLASH ?= \\\\ ;\n",
+"}\n",
+"SLASH ?= / ;\n",
+"rule find-to-root ( dir : patterns + )\n",
+"{\n",
+"local globs = [ GLOB $(dir) : $(patterns) ] ;\n",
+"while ! $(globs) && $(dir:P) != $(dir)\n",
+"{\n",
+"dir = $(dir:P) ;\n",
+"globs = [ GLOB $(dir) : $(patterns) ] ;\n",
+"}\n",
+"return $(globs) ;\n",
+"}\n",
+".boost-build-file = ;\n",
+".bootstrap-file = ;\n",
+"BOOST_BUILD_PATH.user-value = $(BOOST_BUILD_PATH) ;\n",
+"if ! $(BOOST_BUILD_PATH) && $(UNIX)\n",
+"{\n",
+"BOOST_BUILD_PATH = /usr/share/boost-build ;\n",
+"}\n",
+"rule boost-build ( dir ? )\n",
+"{\n",
+"if $(.bootstrap-file)\n",
+"{\n",
+"EXIT \"Error: Illegal attempt to re-bootstrap the build system by invoking\" ;\n",
+"ECHO ;\n",
+"ECHO \"   'boost-build\" $(dir) \";'\" ;\n",
+"ECHO ;\n",
+"EXIT \"Please consult the documentation at 'http://www.boost.org'.\" ;\n",
+"}\n",
+"BOOST_BUILD_PATH = $(dir:R=$(.boost-build-file:D)) $(BOOST_BUILD_PATH) ;\n",
+"local bootstrap-file =\n",
+"[ GLOB $(BOOST_BUILD_PATH) : bootstrap.jam ] ;\n",
+".bootstrap-file = $(bootstrap-file[1]) ;\n",
+"if ! $(.bootstrap-file)\n",
+"{\n",
+"ECHO \"Unable to load Boost.Build: could not find build system.\" ;\n",
+"ECHO --------------------------------------------------------- ;\n",
+"ECHO \"$(.boost-build-file) attempted to load the build system by invoking\" ;\n",
+"ECHO ;\n",
+"ECHO \"   'boost-build\" $(dir) \";'\" ;\n",
+"ECHO ;\n",
+"ECHO \"but we were unable to find \\\"bootstrap.jam\\\" in the specified directory\" ;\n",
+"ECHO \"or in BOOST_BUILD_PATH (searching \"$(BOOST_BUILD_PATH:J=\", \")\").\" ;\n",
+"ECHO ;\n",
+"EXIT \"Please consult the documentation at 'http://www.boost.org'.\" ;\n",
+"}\n",
+"if [ MATCH .*(--debug-configuration).* : $(ARGV) ]\n",
+"{\n",
+"ECHO \"notice: loading Boost.Build from\" \n",
+"[ NORMALIZE_PATH $(.bootstrap-file:D) ] ;\n",
+"}\n",
+"include $(.bootstrap-file) ;\n",
+"}\n",
+"if [ MATCH .*(bjam).* : $(ARGV[1]:BL) ]\n",
+"|| $(BOOST_ROOT)    # A temporary measure so Jam works with Boost.Build v1\n",
+"{\n",
+"local search-path = $(BOOST_BUILD_PATH) $(BOOST_ROOT) ;\n",
+"local boost-build-files =\n",
+"[ find-to-root [ PWD ] : boost-build.jam ]\n",
+"[ GLOB $(search-path) : boost-build.jam ] ;\n",
+".boost-build-file = $(boost-build-files[1]) ;\n",
+"if [ MATCH .*(--debug-configuration).* : $(ARGV) ]\n",
+"{\n",
+"ECHO \"notice: found boost-build.jam at\" \n",
+"[ NORMALIZE_PATH $(.boost-build-file) ] ;\n",
+"}\n",
+"if ! $(.boost-build-file)\n",
+"{\n",
+"ECHO \"Unable to load Boost.Build: could not find \\\"boost-build.jam\\\"\" ;\n",
+"ECHO --------------------------------------------------------------- ;\n",
+"if ! [ MATCH .*(bjam).* : $(ARGV[1]:BL) ]\n",
+"{\n",
+"ECHO \"BOOST_ROOT must be set, either in the environment, or \" ;\n",
+"ECHO \"on the command-line with -sBOOST_ROOT=..., to the root\" ;\n",
+"ECHO \"of the boost installation.\" ;\n",
+"ECHO ;\n",
+"}\n",
+"ECHO \"Attempted search from\" [ PWD ] \"up to the root\" ;\n",
+"ECHO \"and in these directories from BOOST_BUILD_PATH and BOOST_ROOT: \"$(search-path:J=\", \")\".\" ;\n",
+"EXIT \"Please consult the documentation at 'http://www.boost.org'.\" ;\n",
+"}\n",
+"include $(.boost-build-file) ;\n",
+"if ! $(.bootstrap-file)\n",
+"{\n",
+"ECHO \"Unable to load Boost.Build\" ;\n",
+"ECHO -------------------------- ;\n",
+"ECHO \"\\\"$(.boost-build-file)\\\" was found by searching from\" [ PWD ] \"up to the root\" ;\n",
+"ECHO \"and in these directories from BOOST_BUILD_PATH and BOOST_ROOT: \"$(search-path:J=\", \")\".\" ;\n",
+"ECHO ;\n",
+"ECHO \"However, it failed to call the \\\"boost-build\\\" rule to indicate\" ;\n",
+"ECHO \"the location of the build system.\" ;\n",
+"ECHO ;\n",
+"EXIT \"Please consult the documentation at 'http://www.boost.org'.\" ;\n",
+"}\n",
+"}\n",
+"else\n",
+"{\n",
+"if $(NT)\n",
+"{\n",
+"local SUPPORTED_TOOLSETS = \"BORLANDC\" \"VC7\" \"VISUALC\" \"VISUALC16\" \"INTELC\" \"WATCOM\"\n",
+"\"MINGW\" \"LCC\" ;\n",
+"TOOLSET = \"\" ;\n",
+"if $(JAM_TOOLSET)\n",
+"{\n",
+"local t ;\n",
+"for t in $(SUPPORTED_TOOLSETS)\n",
+"{\n",
+"$(t) = $($(t):J=\" \") ; # reconstitute paths with spaces in them\n",
+"if $(t) = $(JAM_TOOLSET) { TOOLSET = $(t) ; }\n",
+"}\n",
+"if ! $(TOOLSET)\n",
+"{\n",
+"ECHO  \"The JAM_TOOLSET environment variable is defined but its value\" ;\n",
+"ECHO  \"is invalid, please use one of the following:\" ;\n",
+"ECHO  ;\n",
+"for t in $(SUPPORTED_TOOLSETS) { ECHO \"  \" $(t) ; }\n",
+"EXIT ;\n",
+"}\n",
+"}\n",
+"if ! $(TOOLSET)\n",
+"{\n",
+"if $(BCCROOT)\n",
+"{\n",
+"TOOLSET  = BORLANDC ;\n",
+"BORLANDC = $(BCCROOT:J=\" \") ;\n",
+"}\n",
+"else if $(MSVC)\n",
+"{\n",
+"TOOLSET   = VISUALC16 ;\n",
+"VISUALC16 = $(MSVC:J=\" \") ;\n",
+"}\n",
+"else if $(MSVCNT)\n",
+"{\n",
+"TOOLSET = VISUALC ;\n",
+"VISUALC = $(MSVCNT:J=\" \") ;\n",
+"}\n",
+"else if $(MSVCDir)\n",
+"{\n",
+"TOOLSET = VISUALC ;\n",
+"VISUALC = $(MSVCDir:J=\" \") ;\n",
+"}\n",
+"else if $(MINGW)\n",
+"{\n",
+"TOOLSET = MINGW ;\n",
+"}\n",
+"else\n",
+"{\n",
+"ECHO  \"Jam cannot be run because, either:\" ;\n",
+"ECHO  \"   a. You didn't set BOOST_ROOT to indicate the root of your\" ;\n",
+"ECHO  \"      Boost installation.\" ;\n",
+"ECHO  \"   b. You are trying to use stock Jam but didn't indicate which\" ;\n",
+"ECHO  \"      compilation toolset to use. To do so, follow these simple\" ;\n",
+"ECHO  \"      instructions:\" ;\n",
+"ECHO  ;\n",
+"ECHO  \"  - define one of the following environment variable, with the\" ;\n",
+"ECHO  \"    appropriate value according to this list:\" ;\n",
+"ECHO  ;\n",
+"ECHO  \"   Variable    Toolset                      Description\" ;\n",
+"ECHO  ;\n",
+"ECHO  \"   BORLANDC    Borland C++                  BC++ install path\" ;\n",
+"ECHO  \"   VISUALC     Microsoft Visual C++         VC++ install path\" ;\n",
+"ECHO  \"   VISUALC16   Microsoft Visual C++ 16 bit  VC++ 16 bit install\" ;\n",
+"ECHO  \"   INTELC      Intel C/C++                  IC++ install path\" ;\n",
+"ECHO  \"   WATCOM      Watcom C/C++                 Watcom install path\" ;\n",
+"ECHO  \"   MINGW       MinGW (gcc)                  MinGW install path\" ;\n",
+"ECHO  \"   LCC         Win32-LCC                    LCC-Win32 install path\" ;\n",
+"ECHO  ;\n",
+"ECHO  \"  - define the JAM_TOOLSET environment variable with the *name*\" ;\n",
+"ECHO  \"    of the toolset variable you want to use.\" ;\n",
+"ECHO  ;\n",
+"ECHO  \"  e.g.:  set VISUALC=C:\\\\Visual6\" ;\n",
+"ECHO  \"         set JAM_TOOLSET=VISUALC\" ;\n",
+"EXIT  ;\n",
+"}\n",
+"}\n",
+"CP          ?= copy ;\n",
+"RM          ?= del /f/q ;\n",
+"SLASH       ?= \\\\ ;\n",
+"SUFLIB      ?= .lib ;\n",
+"SUFOBJ      ?= .obj ;\n",
+"SUFEXE      ?= .exe ;\n",
+"if $(TOOLSET) = BORLANDC\n",
+"{\n",
+"ECHO \"Compiler is Borland C++\" ;\n",
+"AR          ?= tlib /C /P64 ;\n",
+"CC          ?= bcc32 ;\n",
+"CCFLAGS     ?= -q -y -d -v -w-par -w-ccc -w-rch -w-pro -w-aus ;\n",
+"C++         ?= bcc32 ;\n",
+"C++FLAGS    ?= -q -y -d -v -w-par -w-ccc -w-rch -w-pro -w-aus -P ;\n",
+"LINK        ?= $(CC) ;\n",
+"LINKFLAGS   ?= $(CCFLAGS) ;\n",
+"STDLIBPATH  ?= $(BORLANDC)\\\\lib ;\n",
+"STDHDRS     ?= $(BORLANDC)\\\\include ;\n",
+"NOARSCAN    ?= true ;\n",
+"}\n",
+"else if $(TOOLSET) = VISUALC16\n",
+"{\n",
+"ECHO \"Compiler is Microsoft Visual C++ 16 bit\" ;\n",
+"AR          ?= lib /nologo ;\n",
+"CC          ?= cl /nologo ;\n",
+"CCFLAGS     ?= /D \\\"WIN\\\" ;\n",
+"C++         ?= $(CC) ;\n",
+"C++FLAGS    ?= $(CCFLAGS) ;\n",
+"LINK        ?= $(CC) ;\n",
+"LINKFLAGS   ?= $(CCFLAGS) ;\n",
+"LINKLIBS    ?= \n",
+"\\\"$(VISUALC16)\\\\lib\\\\mlibce.lib\\\"\n",
+"\\\"$(VISUALC16)\\\\lib\\\\oldnames.lib\\\"\n",
+";\n",
+"LINKLIBS    ?= ;\n",
+"NOARSCAN    ?= true ;\n",
+"OPTIM       ?= \"\" ;\n",
+"STDHDRS     ?= $(VISUALC16)\\\\include ;\n",
+"UNDEFFLAG   ?= \"/u _\" ;\n",
+"}\n",
+"else if $(TOOLSET) = VISUALC\n",
+"{\n",
+"ECHO \"Compiler is Microsoft Visual C++\" ;\n",
+"AR          ?= lib ;\n",
+"AS          ?= masm386 ;\n",
+"CC          ?= cl /nologo ;\n",
+"CCFLAGS     ?= \"\" ;\n",
+"C++         ?= $(CC) ;\n",
+"C++FLAGS    ?= $(CCFLAGS) ;\n",
+"LINK        ?= link /nologo ;\n",
+"LINKFLAGS   ?= \"\" ;\n",
+"LINKLIBS    ?= \\\"$(VISUALC)\\\\lib\\\\advapi32.lib\\\"\n",
+"\\\"$(VISUALC)\\\\lib\\\\gdi32.lib\\\"\n",
+"\\\"$(VISUALC)\\\\lib\\\\user32.lib\\\"\n",
+"\\\"$(VISUALC)\\\\lib\\\\kernel32.lib\\\" ;\n",
+"OPTIM       ?= \"\" ;\n",
+"STDHDRS     ?= $(VISUALC)\\\\include ;\n",
+"UNDEFFLAG   ?= \"/u _\" ;\n",
+"}\n",
+"else if $(TOOLSET) = VC7\n",
+"{\n",
+"ECHO \"Compiler is Microsoft Visual C++ .NET\" ;\n",
+"AR          ?= lib ;\n",
+"AS          ?= masm386 ;\n",
+"CC          ?= cl /nologo ;\n",
+"CCFLAGS     ?= \"\" ;\n",
+"C++         ?= $(CC) ;\n",
+"C++FLAGS    ?= $(CCFLAGS) ;\n",
+"LINK        ?= link /nologo ;\n",
+"LINKFLAGS   ?= \"\" ;\n",
+"LINKLIBS    ?= \\\"$(VISUALC)\\\\PlatformSDK\\\\lib\\\\advapi32.lib\\\"\n",
+"\\\"$(VISUALC)\\\\PlatformSDK\\\\lib\\\\gdi32.lib\\\"\n",
+"\\\"$(VISUALC)\\\\PlatformSDK\\\\lib\\\\user32.lib\\\"\n",
+"\\\"$(VISUALC)\\\\PlatformSDK\\\\lib\\\\kernel32.lib\\\" ;\n",
+"OPTIM       ?= \"\" ;\n",
+"STDHDRS     ?= \\\"$(VISUALC)\\\\include\\\"\n",
+"\\\"$(VISUALC)\\\\PlatformSDK\\\\include\\\" ;\n",
+"UNDEFFLAG   ?= \"/u _\" ;\n",
+"}\n",
+"else if $(TOOLSET) = INTELC\n",
+"{\n",
+"ECHO \"Compiler is Intel C/C++\" ;\n",
+"if ! $(VISUALC)\n",
+"{\n",
+"ECHO \"As a special exception, when using the Intel C++ compiler, you need\" ;\n",
+"ECHO \"to define the VISUALC environment variable to indicate the location\" ;\n",
+"ECHO \"of your Visual C++ installation. Aborting..\" ;\n",
+"EXIT ;\n",
+"}\n",
+"AR          ?= lib ;\n",
+"AS          ?= masm386 ;\n",
+"CC          ?= icl /nologo ;\n",
+"CCFLAGS     ?= \"\" ;\n",
+"C++         ?= $(CC) ;\n",
+"C++FLAGS    ?= $(CCFLAGS) ;\n",
+"LINK        ?= link /nologo ;\n",
+"LINKFLAGS   ?= \"\" ;\n",
+"LINKLIBS    ?= $(VISUALC)\\\\lib\\\\advapi32.lib\n",
+"$(VISUALC)\\\\lib\\\\kernel32.lib\n",
+";\n",
+"OPTIM       ?= \"\" ;\n",
+"STDHDRS     ?= $(INTELC)\\include $(VISUALC)\\\\include ;\n",
+"UNDEFFLAG   ?= \"/u _\" ;\n",
+"}\n",
+"else if $(TOOLSET) = WATCOM\n",
+"{\n",
+"ECHO \"Compiler is Watcom C/C++\" ;\n",
+"AR          ?= wlib ;\n",
+"CC          ?= wcc386 ;\n",
+"CCFLAGS     ?= /zq /DWIN32 /I$(WATCOM)\\\\h ; # zq=quiet\n",
+"C++         ?= wpp386 ;\n",
+"C++FLAGS    ?= $(CCFLAGS) ;\n",
+"CP          ?= copy ;\n",
+"DOT         ?= . ;\n",
+"DOTDOT      ?= .. ;\n",
+"LINK        ?= wcl386 ;\n",
+"LINKFLAGS   ?= /zq ; # zq=quiet\n",
+"LINKLIBS    ?= ;\n",
+"MV          ?= move ;\n",
+"NOARSCAN    ?= true ;\n",
+"OPTIM       ?= ;\n",
+"RM          ?= del /f ;\n",
+"SLASH       ?= \\\\ ;\n",
+"STDHDRS     ?= $(WATCOM)\\\\h $(WATCOM)\\\\h\\\\nt ;\n",
+"SUFEXE      ?= .exe ;\n",
+"SUFLIB      ?= .lib ;\n",
+"SUFOBJ      ?= .obj ;\n",
+"UNDEFFLAG   ?= \"/u _\" ;\n",
+"}\n",
+"else if $(TOOLSET) = MINGW\n",
+"{\n",
+"ECHO \"Compiler is GCC with Mingw\" ;\n",
+"AR              ?= ar -ru ;\n",
+"CC              ?= gcc ;\n",
+"CCFLAGS         ?= \"\" ;\n",
+"C++             ?= $(CC) ;\n",
+"C++FLAGS        ?= $(CCFLAGS) ;\n",
+"LINK            ?= $(CC) ;\n",
+"LINKFLAGS       ?= \"\" ;\n",
+"LINKLIBS        ?= \"\" ;\n",
+"OPTIM           ?= ;\n",
+"SUFOBJ           = .o ;\n",
+"SUFLIB           = .a ;\n",
+"SLASH            = / ;\n",
+"}\n",
+"else if $(TOOLSET) = LCC\n",
+"{\n",
+"ECHO \"Compiler is Win32-LCC\" ;\n",
+"AR              ?= lcclib ;\n",
+"CC              ?= lcc ;\n",
+"CCFLAGS         ?= \"\" ;\n",
+"C++             ?= $(CC) ;\n",
+"C++FLAGS        ?= $(CCFLAGS) ;\n",
+"LINK            ?= lcclnk ;\n",
+"LINKFLAGS       ?= \"\" ;\n",
+"LINKLIBS        ?= \"\" ;\n",
+"OPTIM           ?= ;\n",
+"NOARSCAN         = true ;\n",
+"}\n",
+"else\n",
+"{\n",
+"EXIT On NT, set BCCROOT, MSVCNT, MINGW or MSVC to the root of the\n",
+"Borland or Microsoft directories. ;\n",
+"}\n",
+"}\n",
+"else if $(OS2)\n",
+"{\n",
+"local SUPPORTED_TOOLSETS = \"EMX\" \"WATCOM\" ;\n",
+"TOOLSET = \"\" ;\n",
+"if $(JAM_TOOLSET)\n",
+"{\n",
+"local t ;\n",
+"for t in $(SUPPORTED_TOOLSETS)\n",
+"{\n",
+"$(t) = $($(t):J=\" \") ; # reconstitute paths with spaces in them\n",
+"if $(t) = $(JAM_TOOLSET) { TOOLSET = $(t) ; }\n",
+"}\n",
+"if ! $(TOOLSET)\n",
+"{\n",
+"ECHO  \"The JAM_TOOLSET environment variable is defined but its value\" ;\n",
+"ECHO  \"is invalid, please use one of the following:\" ;\n",
+"ECHO  ;\n",
+"for t in $(SUPPORTED_TOOLSETS) { ECHO \"  \" $(t) ; }\n",
+"EXIT ;\n",
+"}\n",
+"}\n",
+"if ! $(TOOLSET)\n",
+"{\n",
+"if $(watcom)\n",
+"{\n",
+"WATCOM   = $(watcom:J=\" \") ;\n",
+"TOOLSET  = WATCOM ;\n",
+"}\n",
+"else\n",
+"{\n",
+"ECHO  \"Jam cannot be run because you didn't indicate which compilation toolset\" ;\n",
+"ECHO  \"to use. To do so, follow these simple instructions:\" ;\n",
+"ECHO  ;\n",
+"ECHO  \"  - define one of the following environment variable, with the\" ;\n",
+"ECHO  \"    appropriate value according to this list:\" ;\n",
+"ECHO  ;\n",
+"ECHO  \"   Variable    Toolset                      Description\" ;\n",
+"ECHO  ;\n",
+"ECHO  \"   WATCOM      Watcom C/C++                 Watcom install path\" ;\n",
+"ECHO  \"   EMX         EMX (gcc)                    EMX install path\" ;\n",
+"ECHO  \"   VISUALAGE   IBM Visual Age C/C++         VisualAge install path\" ;\n",
+"ECHO  ;\n",
+"ECHO  \"  - define the JAM_TOOLSET environment variable with the *name*\" ;\n",
+"ECHO  \"    of the toolset variable you want to use.\" ;\n",
+"ECHO  ;\n",
+"ECHO  \"  e.g.:  set WATCOM=C:\\WATCOM\" ;\n",
+"ECHO  \"         set JAM_TOOLSET=WATCOM\" ;\n",
+"ECHO  ;\n",
+"EXIT  ;\n",
+"}\n",
+"}\n",
+"RM       = del /f ;\n",
+"CP       = copy ;\n",
+"MV      ?= move ;\n",
+"DOT     ?= . ;\n",
+"DOTDOT  ?= .. ;\n",
+"SUFLIB  ?= .lib ;\n",
+"SUFOBJ  ?= .obj ;\n",
+"SUFEXE  ?= .exe ;\n",
+"if $(TOOLSET) = WATCOM\n",
+"{\n",
+"AR           ?= wlib ;\n",
+"BINDIR       ?= \\\\os2\\\\apps ;\n",
+"CC           ?= wcc386 ;\n",
+"CCFLAGS      ?= /zq /DOS2 /I$(WATCOM)\\\\h ; # zq=quiet\n",
+"C++          ?= wpp386 ;\n",
+"C++FLAGS     ?= $(CCFLAGS) ;\n",
+"LINK         ?= wcl386 ;\n",
+"LINKFLAGS    ?= /zq ; # zq=quiet\n",
+"LINKLIBS     ?= ;\n",
+"NOARSCAN     ?= true ;\n",
+"OPTIM        ?= ;\n",
+"SLASH        ?= \\\\ ;\n",
+"STDHDRS      ?= $(WATCOM)\\\\h ;\n",
+"UNDEFFLAG    ?= \"/u _\" ;\n",
+"}\n",
+"else if $(TOOLSET) = EMX\n",
+"{\n",
+"ECHO \"Compiler is GCC-EMX\" ;\n",
+"AR            ?= ar -ru ;\n",
+"CC            ?= gcc ;\n",
+"CCFLAGS       ?= \"\" ;\n",
+"C++           ?= $(CC) ;\n",
+"C++FLAGS      ?= $(CCFLAGS) ;\n",
+"LINK          ?= $(CC) ;\n",
+"LINKFLAGS     ?= \"\" ;\n",
+"LINKLIBS      ?= \"\" ;\n",
+"OPTIM         ?= ;\n",
+"SUFOBJ         = .o ;\n",
+"SUFLIB         = .a ;\n",
+"UNDEFFLAG     ?= \"-U\" ;\n",
+"SLASH          = / ;\n",
+"}\n",
+"else\n",
+"{\n",
+"EXIT  \"Sorry, but the $(JAM_TOOLSET) toolset isn't supported for now\" ;\n",
+"}\n",
+"}\n",
+"else if $(VMS)\n",
+"{\n",
+"C++         ?= cxx ;\n",
+"C++FLAGS    ?= ;\n",
+"CC          ?= cc ;\n",
+"CCFLAGS     ?= ;\n",
+"CHMOD       ?= set file/prot= ;\n",
+"CP          ?= copy/replace ;\n",
+"CRELIB      ?= true ;\n",
+"DOT         ?= [] ;\n",
+"DOTDOT      ?= [-] ;\n",
+"EXEMODE     ?= (w:e) ;\n",
+"FILEMODE    ?= (w:r) ;\n",
+"HDRS        ?= ;\n",
+"LINK        ?= link ;\n",
+"LINKFLAGS   ?= \"\" ;\n",
+"LINKLIBS    ?= ;\n",
+"MKDIR       ?= create/dir ;\n",
+"MV          ?= rename ;\n",
+"OPTIM       ?= \"\" ;\n",
+"RM          ?= delete ;\n",
+"RUNVMS      ?= mcr ;\n",
+"SHELLMODE   ?= (w:er) ;\n",
+"SLASH       ?= . ;\n",
+"STDHDRS     ?= decc$library_include ;\n",
+"SUFEXE      ?= .exe ;\n",
+"SUFLIB      ?= .olb ;\n",
+"SUFOBJ      ?= .obj ;\n",
+"switch $(OS) \n",
+"{\n",
+"case OPENVMS : CCFLAGS  ?= /stand=vaxc ;\n",
+"case VMS     : LINKLIBS ?= sys$library:vaxcrtl.olb/lib ;\n",
+"}\n",
+"}\n",
+"else if $(MAC)\n",
+"{\n",
+"local OPT ;\n",
+"CW  ?= \"{CW}\" ;\n",
+"MACHDRS ?=\n",
+"\"$(UMACHDRS):Universal:Interfaces:CIncludes\"\n",
+"\"$(CW):MSL:MSL_C:MSL_Common:Include\"\n",
+"\"$(CW):MSL:MSL_C:MSL_MacOS:Include\" ;\n",
+"MACLIBS ?=\n",
+"\"$(CW):MacOS Support:Universal:Libraries:StubLibraries:Interfacelib\"\n",
+"\"$(CW):MacOS Support:Universal:Libraries:StubLibraries:Mathlib\" ;\n",
+"MPWLIBS ?= \n",
+"\"$(CW):MacOS Support:Libraries:Runtime:Runtime PPC:MSL MPWCRuntime.lib\"\n",
+"\"$(CW):MSL:MSL_C:MSL_MacOS:Lib:PPC:MSL C.PPC MPW.Lib\" ;\n",
+"MPWNLLIBS ?= \n",
+"\"$(CW):MacOS Support:Libraries:Runtime:Runtime PPC:MSL MPWCRuntime.lib\"\n",
+"\"$(CW):MSL:MSL_C:MSL_MacOS:Lib:PPC:MSL C.PPC MPW(NL).Lib\" ;\n",
+"SIOUXHDRS ?= ;\n",
+"SIOUXLIBS ?= \n",
+"\"$(CW):MacOS Support:Libraries:Runtime:Runtime PPC:MSL RuntimePPC.lib\"\n",
+"\"$(CW):MSL:MSL_C:MSL_MacOS:Lib:PPC:MSL SIOUX.PPC.Lib\" \n",
+"\"$(CW):MSL:MSL_C:MSL_MacOS:Lib:PPC:MSL C.PPC.Lib\" ;\n",
+"C++         ?= mwcppc ;\n",
+"C++FLAGS    ?= -w off -nomapcr ;\n",
+"CC          ?= mwcppc ;\n",
+"CCFLAGS     ?= -w off -nomapcr ;\n",
+"CP          ?= duplicate -y ;\n",
+"DOT         ?= \":\" ;\n",
+"DOTDOT      ?= \"::\" ;\n",
+"HDRS        ?= $(MACHDRS) $(MPWHDRS) ;\n",
+"LINK        ?= mwlinkppc ;\n",
+"LINKFLAGS   ?= -mpwtool -warn ;             \n",
+"LINKLIBS    ?= $(MACLIBS) $(MPWLIBS) ;              \n",
+"MKDIR       ?= newfolder ;\n",
+"MV          ?= rename -y ;\n",
+"NOARSCAN    ?= true ;\n",
+"OPTIM       ?= ;\n",
+"RM          ?= delete -y ;\n",
+"SLASH       ?= \":\" ;\n",
+"STDHDRS     ?= ; \n",
+"SUFLIB      ?= .lib ;\n",
+"SUFOBJ      ?= .o ;\n",
+"}\n",
+"else if $(OS) = BEOS && $(METROWERKS)\n",
+"{\n",
+"AR          ?= mwld -xml -o ;\n",
+"BINDIR      ?= /boot/apps ;\n",
+"CC          ?= mwcc ;\n",
+"CCFLAGS     ?= -nosyspath ;\n",
+"C++         ?= $(CC) ;\n",
+"C++FLAGS    ?= -nosyspath ;\n",
+"FORTRAN     ?= \"\" ;\n",
+"LIBDIR      ?= /boot/develop/libraries ;\n",
+"LINK        ?= mwld ;\n",
+"LINKFLAGS   ?= \"\" ;\n",
+"MANDIR      ?= /boot/documentation/\"Shell Tools\"/HTML ;\n",
+"NOARSCAN    ?= true ;\n",
+"STDHDRS     ?= /boot/develop/headers/posix ;\n",
+"}\n",
+"else if $(OS) = BEOS \n",
+"{\n",
+"BINDIR      ?= /boot/apps ;\n",
+"CC          ?= gcc ;\n",
+"C++         ?= $(CC) ;\n",
+"FORTRAN     ?= \"\" ;\n",
+"LIBDIR      ?= /boot/develop/libraries ;\n",
+"LINK        ?= gcc ;\n",
+"LINKLIBS    ?= -lnet ;\n",
+"NOARSCAN    ?= true ;\n",
+"STDHDRS     ?= /boot/develop/headers/posix ;\n",
+"}\n",
+"else if $(UNIX)\n",
+"{\n",
+"switch $(OS)\n",
+"{\n",
+"case AIX :\n",
+"LINKLIBS    ?= -lbsd ;\n",
+"case AMIGA :\n",
+"CC          ?= gcc ;\n",
+"YACC        ?= \"bison -y\" ;\n",
+"case CYGWIN :   \n",
+"CC          ?= gcc ;\n",
+"CCFLAGS     += -D__cygwin__ ;\n",
+"LEX         ?= flex ;\n",
+"RANLIB      ?= \"\" ;\n",
+"SUFEXE      ?= .exe ;\n",
+"YACC        ?= \"bison -y\" ;\n",
+"case DGUX :\n",
+"RANLIB      ?= \"\" ;\n",
+"RELOCATE    ?= true ;\n",
+"case HPUX :\n",
+"YACC        = ;\n",
+"CFLAGS      += -Ae ;\n",
+"CCFLAGS     += -Ae ;\n",
+"RANLIB      ?= \"\" ;\n",
+"case INTERIX :\n",
+"CC          ?= gcc ;\n",
+"RANLIB      ?= \"\" ;\n",
+"case IRIX :\n",
+"RANLIB      ?= \"\" ;\n",
+"case MPEIX :\n",
+"CC          ?= gcc ;\n",
+"C++         ?= gcc ;\n",
+"CCFLAGS     += -D_POSIX_SOURCE ;\n",
+"HDRS        += /usr/include ;\n",
+"RANLIB      ?= \"\" ; \n",
+"NOARSCAN    ?= true ;\n",
+"NOARUPDATE  ?= true ;\n",
+"case MVS :\n",
+"RANLIB      ?= \"\" ; \n",
+"case NEXT :\n",
+"AR          ?= libtool -o ;\n",
+"RANLIB      ?= \"\" ;\n",
+"case MACOSX :\n",
+"AR          ?= libtool -o ;\n",
+"C++         ?= c++ ;\n",
+"MANDIR      ?= /usr/local/share/man ;\n",
+"RANLIB      ?= \"\" ;\n",
+"case NCR :\n",
+"RANLIB      ?= \"\" ;\n",
+"case PTX :\n",
+"RANLIB      ?= \"\" ;\n",
+"case QNX :\n",
+"AR          ?= wlib ;\n",
+"CC          ?= cc ;\n",
+"CCFLAGS     ?= -Q ; # quiet\n",
+"C++         ?= $(CC) ;\n",
+"C++FLAGS    ?= -Q ; # quiet\n",
+"LINK        ?= $(CC) ;\n",
+"LINKFLAGS   ?= -Q ; # quiet\n",
+"NOARSCAN    ?= true ;\n",
+"RANLIB      ?= \"\" ;\n",
+"case SCO :\n",
+"RANLIB      ?= \"\" ;\n",
+"RELOCATE    ?= true ;\n",
+"case SINIX :\n",
+"RANLIB      ?= \"\" ;\n",
+"case SOLARIS :\n",
+"RANLIB      ?= \"\" ;\n",
+"AR          ?= \"/usr/ccs/bin/ar ru\" ;\n",
+"case UNICOS :\n",
+"NOARSCAN    ?= true ;\n",
+"OPTIM       ?= -O0 ;\n",
+"case UNIXWARE :\n",
+"RANLIB      ?= \"\" ;\n",
+"RELOCATE    ?= true ;\n",
+"}\n",
+"CCFLAGS     ?= ;\n",
+"C++FLAGS    ?= $(CCFLAGS) ;\n",
+"CHMOD       ?= chmod ;\n",
+"CHGRP       ?= chgrp ;\n",
+"CHOWN       ?= chown ;\n",
+"LEX         ?= lex ;\n",
+"LINKFLAGS   ?= $(CCFLAGS) ;\n",
+"LINKLIBS    ?= ;\n",
+"OPTIM       ?= -O ;\n",
+"RANLIB      ?= ranlib ;\n",
+"YACC        ?= yacc ;\n",
+"YACCFILES   ?= y.tab ;\n",
+"YACCFLAGS   ?= -d ;\n",
+"}\n",
+"AR          ?= ar ru ;\n",
+"AS          ?= as ;\n",
+"ASFLAGS     ?= ;\n",
+"AWK         ?= awk ;\n",
+"BINDIR      ?= /usr/local/bin ;\n",
+"C++         ?= cc ;\n",
+"C++FLAGS    ?= ;\n",
+"CC          ?= cc ;\n",
+"CCFLAGS     ?= ;\n",
+"CP          ?= cp -f ;\n",
+"CRELIB      ?= ;\n",
+"DOT         ?= . ;\n",
+"DOTDOT      ?= .. ;\n",
+"EXEMODE     ?= 711 ;\n",
+"FILEMODE    ?= 644 ;\n",
+"FORTRAN     ?= f77 ;\n",
+"FORTRANFLAGS ?= ;\n",
+"HDRS        ?= ;\n",
+"INSTALLGRIST ?= installed ;\n",
+"JAMFILE     ?= Jamfile ;\n",
+"JAMRULES    ?= Jamrules ;\n",
+"LEX         ?= ;\n",
+"LIBDIR      ?= /usr/local/lib ;\n",
+"LINK        ?= $(CC) ;\n",
+"LINKFLAGS   ?= ;\n",
+"LINKLIBS    ?= ;\n",
+"LN          ?= ln ;\n",
+"MANDIR      ?= /usr/local/man ;\n",
+"MKDIR       ?= mkdir ;\n",
+"MV          ?= mv -f ;\n",
+"OPTIM       ?= ;\n",
+"RCP         ?= rcp ;\n",
+"RM          ?= rm -f ;\n",
+"RSH         ?= rsh ;\n",
+"SED         ?= sed ;\n",
+"SHELLHEADER ?= \"#!/bin/sh\" ;\n",
+"SHELLMODE   ?= 755 ;\n",
+"SLASH       ?= / ;\n",
+"STDHDRS     ?= /usr/include ;\n",
+"SUFEXE      ?= \"\" ;\n",
+"SUFLIB      ?= .a ;\n",
+"SUFOBJ      ?= .o ;\n",
+"UNDEFFLAG   ?= \"-u _\" ;\n",
+"YACC        ?= ;\n",
+"YACCFILES   ?= ;\n",
+"YACCFLAGS   ?= ;\n",
+"HDRPATTERN = \n",
+"\"^[     ]*#[    ]*include[  ]*[<\\\"]([^\\\">]*)[\\\">].*$\" ;\n",
+"OSFULL = $(OS)$(OSVER)$(OSPLAT) $(OS)$(OSPLAT) $(OS)$(OSVER) $(OS) ;\n",
+"DEPENDS all : shell files lib exe obj ;\n",
+"DEPENDS all shell files lib exe obj : first ;\n",
+"NOTFILE all first shell files lib exe obj dirs clean uninstall ;\n",
+"ALWAYS clean uninstall ;\n",
+"rule As\n",
+"{\n",
+"DEPENDS $(<) : $(>) ;\n",
+"ASFLAGS on $(<) += $(ASFLAGS) $(SUBDIRASFLAGS) ;\n",
+"}\n",
+"rule Bulk\n",
+"{\n",
+"local i ;\n",
+"for i in $(>)\n",
+"{\n",
+"File $(i:D=$(<)) : $(i) ;\n",
+"}\n",
+"}\n",
+"rule Cc\n",
+"{\n",
+"local _h ;\n",
+"DEPENDS $(<) : $(>) ;\n",
+"CCFLAGS on $(<) += $(CCFLAGS) $(SUBDIRCCFLAGS) ;\n",
+"if $(RELOCATE)\n",
+"{\n",
+"CcMv $(<) : $(>) ;\n",
+"}\n",
+"_h = $(SEARCH_SOURCE) $(HDRS) $(SUBDIRHDRS) ;\n",
+"if $(VMS) && $(_h)\n",
+"{\n",
+"SLASHINC on $(<) = \"/inc=(\" $(_h[1]) ,$(_h[2-]) \")\" ;\n",
+"}\n",
+"else if $(MAC) && $(_h)\n",
+"{\n",
+"local _i _j ;\n",
+"_j = $(_h[1]) ;\n",
+"for _i in $(_h[2-])\n",
+"{\n",
+"_j = $(_j),$(_i) ;\n",
+"}\n",
+"MACINC on $(<) = \\\"$(_j)\\\" ;\n",
+"}\n",
+"}\n",
+"rule C++\n",
+"{\n",
+"local _h ;\n",
+"DEPENDS $(<) : $(>) ;\n",
+"C++FLAGS on $(<) += $(C++FLAGS) $(SUBDIRC++FLAGS) ;\n",
+"if $(RELOCATE)\n",
+"{\n",
+"CcMv $(<) : $(>) ;\n",
+"}\n",
+"_h = $(SEARCH_SOURCE) $(HDRS) $(SUBDIRHDRS) ;\n",
+"if $(VMS) && $(_h)\n",
+"{\n",
+"SLASHINC on $(<) = \"/inc=(\" $(_h[1]) ,$(_h[2-]) \")\" ;\n",
+"}\n",
+"else if $(MAC) && $(_h)\n",
+"{\n",
+"local _i _j ;\n",
+"_j = $(_h[1]) ;\n",
+"for _i in $(_h[2-])\n",
+"{\n",
+"_j = $(_j),$(_i) ;\n",
+"}\n",
+"MACINC on $(<) = \\\"$(_j)\\\" ;\n",
+"}\n",
+"}\n",
+"rule Chmod\n",
+"{\n",
+"if $(CHMOD) { Chmod1 $(<) ; }\n",
+"}\n",
+"rule File\n",
+"{\n",
+"DEPENDS files : $(<) ;\n",
+"DEPENDS $(<) : $(>) ;\n",
+"SEARCH on $(>) = $(SEARCH_SOURCE) ;\n",
+"MODE on $(<) = $(FILEMODE) ;\n",
+"Chmod $(<) ;\n",
+"}\n",
+"rule Fortran\n",
+"{\n",
+"DEPENDS $(<) : $(>) ;\n",
+"}\n",
+"rule GenFile \n",
+"{\n",
+"local _t = [ FGristSourceFiles $(<) ] ;\n",
+"local _s = [ FAppendSuffix $(>[1]) : $(SUFEXE) ] ;\n",
+"Depends $(_t) : $(_s) $(>[2-]) ;\n",
+"GenFile1 $(_t) : $(_s) $(>[2-]) ;\n",
+"Clean clean : $(_t) ;\n",
+"}\n",
+"rule GenFile1\n",
+"{\n",
+"MakeLocate $(<) : $(LOCATE_SOURCE) ;\n",
+"SEARCH on $(>) = $(SEARCH_SOURCE) ;\n",
+"}\n",
+"rule HardLink\n",
+"{\n",
+"DEPENDS files : $(<) ;\n",
+"DEPENDS $(<) : $(>) ;\n",
+"SEARCH on $(>) = $(SEARCH_SOURCE) ;\n",
+"}\n",
+"rule HdrMacroFile\n",
+"{\n",
+"HDRMACRO $(<) ;\n",
+"}\n",
+"rule HdrRule\n",
+"{\n",
+"local s ;\n",
+"if $(HDRGRIST) \n",
+"{ \n",
+"s = $(>:G=$(HDRGRIST)) ;\n",
+"} else { \n",
+"s = $(>) ; \n",
+"}\n",
+"INCLUDES $(<) : $(s) ;\n",
+"SEARCH on $(s) = $(HDRSEARCH) ;\n",
+"NOCARE $(s) ;\n",
+"HDRSEARCH on $(s) = $(HDRSEARCH) ;\n",
+"HDRSCAN on $(s) = $(HDRSCAN) ;\n",
+"HDRRULE on $(s) = $(HDRRULE) ;\n",
+"HDRGRIST on $(s) = $(HDRGRIST) ;\n",
+"}\n",
+"rule InstallInto\n",
+"{\n",
+"local i t ;\n",
+"t = $(>:G=$(INSTALLGRIST)) ;\n",
+"Depends install : $(t) ;\n",
+"Clean uninstall : $(t) ;\n",
+"SEARCH on $(>) = $(SEARCH_SOURCE) ;\n",
+"MakeLocate $(t) : $(<) ;\n",
+"for i in $(>)\n",
+"{\n",
+"local tt = $(i:G=$(INSTALLGRIST)) ;\n",
+"Depends $(tt) : $(i) ;\n",
+"Install $(tt) : $(i) ;\n",
+"Chmod $(tt) ;\n",
+"if $(OWNER) && $(CHOWN) \n",
+"{ \n",
+"Chown $(tt) ;\n",
+"OWNER on $(tt) = $(OWNER) ;\n",
+"}\n",
+"if $(GROUP) && $(CHGRP) \n",
+"{ \n",
+"Chgrp $(tt) ;\n",
+"GROUP on $(tt) = $(GROUP) ;\n",
+"}\n",
+"}\n",
+"}\n",
+"rule InstallBin\n",
+"{\n",
+"local _t = [ FAppendSuffix $(>) : $(SUFEXE) ] ;\n",
+"InstallInto $(<) : $(_t) ;\n",
+"MODE on $(_t:G=installed) = $(EXEMODE) ;\n",
+"}\n",
+"rule InstallFile\n",
+"{\n",
+"InstallInto $(<) : $(>) ;\n",
+"MODE on $(>:G=installed) = $(FILEMODE) ;\n",
+"}\n",
+"rule InstallLib\n",
+"{\n",
+"InstallInto $(<) : $(>) ;\n",
+"MODE on $(>:G=installed) = $(FILEMODE) ;\n",
+"}\n",
+"rule InstallMan\n",
+"{\n",
+"local i s d ;\n",
+"for i in $(>)\n",
+"{\n",
+"switch $(i:S)\n",
+"{\n",
+"case .1 : s = 1 ; case .2 : s = 2 ; case .3 : s = 3 ;\n",
+"case .4 : s = 4 ; case .5 : s = 5 ; case .6 : s = 6 ;\n",
+"case .7 : s = 7 ; case .8 : s = 8 ; case .l : s = l ;\n",
+"case .n : s = n ; case .man : s = 1 ;\n",
+"}\n",
+"d = man$(s) ;\n",
+"InstallInto $(d:R=$(<)) : $(i) ;\n",
+"}\n",
+"MODE on $(>:G=installed) = $(FILEMODE) ;\n",
+"}\n",
+"rule InstallShell\n",
+"{\n",
+"InstallInto $(<) : $(>) ;\n",
+"MODE on $(>:G=installed) = $(SHELLMODE) ;\n",
+"}\n",
+"rule Lex\n",
+"{\n",
+"LexMv $(<) : $(>) ;\n",
+"DEPENDS $(<) : $(>) ;\n",
+"MakeLocate $(<) : $(LOCATE_SOURCE) ;\n",
+"Clean clean : $(<) ;\n",
+"}\n",
+"rule Library\n",
+"{\n",
+"LibraryFromObjects $(<) : $(>:S=$(SUFOBJ)) ;\n",
+"Objects $(>) ;\n",
+"}\n",
+"rule LibraryFromObjects\n",
+"{\n",
+"local _i _l _s ;\n",
+"_s = [ FGristFiles $(>) ] ;\n",
+"_l = $(<:S=$(SUFLIB)) ;\n",
+"if $(KEEPOBJS)\n",
+"{\n",
+"DEPENDS obj : $(_s) ;\n",
+"}\n",
+"else\n",
+"{\n",
+"DEPENDS lib : $(_l) ;\n",
+"}\n",
+"if ! $(_l:D)\n",
+"{\n",
+"MakeLocate $(_l) $(_l)($(_s:BS)) : $(LOCATE_TARGET) ;\n",
+"}\n",
+"if $(NOARSCAN) \n",
+"{ \n",
+"DEPENDS $(_l) : $(_s) ;\n",
+"}\n",
+"else\n",
+"{\n",
+"DEPENDS $(_l) : $(_l)($(_s:BS)) ;\n",
+"for _i in $(_s)\n",
+"{\n",
+"DEPENDS $(_l)($(_i:BS)) : $(_i) ;\n",
+"}\n",
+"}\n",
+"Clean clean : $(_l) ;\n",
+"if $(CRELIB) { CreLib $(_l) : $(_s[1]) ; }\n",
+"Archive $(_l) : $(_s) ;\n",
+"if $(RANLIB) { Ranlib $(_l) ; }\n",
+"if ! ( $(NOARSCAN) || $(KEEPOBJS) ) { RmTemps $(_l) : $(_s) ; }\n",
+"}\n",
+"rule Link\n",
+"{\n",
+"MODE on $(<) = $(EXEMODE) ;\n",
+"Chmod $(<) ;\n",
+"}\n",
+"rule LinkLibraries\n",
+"{\n",
+"local _t = [ FAppendSuffix $(<) : $(SUFEXE) ] ;\n",
+"DEPENDS $(_t) : $(>:S=$(SUFLIB)) ;\n",
+"NEEDLIBS on $(_t) += $(>:S=$(SUFLIB)) ;\n",
+"}\n",
+"rule Main\n",
+"{\n",
+"MainFromObjects $(<) : $(>:S=$(SUFOBJ)) ;\n",
+"Objects $(>) ;\n",
+"}\n",
+"rule MainFromObjects\n",
+"{\n",
+"local _s _t ;\n",
+"_s = [ FGristFiles $(>) ] ;\n",
+"_t = [ FAppendSuffix $(<) : $(SUFEXE) ] ;\n",
+"if $(_t) != $(<)\n",
+"{\n",
+"DEPENDS $(<) : $(_t) ;\n",
+"NOTFILE $(<) ;\n",
+"}\n",
+"DEPENDS exe : $(_t) ;\n",
+"DEPENDS $(_t) : $(_s) ;\n",
+"MakeLocate $(_t) : $(LOCATE_TARGET) ;\n",
+"Clean clean : $(_t) ;\n",
+"Link $(_t) : $(_s) ;\n",
+"}\n",
+"rule MakeLocate\n",
+"{\n",
+"if $(>)\n",
+"{\n",
+"LOCATE on $(<) = $(>) ;\n",
+"Depends $(<) : $(>[1]) ;\n",
+"MkDir $(>[1]) ;\n",
+"}\n",
+"}\n",
+"rule MkDir\n",
+"{\n",
+"NOUPDATE $(<) ;\n",
+"if $(<) != $(DOT) && ! $($(<)-mkdir) \n",
+"{\n",
+"local s ;\n",
+"$(<)-mkdir = true ;\n",
+"MkDir1 $(<) ;\n",
+"Depends dirs : $(<) ;\n",
+"s = $(<:P) ;\n",
+"if $(NT)\n",
+"{\n",
+"switch $(s)\n",
+"{\n",
+"case *:   : s = ;\n",
+"case *:\\\\ : s = ;\n",
+"}\n",
+"}\n",
+"if $(s) && $(s) != $(<)\n",
+"{\n",
+"Depends $(<) : $(s) ;\n",
+"MkDir $(s) ;\n",
+"}\n",
+"else if $(s)\n",
+"{\n",
+"NOTFILE $(s) ;\n",
+"}\n",
+"}\n",
+"}\n",
+"rule Object\n",
+"{\n",
+"local h ;\n",
+"Clean clean : $(<) ;\n",
+"MakeLocate $(<) : $(LOCATE_TARGET) ;\n",
+"SEARCH on $(>) = $(SEARCH_SOURCE) ;\n",
+"HDRS on $(<) = $(SEARCH_SOURCE) $(HDRS) $(SUBDIRHDRS) ;\n",
+"if $(SEARCH_SOURCE)\n",
+"{\n",
+"h = $(SEARCH_SOURCE) ;\n",
+"}\n",
+"else\n",
+"{\n",
+"h = \"\" ;\n",
+"}\n",
+"HDRRULE on $(>) = HdrRule ;\n",
+"HDRSCAN on $(>) = $(HDRPATTERN) ;\n",
+"HDRSEARCH on $(>) = $(HDRS) $(SUBDIRHDRS) $(h) $(STDHDRS) ;\n",
+"HDRGRIST on $(>) = $(HDRGRIST) ;\n",
+"switch $(>:S)\n",
+"{\n",
+"case .asm : As $(<) : $(>) ;\n",
+"case .c :   Cc $(<) : $(>) ;\n",
+"case .C :   C++ $(<) : $(>) ;\n",
+"case .cc :  C++ $(<) : $(>) ;\n",
+"case .cpp : C++ $(<) : $(>) ;\n",
+"case .f :   Fortran $(<) : $(>) ;\n",
+"case .l :   Cc $(<) : $(<:S=.c) ;\n",
+"Lex $(<:S=.c) : $(>) ;\n",
+"case .s :   As $(<) : $(>) ;\n",
+"case .y :   Cc $(<) : $(<:S=.c) ;\n",
+"Yacc $(<:S=.c) : $(>) ;\n",
+"case * :    UserObject $(<) : $(>) ;\n",
+"}\n",
+"}\n",
+"rule ObjectCcFlags\n",
+"{\n",
+"CCFLAGS on [ FGristFiles $(<:S=$(SUFOBJ)) ] += $(>) ;\n",
+"}\n",
+"rule ObjectC++Flags\n",
+"{\n",
+"C++FLAGS on [ FGristFiles $(<:S=$(SUFOBJ)) ] += $(>) ;\n",
+"}\n",
+"rule ObjectHdrs\n",
+"{\n",
+"HDRS on [ FGristFiles $(<:S=$(SUFOBJ)) ] += $(>) ;\n",
+"}\n",
+"rule Objects\n",
+"{\n",
+"local _i ;\n",
+"for _i in [ FGristFiles $(<) ]\n",
+"{\n",
+"Object $(_i:S=$(SUFOBJ)) : $(_i) ;\n",
+"DEPENDS obj : $(_i:S=$(SUFOBJ)) ;\n",
+"}\n",
+"}\n",
+"rule RmTemps\n",
+"{\n",
+"TEMPORARY $(>) ;\n",
+"}\n",
+"rule Setuid\n",
+"{\n",
+"MODE on [ FAppendSuffix $(<) : $(SUFEXE) ] = 4711 ;\n",
+"}\n",
+"rule Shell\n",
+"{\n",
+"DEPENDS shell : $(<) ;\n",
+"DEPENDS $(<) : $(>) ;\n",
+"SEARCH on $(>) = $(SEARCH_SOURCE) ;\n",
+"MODE on $(<) = $(SHELLMODE) ;\n",
+"Clean clean : $(<) ;\n",
+"Chmod $(<) ;\n",
+"}\n",
+"rule SubDir\n",
+"{\n",
+"local _r _s ;\n",
+"if ! $($(<[1]))\n",
+"{\n",
+"if ! $(<[1])\n",
+"{\n",
+"EXIT SubDir syntax error ;\n",
+"}\n",
+"$(<[1]) = [ FSubDir $(<[2-]) ] ;\n",
+"}\n",
+"if ! $($(<[1])-included)\n",
+"{\n",
+"$(<[1])-included = TRUE ;\n",
+"_r = $($(<[1])RULES) ;\n",
+"if ! $(_r)\n",
+"{\n",
+"_r = $(JAMRULES:R=$($(<[1]))) ;\n",
+"}\n",
+"include $(_r) ;\n",
+"}\n",
+"_s = [ FDirName $(<[2-]) ] ;\n",
+"SUBDIR = $(_s:R=$($(<[1]))) ;\n",
+"SUBDIR_TOKENS = $(<[2-]) ;\n",
+"SEARCH_SOURCE = $(SUBDIR) ;\n",
+"LOCATE_SOURCE = $(ALL_LOCATE_TARGET) $(SUBDIR) ;\n",
+"LOCATE_TARGET = $(ALL_LOCATE_TARGET) $(SUBDIR) ;\n",
+"SOURCE_GRIST = [ FGrist $(<[2-]) ] ;\n",
+"SUBDIRCCFLAGS = ;\n",
+"SUBDIRC++FLAGS = ;\n",
+"SUBDIRHDRS = ;\n",
+"}\n",
+"rule SubDirCcFlags\n",
+"{\n",
+"SUBDIRCCFLAGS += $(<) ;\n",
+"}\n",
+"rule SubDirC++Flags\n",
+"{\n",
+"SUBDIRC++FLAGS += $(<) ;\n",
+"}\n",
+"rule SubDirHdrs\n",
+"{\n",
+"SUBDIRHDRS += $(<) ;\n",
+"}\n",
+"rule SubInclude\n",
+"{\n",
+"local _s ;\n",
+"if ! $($(<[1]))\n",
+"{\n",
+"EXIT Top level of source tree has not been set with $(<[1]) ;\n",
+"}\n",
+"_s = [ FDirName $(<[2-]) ] ;\n",
+"include $(JAMFILE:D=$(_s):R=$($(<[1]))) ;\n",
+"}\n",
+"rule Undefines\n",
+"{\n",
+"UNDEFS on [ FAppendSuffix $(<) : $(SUFEXE) ] += $(UNDEFFLAG)$(>) ;\n",
+"}\n",
+"rule UserObject\n",
+"{\n",
+"EXIT \"Unknown suffix on\" $(>) \"- see UserObject rule in Jamfile(5).\" ;\n",
+"}\n",
+"rule Yacc\n",
+"{\n",
+"local _h ;\n",
+"_h = $(<:BS=.h) ;\n",
+"MakeLocate $(<) $(_h) : $(LOCATE_SOURCE) ;\n",
+"if $(YACC)\n",
+"{\n",
+"DEPENDS $(<) $(_h) : $(>) ;\n",
+"Yacc1 $(<) $(_h) : $(>) ;\n",
+"YaccMv $(<) $(_h) : $(>) ;\n",
+"Clean clean : $(<) $(_h) ;\n",
+"}\n",
+"INCLUDES $(<) : $(_h) ;\n",
+"}\n",
+"rule FGrist\n",
+"{\n",
+"local _g _i ;\n",
+"_g = $(<[1]) ;\n",
+"for _i in $(<[2-])\n",
+"{\n",
+"_g = $(_g)!$(_i) ;\n",
+"}\n",
+"return $(_g) ;\n",
+"}\n",
+"rule FGristFiles \n",
+"{\n",
+"if ! $(SOURCE_GRIST)\n",
+"{\n",
+"return $(<) ;\n",
+"}\n",
+"else \n",
+"{\n",
+"return $(<:G=$(SOURCE_GRIST)) ;\n",
+"}\n",
+"}\n",
+"rule FGristSourceFiles\n",
+"{\n",
+"if ! $(SOURCE_GRIST)\n",
+"{\n",
+"return $(<) ;\n",
+"}\n",
+"else \n",
+"{\n",
+"local _i _o ;\n",
+"for _i in $(<)\n",
+"{\n",
+"switch $(_i)\n",
+"{\n",
+"case *.h :  _o += $(_i) ;\n",
+"case * :    _o += $(_i:G=$(SOURCE_GRIST)) ;\n",
+"}\n",
+"}\n",
+"return $(_o) ;\n",
+"}\n",
+"}\n",
+"rule FConcat\n",
+"{\n",
+"local _t _r ;\n",
+"$(_r) = $(<[1]) ;\n",
+"for _t in $(<[2-])\n",
+"{\n",
+"$(_r) = $(_r)$(_t) ;\n",
+"}\n",
+"return $(_r) ;\n",
+"}\n",
+"rule FSubDir\n",
+"{\n",
+"local _i _d ;\n",
+"if ! $(<[1]) \n",
+"{\n",
+"_d = $(DOT) ;\n",
+"} \n",
+"else\n",
+"{\n",
+"_d = $(DOTDOT) ;\n",
+"for _i in $(<[2-])\n",
+"{\n",
+"_d = $(_d:R=$(DOTDOT)) ;\n",
+"}\n",
+"}\n",
+"return $(_d) ;\n",
+"}\n",
+"rule FDirName\n",
+"{\n",
+"local _s _i ;\n",
+"if ! $(<)\n",
+"{\n",
+"_s = $(DOT) ;\n",
+"}\n",
+"else if $(VMS)\n",
+"{\n",
+"switch $(<[1])\n",
+"{\n",
+"case *:* : _s = $(<[1]) ;\n",
+"case \\\\[*\\\\] : _s = $(<[1]) ;\n",
+"case * : _s = [.$(<[1])] ;\n",
+"}\n",
+"for _i in [.$(<[2-])]\n",
+"{\n",
+"_s = $(_i:R=$(_s)) ;\n",
+"}\n",
+"}\n",
+"else if $(MAC)\n",
+"{\n",
+"_s = $(DOT) ;\n",
+"for _i in $(<)\n",
+"{\n",
+"_s = $(_i:R=$(_s)) ;\n",
+"}\n",
+"}\n",
+"else\n",
+"{\n",
+"_s = $(<[1]) ; \n",
+"for _i in $(<[2-])\n",
+"{\n",
+"_s = $(_i:R=$(_s)) ;\n",
+"}\n",
+"}\n",
+"return $(_s) ;\n",
+"}\n",
+"rule _makeCommon\n",
+"{\n",
+"if $($(<)[1]) && $($(<)[1]) = $($(>)[1])\n",
+"{\n",
+"$(<) = $($(<)[2-]) ;\n",
+"$(>) = $($(>)[2-]) ;\n",
+"_makeCommon $(<) : $(>) ;\n",
+"}\n",
+"}\n",
+"rule FRelPath\n",
+"{\n",
+"local _l _r ;\n",
+"_l = $(<) ;\n",
+"_r = $(>) ;\n",
+"_makeCommon _l : _r ;\n",
+"_l = [ FSubDir $(_l) ] ;\n",
+"_r = [ FDirName $(_r) ] ;\n",
+"if $(_r) = $(DOT) {\n",
+"return $(_l) ;\n",
+"} else {\n",
+"return $(_r:R=$(_l)) ;\n",
+"}\n",
+"}\n",
+"rule FAppendSuffix\n",
+"{\n",
+"if $(>)\n",
+"{\n",
+"local _i _o ;\n",
+"for _i in $(<)\n",
+"{\n",
+"if $(_i:S)\n",
+"{\n",
+"_o += $(_i) ;\n",
+"}\n",
+"else\n",
+"{\n",
+"_o += $(_i:S=$(>)) ;\n",
+"}\n",
+"}\n",
+"return $(_o) ;\n",
+"}\n",
+"else\n",
+"{\n",
+"return $(<) ;\n",
+"}\n",
+"}\n",
+"rule unmakeDir\n",
+"{\n",
+"if $(>[1]:D) && $(>[1]:D) != $(>[1]) && $(>[1]:D) != \\\\\\\\ \n",
+"{\n",
+"unmakeDir $(<) : $(>[1]:D) $(>[1]:BS) $(>[2-]) ;\n",
+"}\n",
+"else\n",
+"{\n",
+"$(<) = $(>) ;\n",
+"}\n",
+"}\n",
+"rule FConvertToSlashes\n",
+"{\n",
+"local _d, _s, _i ;\n",
+"unmakeDir _d : $(<) ;\n",
+"_s = $(_d[1]) ; \n",
+"for _i in $(_d[2-])\n",
+"{\n",
+"_s = $(_s)/$(_i) ;\n",
+"}\n",
+"return $(_s) ;\n",
+"}\n",
+"actions updated together piecemeal Archive\n",
+"{\n",
+"$(AR) $(<) $(>)\n",
+"}\n",
+"actions As\n",
+"{\n",
+"$(AS) $(ASFLAGS) -I$(HDRS) -o $(<) $(>)\n",
+"}\n",
+"actions C++\n",
+"{\n",
+"$(C++) -c $(C++FLAGS) $(OPTIM) -I$(HDRS) -o $(<) $(>)\n",
+"}\n",
+"actions Cc\n",
+"{\n",
+"$(CC) -c $(CCFLAGS) $(OPTIM) -I$(HDRS) -o $(<) $(>)\n",
+"}\n",
+"actions Chgrp\n",
+"{\n",
+"$(CHGRP) $(GROUP) $(<)\n",
+"}\n",
+"actions Chmod1\n",
+"{\n",
+"$(CHMOD) $(MODE) $(<)\n",
+"}\n",
+"actions Chown\n",
+"{\n",
+"$(CHOWN) $(OWNER) $(<)\n",
+"}\n",
+"actions piecemeal together existing Clean\n",
+"{\n",
+"$(RM) $(>)\n",
+"}\n",
+"actions File\n",
+"{\n",
+"$(CP) $(>) $(<)\n",
+"}\n",
+"actions GenFile1\n",
+"{\n",
+"$(>[1]) $(<) $(>[2-])\n",
+"}\n",
+"actions Fortran\n",
+"{\n",
+"$(FORTRAN) $(FORTRANFLAGS) -o $(<) $(>)\n",
+"}\n",
+"actions HardLink\n",
+"{\n",
+"$(RM) $(<) && $(LN) $(>) $(<)\n",
+"}\n",
+"actions Install\n",
+"{\n",
+"$(CP) $(>) $(<) \n",
+"}\n",
+"actions Lex\n",
+"{\n",
+"$(LEX) $(>)\n",
+"}\n",
+"actions LexMv\n",
+"{\n",
+"$(MV) lex.yy.c $(<)\n",
+"}\n",
+"actions Link bind NEEDLIBS\n",
+"{\n",
+"$(LINK) $(LINKFLAGS) -o $(<) $(UNDEFS) $(>) $(NEEDLIBS) $(LINKLIBS) \n",
+"}\n",
+"actions MkDir1\n",
+"{\n",
+"$(MKDIR) $(<)\n",
+"}\n",
+"actions together Ranlib\n",
+"{\n",
+"$(RANLIB) $(<)\n",
+"}\n",
+"actions quietly updated piecemeal together RmTemps\n",
+"{\n",
+"$(RM) $(>)\n",
+"}\n",
+"actions Shell\n",
+"{\n",
+"$(AWK) '\n",
+"NR == 1 { print \"$(SHELLHEADER)\" }\n",
+"NR == 1 && /^[#:]/ { next }\n",
+"/^##/ { next }\n",
+"{ print }\n",
+"' < $(>) > $(<)\n",
+"}\n",
+"actions Yacc1\n",
+"{\n",
+"$(YACC) $(YACCFLAGS) $(>)\n",
+"}\n",
+"actions YaccMv\n",
+"{\n",
+"$(MV) $(YACCFILES).c $(<[1])\n",
+"$(MV) $(YACCFILES).h $(<[2])\n",
+"}\n",
+"if $(RELOCATE)\n",
+"{\n",
+"actions C++\n",
+"{\n",
+"$(C++) -c $(C++FLAGS) $(OPTIM) -I$(HDRS) $(>)\n",
+"}\n",
+"actions Cc\n",
+"{\n",
+"$(CC) -c $(CCFLAGS) $(OPTIM) -I$(HDRS) $(>)\n",
+"}\n",
+"actions ignore CcMv\n",
+"{\n",
+"[ $(<) != $(>:BS=$(SUFOBJ)) ] && $(MV) $(>:BS=$(SUFOBJ)) $(<)\n",
+"}\n",
+"}\n",
+"if $(NOARUPDATE)\n",
+"{\n",
+"actions Archive\n",
+"{\n",
+"$(AR) $(<) $(>)\n",
+"}\n",
+"}\n",
+"if $(NT)\n",
+"{\n",
+"if $(TOOLSET) = VISUALC || $(TOOLSET) = VC7 || $(TOOLSET) = INTELC\n",
+"{\n",
+"actions updated together piecemeal Archive\n",
+"{\n",
+"if exist $(<) set _$(<:B)_=$(<)\n",
+"$(AR) /out:$(<) %_$(<:B)_% $(>)\n",
+"}\n",
+"actions As\n",
+"{\n",
+"$(AS) /Ml /p /v /w2 $(>) $(<) ,nul,nul;\n",
+"}\n",
+"actions Cc\n",
+"{\n",
+"$(CC) /c $(CCFLAGS) $(OPTIM) /Fo$(<) /I$(HDRS) /I$(STDHDRS) $(>)\n",
+"}\n",
+"actions C++\n",
+"{\n",
+"$(C++) /c $(C++FLAGS) $(OPTIM) /Fo$(<) /I$(HDRS) /I$(STDHDRS) /Tp$(>)\n",
+"}\n",
+"actions Link bind NEEDLIBS\n",
+"{\n",
+"$(LINK) $(LINKFLAGS) /out:$(<) $(UNDEFS) $(>) $(NEEDLIBS) $(LINKLIBS)\n",
+"}\n",
+"}\n",
+"else if $(TOOLSET) = VISUALC16\n",
+"{\n",
+"actions updated together piecemeal Archive\n",
+"{\n",
+"$(AR) $(<) -+$(>)\n",
+"}\n",
+"actions Cc\n",
+"{\n",
+"$(CC) /c $(CCFLAGS) $(OPTIM) /Fo$(<) /I$(HDRS) $(>)\n",
+"}\n",
+"actions C++\n",
+"{\n",
+"$(C++) /c $(C++FLAGS) $(OPTIM) /Fo$(<) /I$(HDRS) /Tp$(>)\n",
+"}\n",
+"actions Link bind NEEDLIBS\n",
+"{\n",
+"$(LINK) $(LINKFLAGS) /out:$(<) $(UNDEFS) $(>) $(NEEDLIBS) $(LINKLIBS)\n",
+"}\n",
+"}\n",
+"else if $(TOOLSET) = BORLANDC\n",
+"{\n",
+"actions updated together piecemeal Archive\n",
+"{\n",
+"$(AR) $(<) -+$(>)\n",
+"}\n",
+"actions Link bind NEEDLIBS\n",
+"{\n",
+"$(LINK) -e$(<) $(LINKFLAGS) $(UNDEFS) -L$(LINKLIBS) $(NEEDLIBS) $(>)\n",
+"}\n",
+"actions C++\n",
+"{\n",
+"$(C++) -c $(C++FLAGS) $(OPTIM) -I$(HDRS) -o$(<) $(>)\n",
+"}\n",
+"actions Cc\n",
+"{\n",
+"$(CC) -c $(CCFLAGS) $(OPTIM) -I$(HDRS) -o$(<) $(>)\n",
+"}\n",
+"}\n",
+"else if $(TOOLSET) = MINGW\n",
+"{\n",
+"actions together piecemeal Archive\n",
+"{\n",
+"$(AR) $(<) $(>:T)\n",
+"}\n",
+"actions Cc\n",
+"{\n",
+"$(CC) -c $(CCFLAGS) $(OPTIM) -I$(HDRS) -o$(<) $(>)\n",
+"}\n",
+"actions C++\n",
+"{\n",
+"$(C++) -c $(C++FLAGS) $(OPTIM) -I$(HDRS) -o$(<) $(>)\n",
+"}\n",
+"}\n",
+"else if $(TOOLSET) = WATCOM\n",
+"{\n",
+"actions together piecemeal Archive\n",
+"{\n",
+"$(AR) $(<) +-$(>) \n",
+"}\n",
+"actions Cc\n",
+"{\n",
+"$(CC) $(CCFLAGS) $(OPTIM) /Fo=$(<) /I$(HDRS) $(>)\n",
+"}\n",
+"actions C++\n",
+"{\n",
+"$(C++) $(C++FLAGS) $(OPTIM) /Fo=$(<) /I$(HDRS) $(>)\n",
+"}\n",
+"actions Link bind NEEDLIBS\n",
+"{\n",
+"$(LINK) $(LINKFLAGS) /Fe=$(<) $(UNDEFS) $(>) $(NEEDLIBS) $(LINKLIBS)\n",
+"}\n",
+"actions Shell\n",
+"{\n",
+"$(CP) $(>) $(<)\n",
+"}\n",
+"}\n",
+"else if $(TOOLSET) = LCC\n",
+"{\n",
+"actions together piecemeal Archive\n",
+"{\n",
+"$(AR) /out:$(<) $(>) \n",
+"}\n",
+"actions Cc\n",
+"{\n",
+"$(CC) $(CCFLAGS) $(OPTIM) -Fo$(<) -I$(HDRS) $(>)\n",
+"}\n",
+"actions Link bind NEEDLIBS\n",
+"{\n",
+"$(LINK) $(LINKFLAGS) -o $(<) $(UNDEFS) $(>) $(NEEDLIBS) $(LINKLIBS)\n",
+"}\n",
+"actions Shell\n",
+"{\n",
+"$(CP) $(>) $(<)\n",
+"}\n",
+"}\n",
+"}\n",
+"else if $(OS2)             \n",
+"{\n",
+"if $(TOOLSET) = WATCOM\n",
+"{\n",
+"actions together piecemeal Archive\n",
+"{\n",
+"$(AR) $(<) +-$(>) \n",
+"}\n",
+"actions Cc\n",
+"{\n",
+"$(CC) $(CCFLAGS) $(OPTIM) /Fo=$(<) /I$(HDRS) $(>)\n",
+"}\n",
+"actions C++\n",
+"{\n",
+"$(C++) $(C++FLAGS) $(OPTIM) /Fo=$(<) /I$(HDRS) $(>)\n",
+"}\n",
+"actions Link bind NEEDLIBS\n",
+"{\n",
+"$(LINK) $(LINKFLAGS) /Fe=$(<) $(UNDEFS) $(>) $(NEEDLIBS) $(LINKLIBS)\n",
+"}\n",
+"actions Shell\n",
+"{\n",
+"$(CP) $(>) $(<)\n",
+"}\n",
+"}\n",
+"else if $(TOOLSET) = EMX\n",
+"{\n",
+"actions together piecemeal Archive\n",
+"{\n",
+"$(AR) $(<) $(>:T)\n",
+"}\n",
+"actions Cc\n",
+"{\n",
+"$(CC) -c $(CCFLAGS) $(OPTIM) -I$(HDRS) -o$(<) $(>)\n",
+"}\n",
+"actions C++\n",
+"{\n",
+"$(C++) -c $(C++FLAGS) $(OPTIM) -I$(HDRS) -o$(<) $(>)\n",
+"}\n",
+"}\n",
+"}\n",
+"else if $(VMS)\n",
+"{\n",
+"actions updated together piecemeal Archive \n",
+"{\n",
+"lib/replace $(<) $(>[1]) ,$(>[2-])\n",
+"}\n",
+"actions Cc\n",
+"{ \n",
+"$(CC)/obj=$(<) $(CCFLAGS) $(OPTIM) $(SLASHINC) $(>) \n",
+"}\n",
+"actions C++\n",
+"{ \n",
+"$(C++)/obj=$(<) $(C++FLAGS) $(OPTIM) $(SLASHINC) $(>) \n",
+"}\n",
+"actions piecemeal together existing Clean\n",
+"{\n",
+"$(RM) $(>[1]);* ,$(>[2-]);*\n",
+"}\n",
+"actions together quietly CreLib\n",
+"{\n",
+"if f$search(\"$(<)\") .eqs. \"\" then lib/create $(<)\n",
+"}\n",
+"actions GenFile1\n",
+"{\n",
+"mcr $(>[1]) $(<) $(>[2-])\n",
+"}\n",
+"actions Link bind NEEDLIBS\n",
+"{\n",
+"$(LINK)/exe=$(<) $(LINKFLAGS) $(>[1]) ,$(>[2-]) ,$(NEEDLIBS)/lib ,$(LINKLIBS)\n",
+"}\n",
+"actions quietly updated piecemeal together RmTemps\n",
+"{\n",
+"$(RM) $(>[1]);* ,$(>[2-]);*\n",
+"}\n",
+"actions Shell\n",
+"{\n",
+"$(CP) $(>) $(<)\n",
+"}\n",
+"}\n",
+"else if $(MAC)\n",
+"{\n",
+"actions together Archive \n",
+"{\n",
+"$(LINK) -library -o $(<) $(>)\n",
+"}\n",
+"actions Cc\n",
+"{\n",
+"set -e MWCincludes $(MACINC)\n",
+"$(CC) -o $(<) $(CCFLAGS) $(OPTIM) $(>) \n",
+"}\n",
+"actions C++\n",
+"{ \n",
+"set -e MWCincludes $(MACINC)\n",
+"$(CC) -o $(<) $(C++FLAGS) $(OPTIM) $(>) \n",
+"}\n",
+"actions Link bind NEEDLIBS\n",
+"{\n",
+"$(LINK) -o $(<) $(LINKFLAGS) $(>) $(NEEDLIBS) \"$(LINKLIBS)\"\n",
+"}\n",
+"}\n",
+"rule BULK { Bulk $(<) : $(>) ; }\n",
+"rule FILE { File $(<) : $(>) ; }\n",
+"rule HDRRULE { HdrRule $(<) : $(>) ; }\n",
+"rule INSTALL { Install $(<) : $(>) ; }\n",
+"rule LIBRARY { Library $(<) : $(>) ; }\n",
+"rule LIBS { LinkLibraries $(<) : $(>) ; }\n",
+"rule LINK { Link $(<) : $(>) ; }\n",
+"rule MAIN { Main $(<) : $(>) ; }\n",
+"rule SETUID { Setuid $(<) ; }\n",
+"rule SHELL { Shell $(<) : $(>) ; }\n",
+"rule UNDEFINES { Undefines $(<) : $(>) ; }\n",
+"rule INSTALLBIN { InstallBin $(BINDIR) : $(<) ; }\n",
+"rule INSTALLLIB { InstallLib $(LIBDIR) : $(<) ; }\n",
+"rule INSTALLMAN { InstallMan $(MANDIR) : $(<) ; }\n",
+"rule addDirName { $(<) += [ FDirName $(>) ] ; }\n",
+"rule makeDirName { $(<) = [ FDirName $(>) ] ; }\n",
+"rule makeGristedName { $(<) = [ FGristSourceFiles $(>) ] ; }\n",
+"rule makeRelPath { $(<[1]) = [ FRelPath $(<[2-]) : $(>) ] ; }\n",
+"rule makeSuffixed { $(<[1]) = [ FAppendSuffix $(>) : $(<[2]) ] ; }\n",
+"{\n",
+"if $(JAMFILE) { include $(JAMFILE) ; }\n",
+"}\n",
+"}\n",
+0 };

Added: boost-jam/boost-build/branches/upstream/current/jam_src/jambase.h
===================================================================
--- boost-jam/boost-build/branches/upstream/current/jam_src/jambase.h	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/jam_src/jambase.h	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,15 @@
+/*
+ * Copyright 1993, 1995 Christopher Seiwald.
+ *
+ * This file is part of Jam - see jam.c for Copyright information.
+ */
+
+/*
+ * jambase.h - declaration for the internal jambase
+ *
+ * The file Jambase is turned into a C array of strings in jambase.c
+ * so that it can be built in to the executable.  This is the 
+ * declaration for that array.
+ */
+
+extern char *jambase[];

Added: boost-jam/boost-build/branches/upstream/current/jam_src/jamgram.c
===================================================================
--- boost-jam/boost-build/branches/upstream/current/jam_src/jamgram.c	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/jam_src/jamgram.c	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,1830 @@
+/* A Bison parser, made by GNU Bison 1.875.  */
+
+/* Skeleton parser for Yacc-like parsing with Bison,
+   Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+/* As a special exception, when this file is copied by Bison into a
+   Bison output file, you may use that output file without restriction.
+   This special exception was added by the Free Software Foundation
+   in version 1.24 of Bison.  */
+
+/* Written by Richard Stallman by simplifying the original so called
+   ``semantic'' parser.  */
+
+/* All symbols defined below should begin with yy or YY, to avoid
+   infringing on user name space.  This should be done even for local
+   variables, as they might otherwise be expanded by user macros.
+   There are some unavoidable exceptions within include files to
+   define necessary library symbols; they are noted "INFRINGES ON
+   USER NAME SPACE" below.  */
+
+/* Identify Bison output.  */
+#define YYBISON 1
+
+/* Skeleton name.  */
+#define YYSKELETON_NAME "yacc.c"
+
+/* Pure parsers.  */
+#define YYPURE 0
+
+/* Using locations.  */
+#define YYLSP_NEEDED 0
+
+
+
+/* Tokens.  */
+#ifndef YYTOKENTYPE
+# define YYTOKENTYPE
+   /* Put the tokens into the symbol table, so that GDB and other debuggers
+      know about them.  */
+   enum yytokentype {
+     _BANG_t = 258,
+     _BANG_EQUALS_t = 259,
+     _AMPER_t = 260,
+     _AMPERAMPER_t = 261,
+     _LPAREN_t = 262,
+     _RPAREN_t = 263,
+     _PLUS_EQUALS_t = 264,
+     _COLON_t = 265,
+     _SEMIC_t = 266,
+     _LANGLE_t = 267,
+     _LANGLE_EQUALS_t = 268,
+     _EQUALS_t = 269,
+     _RANGLE_t = 270,
+     _RANGLE_EQUALS_t = 271,
+     _QUESTION_EQUALS_t = 272,
+     _LBRACKET_t = 273,
+     _RBRACKET_t = 274,
+     ACTIONS_t = 275,
+     BIND_t = 276,
+     CASE_t = 277,
+     CLASS_t = 278,
+     DEFAULT_t = 279,
+     ELSE_t = 280,
+     EXISTING_t = 281,
+     FOR_t = 282,
+     IF_t = 283,
+     IGNORE_t = 284,
+     IN_t = 285,
+     INCLUDE_t = 286,
+     LOCAL_t = 287,
+     MODULE_t = 288,
+     ON_t = 289,
+     PIECEMEAL_t = 290,
+     QUIETLY_t = 291,
+     RETURN_t = 292,
+     RULE_t = 293,
+     SWITCH_t = 294,
+     TOGETHER_t = 295,
+     UPDATED_t = 296,
+     WHILE_t = 297,
+     _LBRACE_t = 298,
+     _BAR_t = 299,
+     _BARBAR_t = 300,
+     _RBRACE_t = 301,
+     ARG = 302,
+     STRING = 303
+   };
+#endif
+#define _BANG_t 258
+#define _BANG_EQUALS_t 259
+#define _AMPER_t 260
+#define _AMPERAMPER_t 261
+#define _LPAREN_t 262
+#define _RPAREN_t 263
+#define _PLUS_EQUALS_t 264
+#define _COLON_t 265
+#define _SEMIC_t 266
+#define _LANGLE_t 267
+#define _LANGLE_EQUALS_t 268
+#define _EQUALS_t 269
+#define _RANGLE_t 270
+#define _RANGLE_EQUALS_t 271
+#define _QUESTION_EQUALS_t 272
+#define _LBRACKET_t 273
+#define _RBRACKET_t 274
+#define ACTIONS_t 275
+#define BIND_t 276
+#define CASE_t 277
+#define CLASS_t 278
+#define DEFAULT_t 279
+#define ELSE_t 280
+#define EXISTING_t 281
+#define FOR_t 282
+#define IF_t 283
+#define IGNORE_t 284
+#define IN_t 285
+#define INCLUDE_t 286
+#define LOCAL_t 287
+#define MODULE_t 288
+#define ON_t 289
+#define PIECEMEAL_t 290
+#define QUIETLY_t 291
+#define RETURN_t 292
+#define RULE_t 293
+#define SWITCH_t 294
+#define TOGETHER_t 295
+#define UPDATED_t 296
+#define WHILE_t 297
+#define _LBRACE_t 298
+#define _BAR_t 299
+#define _BARBAR_t 300
+#define _RBRACE_t 301
+#define ARG 302
+#define STRING 303
+
+
+
+
+/* Copy the first part of user declarations.  */
+#line 96 "jamgram.y"
+
+#include "jam.h"
+
+#include "lists.h"
+#include "parse.h"
+#include "scan.h"
+#include "compile.h"
+#include "newstr.h"
+#include "rules.h"
+
+# define YYMAXDEPTH 10000	/* for OSF and other less endowed yaccs */
+
+# define F0 (LIST *(*)(PARSE *, FRAME *))0
+# define P0 (PARSE *)0
+# define S0 (char *)0
+
+# define pappend( l,r )    	parse_make( compile_append,l,r,P0,S0,S0,0 )
+# define peval( c,l,r )	parse_make( compile_eval,l,r,P0,S0,S0,c )
+# define pfor( s,l,r,x )    	parse_make( compile_foreach,l,r,P0,s,S0,x )
+# define pif( l,r,t )	  	parse_make( compile_if,l,r,t,S0,S0,0 )
+# define pincl( l )       	parse_make( compile_include,l,P0,P0,S0,S0,0 )
+# define plist( s )	  	parse_make( compile_list,P0,P0,P0,s,S0,0 )
+# define plocal( l,r,t )  	parse_make( compile_local,l,r,t,S0,S0,0 )
+# define pmodule( l,r )	  	parse_make( compile_module,l,r,P0,S0,S0,0 )
+# define pclass( l,r )	  	parse_make( compile_class,l,r,P0,S0,S0,0 )
+# define pnull()	  	parse_make( compile_null,P0,P0,P0,S0,S0,0 )
+# define pon( l,r )	  	parse_make( compile_on,l,r,P0,S0,S0,0 )
+# define prule( s,p )     	parse_make( compile_rule,p,P0,P0,s,S0,0 )
+# define prules( l,r )	  	parse_make( compile_rules,l,r,P0,S0,S0,0 )
+# define pset( l,r,a )          parse_make( compile_set,l,r,P0,S0,S0,a )
+# define pset1( l,r,t,a )	parse_make( compile_settings,l,r,t,S0,S0,a )
+# define psetc( s,p,a,l )     	parse_make( compile_setcomp,p,a,P0,s,S0,l )
+# define psete( s,l,s1,f ) 	parse_make( compile_setexec,l,P0,P0,s,s1,f )
+# define pswitch( l,r )   	parse_make( compile_switch,l,r,P0,S0,S0,0 )
+# define pwhile( l,r )   	parse_make( compile_while,l,r,P0,S0,S0,0 )
+
+# define pnode( l,r )    	parse_make( F0,l,r,P0,S0,S0,0 )
+# define psnode( s,l )     	parse_make( F0,l,P0,P0,s,S0,0 )
+
+
+
+/* Enabling traces.  */
+#ifndef YYDEBUG
+# define YYDEBUG 0
+#endif
+
+/* Enabling verbose error messages.  */
+#ifdef YYERROR_VERBOSE
+# undef YYERROR_VERBOSE
+# define YYERROR_VERBOSE 1
+#else
+# define YYERROR_VERBOSE 0
+#endif
+
+#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED)
+typedef int YYSTYPE;
+# define yystype YYSTYPE /* obsolescent; will be withdrawn */
+# define YYSTYPE_IS_DECLARED 1
+# define YYSTYPE_IS_TRIVIAL 1
+#endif
+
+
+
+/* Copy the second part of user declarations.  */
+
+
+/* Line 214 of yacc.c.  */
+#line 223 "y.tab.c"
+
+#if ! defined (yyoverflow) || YYERROR_VERBOSE
+
+/* The parser invokes alloca or malloc; define the necessary symbols.  */
+
+# if YYSTACK_USE_ALLOCA
+#  define YYSTACK_ALLOC alloca
+# else
+#  ifndef YYSTACK_USE_ALLOCA
+#   if defined (alloca) || defined (_ALLOCA_H)
+#    define YYSTACK_ALLOC alloca
+#   else
+#    ifdef __GNUC__
+#     define YYSTACK_ALLOC __builtin_alloca
+#    endif
+#   endif
+#  endif
+# endif
+
+# ifdef YYSTACK_ALLOC
+   /* Pacify GCC's `empty if-body' warning. */
+#  define YYSTACK_FREE(Ptr) do { /* empty */; } while (0)
+# else
+#  if defined (__STDC__) || defined (__cplusplus)
+#   include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
+#   define YYSIZE_T size_t
+#  endif
+#  define YYSTACK_ALLOC malloc
+#  define YYSTACK_FREE free
+# endif
+#endif /* ! defined (yyoverflow) || YYERROR_VERBOSE */
+
+
+#if (! defined (yyoverflow) \
+     && (! defined (__cplusplus) \
+	 || (YYSTYPE_IS_TRIVIAL)))
+
+/* A type that is properly aligned for any stack member.  */
+union yyalloc
+{
+  short yyss;
+  YYSTYPE yyvs;
+  };
+
+/* The size of the maximum gap between one aligned stack and the next.  */
+# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1)
+
+/* The size of an array large to enough to hold all stacks, each with
+   N elements.  */
+# define YYSTACK_BYTES(N) \
+     ((N) * (sizeof (short) + sizeof (YYSTYPE))				\
+      + YYSTACK_GAP_MAXIMUM)
+
+/* Copy COUNT objects from FROM to TO.  The source and destination do
+   not overlap.  */
+# ifndef YYCOPY
+#  if 1 < __GNUC__
+#   define YYCOPY(To, From, Count) \
+      __builtin_memcpy (To, From, (Count) * sizeof (*(From)))
+#  else
+#   define YYCOPY(To, From, Count)		\
+      do					\
+	{					\
+	  register YYSIZE_T yyi;		\
+	  for (yyi = 0; yyi < (Count); yyi++)	\
+	    (To)[yyi] = (From)[yyi];		\
+	}					\
+      while (0)
+#  endif
+# endif
+
+/* Relocate STACK from its old location to the new one.  The
+   local variables YYSIZE and YYSTACKSIZE give the old and new number of
+   elements in the stack, and YYPTR gives the new location of the
+   stack.  Advance YYPTR to a properly aligned location for the next
+   stack.  */
+# define YYSTACK_RELOCATE(Stack)					\
+    do									\
+      {									\
+	YYSIZE_T yynewbytes;						\
+	YYCOPY (&yyptr->Stack, Stack, yysize);				\
+	Stack = &yyptr->Stack;						\
+	yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
+	yyptr += yynewbytes / sizeof (*yyptr);				\
+      }									\
+    while (0)
+
+#endif
+
+#if defined (__STDC__) || defined (__cplusplus)
+   typedef signed char yysigned_char;
+#else
+   typedef short yysigned_char;
+#endif
+
+/* YYFINAL -- State number of the termination state. */
+#define YYFINAL  43
+/* YYLAST -- Last index in YYTABLE.  */
+#define YYLAST   261
+
+/* YYNTOKENS -- Number of terminals. */
+#define YYNTOKENS  49
+/* YYNNTS -- Number of nonterminals. */
+#define YYNNTS  24
+/* YYNRULES -- Number of rules. */
+#define YYNRULES  75
+/* YYNRULES -- Number of states. */
+#define YYNSTATES  159
+
+/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX.  */
+#define YYUNDEFTOK  2
+#define YYMAXUTOK   303
+
+#define YYTRANSLATE(YYX) 						\
+  ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
+
+/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX.  */
+static const unsigned char yytranslate[] =
+{
+       0,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     1,     2,     3,     4,
+       5,     6,     7,     8,     9,    10,    11,    12,    13,    14,
+      15,    16,    17,    18,    19,    20,    21,    22,    23,    24,
+      25,    26,    27,    28,    29,    30,    31,    32,    33,    34,
+      35,    36,    37,    38,    39,    40,    41,    42,    43,    44,
+      45,    46,    47,    48
+};
+
+#if YYDEBUG
+/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in
+   YYRHS.  */
+static const unsigned char yyprhs[] =
+{
+       0,     0,     3,     4,     6,     8,    10,    12,    15,    21,
+      22,    25,    27,    31,    32,    34,    35,    39,    43,    47,
+      52,    59,    63,    72,    78,    84,    90,    96,   102,   110,
+     116,   120,   121,   122,   132,   134,   136,   138,   141,   143,
+     147,   151,   155,   159,   163,   167,   171,   175,   179,   183,
+     187,   190,   194,   195,   198,   203,   205,   209,   211,   212,
+     215,   217,   218,   223,   226,   231,   236,   237,   240,   242,
+     244,   246,   248,   250,   252,   253
+};
+
+/* YYRHS -- A `-1'-separated list of the rules' RHS. */
+static const yysigned_char yyrhs[] =
+{
+      50,     0,    -1,    -1,    52,    -1,    53,    -1,    52,    -1,
+      57,    -1,    57,    52,    -1,    32,    65,    54,    11,    51,
+      -1,    -1,    14,    65,    -1,    53,    -1,     7,    64,     8,
+      -1,    -1,    32,    -1,    -1,    43,    51,    46,    -1,    31,
+      65,    11,    -1,    47,    64,    11,    -1,    67,    60,    65,
+      11,    -1,    67,    34,    65,    60,    65,    11,    -1,    37,
+      65,    11,    -1,    27,    56,    47,    30,    65,    43,    51,
+      46,    -1,    39,    65,    43,    62,    46,    -1,    28,    61,
+      43,    51,    46,    -1,    33,    65,    43,    51,    46,    -1,
+      23,    64,    43,    51,    46,    -1,    42,    61,    43,    51,
+      46,    -1,    28,    61,    43,    51,    46,    25,    57,    -1,
+      56,    38,    47,    55,    57,    -1,    34,    67,    57,    -1,
+      -1,    -1,    20,    70,    47,    72,    43,    58,    48,    59,
+      46,    -1,    14,    -1,     9,    -1,    17,    -1,    24,    14,
+      -1,    67,    -1,    61,    14,    61,    -1,    61,     4,    61,
+      -1,    61,    12,    61,    -1,    61,    13,    61,    -1,    61,
+      15,    61,    -1,    61,    16,    61,    -1,    61,     5,    61,
+      -1,    61,     6,    61,    -1,    61,    44,    61,    -1,    61,
+      45,    61,    -1,    67,    30,    65,    -1,     3,    61,    -1,
+       7,    61,     8,    -1,    -1,    63,    62,    -1,    22,    47,
+      10,    51,    -1,    65,    -1,    65,    10,    64,    -1,    66,
+      -1,    -1,    66,    67,    -1,    47,    -1,    -1,    18,    68,
+      69,    19,    -1,    67,    64,    -1,    34,    67,    67,    64,
+      -1,    34,    67,    37,    65,    -1,    -1,    70,    71,    -1,
+      41,    -1,    40,    -1,    29,    -1,    36,    -1,    35,    -1,
+      26,    -1,    -1,    21,    65,    -1
+};
+
+/* YYRLINE[YYN] -- source line where rule number YYN was defined.  */
+static const unsigned short yyrline[] =
+{
+       0,   139,   139,   141,   152,   154,   158,   160,   162,   167,
+     170,   172,   176,   179,   182,   185,   188,   190,   192,   194,
+     196,   198,   200,   202,   204,   206,   208,   210,   212,   214,
+     216,   219,   221,   218,   230,   232,   234,   236,   243,   245,
+     247,   249,   251,   253,   255,   257,   259,   261,   263,   265,
+     267,   269,   281,   282,   286,   295,   297,   307,   312,   313,
+     317,   319,   319,   328,   330,   332,   343,   344,   348,   350,
+     352,   354,   356,   358,   368,   369
+};
+#endif
+
+#if YYDEBUG || YYERROR_VERBOSE
+/* YYTNME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
+   First, the terminals, then, starting at YYNTOKENS, nonterminals. */
+static const char *const yytname[] =
+{
+  "$end", "error", "$undefined", "_BANG_t", "_BANG_EQUALS_t", "_AMPER_t", 
+  "_AMPERAMPER_t", "_LPAREN_t", "_RPAREN_t", "_PLUS_EQUALS_t", "_COLON_t", 
+  "_SEMIC_t", "_LANGLE_t", "_LANGLE_EQUALS_t", "_EQUALS_t", "_RANGLE_t", 
+  "_RANGLE_EQUALS_t", "_QUESTION_EQUALS_t", "_LBRACKET_t", "_RBRACKET_t", 
+  "ACTIONS_t", "BIND_t", "CASE_t", "CLASS_t", "DEFAULT_t", "ELSE_t", 
+  "EXISTING_t", "FOR_t", "IF_t", "IGNORE_t", "IN_t", "INCLUDE_t", 
+  "LOCAL_t", "MODULE_t", "ON_t", "PIECEMEAL_t", "QUIETLY_t", "RETURN_t", 
+  "RULE_t", "SWITCH_t", "TOGETHER_t", "UPDATED_t", "WHILE_t", "_LBRACE_t", 
+  "_BAR_t", "_BARBAR_t", "_RBRACE_t", "ARG", "STRING", "$accept", "run", 
+  "block", "rules", "null", "assign_list_opt", "arglist_opt", "local_opt", 
+  "rule", "@1", "@2", "assign", "expr", "cases", "case", "lol", "list", 
+  "listp", "arg", "@3", "func", "eflags", "eflag", "bindlist", 0
+};
+#endif
+
+# ifdef YYPRINT
+/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to
+   token YYLEX-NUM.  */
+static const unsigned short yytoknum[] =
+{
+       0,   256,   257,   258,   259,   260,   261,   262,   263,   264,
+     265,   266,   267,   268,   269,   270,   271,   272,   273,   274,
+     275,   276,   277,   278,   279,   280,   281,   282,   283,   284,
+     285,   286,   287,   288,   289,   290,   291,   292,   293,   294,
+     295,   296,   297,   298,   299,   300,   301,   302,   303
+};
+# endif
+
+/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives.  */
+static const unsigned char yyr1[] =
+{
+       0,    49,    50,    50,    51,    51,    52,    52,    52,    53,
+      54,    54,    55,    55,    56,    56,    57,    57,    57,    57,
+      57,    57,    57,    57,    57,    57,    57,    57,    57,    57,
+      57,    58,    59,    57,    60,    60,    60,    60,    61,    61,
+      61,    61,    61,    61,    61,    61,    61,    61,    61,    61,
+      61,    61,    62,    62,    63,    64,    64,    65,    66,    66,
+      67,    68,    67,    69,    69,    69,    70,    70,    71,    71,
+      71,    71,    71,    71,    72,    72
+};
+
+/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN.  */
+static const unsigned char yyr2[] =
+{
+       0,     2,     0,     1,     1,     1,     1,     2,     5,     0,
+       2,     1,     3,     0,     1,     0,     3,     3,     3,     4,
+       6,     3,     8,     5,     5,     5,     5,     5,     7,     5,
+       3,     0,     0,     9,     1,     1,     1,     2,     1,     3,
+       3,     3,     3,     3,     3,     3,     3,     3,     3,     3,
+       2,     3,     0,     2,     4,     1,     3,     1,     0,     2,
+       1,     0,     4,     2,     4,     4,     0,     2,     1,     1,
+       1,     1,     1,     1,     0,     2
+};
+
+/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
+   STATE-NUM when YYTABLE doesn't specify something else to do.  Zero
+   means the default is an error.  */
+static const unsigned char yydefact[] =
+{
+       2,    61,    66,    58,    15,     0,    58,    58,    58,     0,
+      58,    58,     0,     9,    60,     0,     3,     0,     6,     0,
+       0,     0,     0,    55,    57,    14,     0,     0,     0,    60,
+       0,    38,     0,     9,     0,    15,     0,     0,     0,     0,
+       5,     4,     0,     1,     0,     7,    35,    34,    36,     0,
+      58,    58,     0,    58,     0,    73,    70,    72,    71,    69,
+      68,    74,    67,     9,    58,    59,     0,    50,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     9,     0,     0,
+      58,    17,    58,    11,     0,     9,    30,    21,    52,     9,
+      16,    18,    13,    37,     0,     0,     0,    63,    62,    58,
+       0,     0,    56,    58,    51,    40,    45,    46,    41,    42,
+      39,    43,    44,     0,    47,    48,    49,    10,     9,     0,
+       0,     0,    52,     0,    58,    15,    58,    19,    58,    58,
+      75,    31,    26,     0,    24,     8,    25,     0,    23,    53,
+      27,     0,    29,     0,    65,    64,     0,     9,    15,     9,
+      12,    20,    32,     0,    28,    54,     0,    22,    33
+};
+
+/* YYDEFGOTO[NTERM-NUM]. */
+static const short yydefgoto[] =
+{
+      -1,    15,    39,    40,    41,    84,   125,    17,    18,   146,
+     156,    51,    30,   121,   122,    22,    23,    24,    31,    20,
+      54,    21,    62,   100
+};
+
+/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
+   STATE-NUM.  */
+#define YYPACT_NINF -48
+static const short yypact[] =
+{
+     179,   -48,   -48,   -48,   -15,     7,   -48,   -16,   -48,     3,
+     -48,   -48,     7,   179,     1,    27,   -48,    -9,   179,    19,
+      -3,    33,   -11,    24,     3,   -48,   -10,     7,     7,   -48,
+     138,     9,    30,    35,    13,   205,    53,    22,   151,    20,
+     -48,   -48,    56,   -48,    23,   -48,   -48,   -48,   -48,    61,
+     -48,   -48,     3,   -48,    62,   -48,   -48,   -48,   -48,   -48,
+     -48,    58,   -48,   179,   -48,   -48,    52,   -48,   164,     7,
+       7,     7,     7,     7,     7,     7,     7,   179,     7,     7,
+     -48,   -48,   -48,   -48,    72,   179,   -48,   -48,    68,   179,
+     -48,   -48,    85,   -48,    77,    73,     8,   -48,   -48,   -48,
+      50,    57,   -48,   -48,   -48,    45,    93,    93,   -48,   -48,
+      45,   -48,   -48,    64,   245,   245,   -48,   -48,   179,    66,
+      67,    69,    68,    71,   -48,   205,   -48,   -48,   -48,   -48,
+     -48,   -48,   -48,    70,    79,   -48,   -48,   109,   -48,   -48,
+     -48,   112,   -48,   115,   -48,   -48,    75,   179,   205,   179,
+     -48,   -48,   -48,    81,   -48,   -48,    82,   -48,   -48
+};
+
+/* YYPGOTO[NTERM-NUM].  */
+static const short yypgoto[] =
+{
+     -48,   -48,   -47,     5,   104,   -48,   -48,   136,   -27,   -48,
+     -48,    47,    60,    36,   -48,   -13,    -4,   -48,     0,   -48,
+     -48,   -48,   -48,   -48
+};
+
+/* YYTABLE[YYPACT[STATE-NUM]].  What to do in state STATE-NUM.  If
+   positive, shift that token.  If negative, reduce the rule which
+   number is the opposite.  If zero, do what YYDEFACT says.
+   If YYTABLE_NINF, syntax error.  */
+#define YYTABLE_NINF -59
+static const short yytable[] =
+{
+      19,    42,    32,    33,    34,    16,    36,    37,    86,    35,
+      27,   -58,   -58,    19,    28,     1,   101,    25,    19,   -58,
+      53,     1,   -14,    45,    65,     1,     1,    43,    46,    44,
+     113,    52,    63,    47,    64,    19,    48,    66,   119,    80,
+      97,    81,   123,    49,    29,   128,    94,    95,   -58,    82,
+      29,   102,    96,    50,    29,    29,    85,    72,    73,    55,
+      75,    76,    56,    19,    87,    88,    90,    91,    57,    58,
+      92,   135,    38,    59,    60,    93,   116,    19,   117,    99,
+      61,    98,   103,   118,   127,    19,    46,    67,    68,    19,
+     120,    47,   124,   131,    48,   130,   129,    69,   142,   133,
+     153,    49,   155,   132,   148,    72,    73,    74,    75,    76,
+     134,   141,   136,   147,   137,   138,   145,   140,    19,   149,
+     150,   154,   143,   152,   144,    19,   151,   157,   158,   105,
+     106,   107,   108,   109,   110,   111,   112,    83,   114,   115,
+      26,   126,    69,    70,    71,     0,     0,    19,    19,    19,
+      72,    73,    74,    75,    76,    69,    70,    71,   139,     0,
+       0,     0,     0,    72,    73,    74,    75,    76,    69,    70,
+      71,     0,   104,     0,     0,     0,    72,    73,    74,    75,
+      76,    77,    78,    79,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,    89,    78,    79,     1,     0,     2,
+       0,     0,     3,     0,     0,     0,     4,     5,    78,    79,
+       6,     7,     8,     9,     0,     0,    10,   -15,    11,     0,
+       0,    12,    13,     1,     0,     2,    14,     0,     3,     0,
+       0,     0,     4,     5,     0,     0,     6,    25,     8,     9,
+       0,     0,    10,     0,    11,     0,     0,    12,    13,    69,
+      70,    71,    14,     0,     0,     0,     0,    72,    73,    74,
+      75,    76
+};
+
+static const short yycheck[] =
+{
+       0,    14,     6,     7,     8,     0,    10,    11,    35,     9,
+       3,    10,    11,    13,     7,    18,    63,    32,    18,    18,
+      20,    18,    38,    18,    24,    18,    18,     0,     9,    38,
+      77,    34,    43,    14,    10,    35,    17,    47,    85,    30,
+      53,    11,    89,    24,    47,    37,    50,    51,    47,    14,
+      47,    64,    52,    34,    47,    47,    43,    12,    13,    26,
+      15,    16,    29,    63,    11,    43,    46,    11,    35,    36,
+      47,   118,    12,    40,    41,    14,    80,    77,    82,    21,
+      47,    19,    30,    11,    11,    85,     9,    27,    28,    89,
+      22,    14,     7,    43,    17,    99,    96,     4,   125,   103,
+     147,    24,   149,    46,    25,    12,    13,    14,    15,    16,
+      46,   124,    46,    43,    47,    46,   129,    46,   118,    10,
+       8,   148,   126,    48,   128,   125,    11,    46,    46,    69,
+      70,    71,    72,    73,    74,    75,    76,    33,    78,    79,
+       4,    94,     4,     5,     6,    -1,    -1,   147,   148,   149,
+      12,    13,    14,    15,    16,     4,     5,     6,   122,    -1,
+      -1,    -1,    -1,    12,    13,    14,    15,    16,     4,     5,
+       6,    -1,     8,    -1,    -1,    -1,    12,    13,    14,    15,
+      16,    43,    44,    45,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    43,    44,    45,    18,    -1,    20,
+      -1,    -1,    23,    -1,    -1,    -1,    27,    28,    44,    45,
+      31,    32,    33,    34,    -1,    -1,    37,    38,    39,    -1,
+      -1,    42,    43,    18,    -1,    20,    47,    -1,    23,    -1,
+      -1,    -1,    27,    28,    -1,    -1,    31,    32,    33,    34,
+      -1,    -1,    37,    -1,    39,    -1,    -1,    42,    43,     4,
+       5,     6,    47,    -1,    -1,    -1,    -1,    12,    13,    14,
+      15,    16
+};
+
+/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
+   symbol of state STATE-NUM.  */
+static const unsigned char yystos[] =
+{
+       0,    18,    20,    23,    27,    28,    31,    32,    33,    34,
+      37,    39,    42,    43,    47,    50,    52,    56,    57,    67,
+      68,    70,    64,    65,    66,    32,    56,     3,     7,    47,
+      61,    67,    65,    65,    65,    67,    65,    65,    61,    51,
+      52,    53,    64,     0,    38,    52,     9,    14,    17,    24,
+      34,    60,    34,    67,    69,    26,    29,    35,    36,    40,
+      41,    47,    71,    43,    10,    67,    47,    61,    61,     4,
+       5,     6,    12,    13,    14,    15,    16,    43,    44,    45,
+      30,    11,    14,    53,    54,    43,    57,    11,    43,    43,
+      46,    11,    47,    14,    65,    65,    67,    64,    19,    21,
+      72,    51,    64,    30,     8,    61,    61,    61,    61,    61,
+      61,    61,    61,    51,    61,    61,    65,    65,    11,    51,
+      22,    62,    63,    51,     7,    55,    60,    11,    37,    67,
+      65,    43,    46,    65,    46,    51,    46,    47,    46,    62,
+      46,    64,    57,    65,    65,    64,    58,    43,    25,    10,
+       8,    11,    48,    51,    57,    51,    59,    46,    46
+};
+
+#if ! defined (YYSIZE_T) && defined (__SIZE_TYPE__)
+# define YYSIZE_T __SIZE_TYPE__
+#endif
+#if ! defined (YYSIZE_T) && defined (size_t)
+# define YYSIZE_T size_t
+#endif
+#if ! defined (YYSIZE_T)
+# if defined (__STDC__) || defined (__cplusplus)
+#  include <stddef.h> /* INFRINGES ON USER NAME SPACE */
+#  define YYSIZE_T size_t
+# endif
+#endif
+#if ! defined (YYSIZE_T)
+# define YYSIZE_T unsigned int
+#endif
+
+#define yyerrok		(yyerrstatus = 0)
+#define yyclearin	(yychar = YYEMPTY)
+#define YYEMPTY		(-2)
+#define YYEOF		0
+
+#define YYACCEPT	goto yyacceptlab
+#define YYABORT		goto yyabortlab
+#define YYERROR		goto yyerrlab1
+
+/* Like YYERROR except do call yyerror.  This remains here temporarily
+   to ease the transition to the new meaning of YYERROR, for GCC.
+   Once GCC version 2 has supplanted version 1, this can go.  */
+
+#define YYFAIL		goto yyerrlab
+
+#define YYRECOVERING()  (!!yyerrstatus)
+
+#define YYBACKUP(Token, Value)					\
+do								\
+  if (yychar == YYEMPTY && yylen == 1)				\
+    {								\
+      yychar = (Token);						\
+      yylval = (Value);						\
+      yytoken = YYTRANSLATE (yychar);				\
+      YYPOPSTACK;						\
+      goto yybackup;						\
+    }								\
+  else								\
+    { 								\
+      yyerror ("syntax error: cannot back up");\
+      YYERROR;							\
+    }								\
+while (0)
+
+#define YYTERROR	1
+#define YYERRCODE	256
+
+/* YYLLOC_DEFAULT -- Compute the default location (before the actions
+   are run).  */
+
+#ifndef YYLLOC_DEFAULT
+# define YYLLOC_DEFAULT(Current, Rhs, N)         \
+  Current.first_line   = Rhs[1].first_line;      \
+  Current.first_column = Rhs[1].first_column;    \
+  Current.last_line    = Rhs[N].last_line;       \
+  Current.last_column  = Rhs[N].last_column;
+#endif
+
+/* YYLEX -- calling `yylex' with the right arguments.  */
+
+#ifdef YYLEX_PARAM
+# define YYLEX yylex (YYLEX_PARAM)
+#else
+# define YYLEX yylex ()
+#endif
+
+/* Enable debugging if requested.  */
+#if YYDEBUG
+
+# ifndef YYFPRINTF
+#  include <stdio.h> /* INFRINGES ON USER NAME SPACE */
+#  define YYFPRINTF fprintf
+# endif
+
+# define YYDPRINTF(Args)			\
+do {						\
+  if (yydebug)					\
+    YYFPRINTF Args;				\
+} while (0)
+
+# define YYDSYMPRINT(Args)			\
+do {						\
+  if (yydebug)					\
+    yysymprint Args;				\
+} while (0)
+
+# define YYDSYMPRINTF(Title, Token, Value, Location)		\
+do {								\
+  if (yydebug)							\
+    {								\
+      YYFPRINTF (stderr, "%s ", Title);				\
+      yysymprint (stderr, 					\
+                  Token, Value);	\
+      YYFPRINTF (stderr, "\n");					\
+    }								\
+} while (0)
+
+/*------------------------------------------------------------------.
+| yy_stack_print -- Print the state stack from its BOTTOM up to its |
+| TOP (cinluded).                                                   |
+`------------------------------------------------------------------*/
+
+#if defined (__STDC__) || defined (__cplusplus)
+static void
+yy_stack_print (short *bottom, short *top)
+#else
+static void
+yy_stack_print (bottom, top)
+    short *bottom;
+    short *top;
+#endif
+{
+  YYFPRINTF (stderr, "Stack now");
+  for (/* Nothing. */; bottom <= top; ++bottom)
+    YYFPRINTF (stderr, " %d", *bottom);
+  YYFPRINTF (stderr, "\n");
+}
+
+# define YY_STACK_PRINT(Bottom, Top)				\
+do {								\
+  if (yydebug)							\
+    yy_stack_print ((Bottom), (Top));				\
+} while (0)
+
+
+/*------------------------------------------------.
+| Report that the YYRULE is going to be reduced.  |
+`------------------------------------------------*/
+
+#if defined (__STDC__) || defined (__cplusplus)
+static void
+yy_reduce_print (int yyrule)
+#else
+static void
+yy_reduce_print (yyrule)
+    int yyrule;
+#endif
+{
+  int yyi;
+  unsigned int yylineno = yyrline[yyrule];
+  YYFPRINTF (stderr, "Reducing stack by rule %d (line %u), ",
+             yyrule - 1, yylineno);
+  /* Print the symbols being reduced, and their result.  */
+  for (yyi = yyprhs[yyrule]; 0 <= yyrhs[yyi]; yyi++)
+    YYFPRINTF (stderr, "%s ", yytname [yyrhs[yyi]]);
+  YYFPRINTF (stderr, "-> %s\n", yytname [yyr1[yyrule]]);
+}
+
+# define YY_REDUCE_PRINT(Rule)		\
+do {					\
+  if (yydebug)				\
+    yy_reduce_print (Rule);		\
+} while (0)
+
+/* Nonzero means print parse trace.  It is left uninitialized so that
+   multiple parsers can coexist.  */
+int yydebug;
+#else /* !YYDEBUG */
+# define YYDPRINTF(Args)
+# define YYDSYMPRINT(Args)
+# define YYDSYMPRINTF(Title, Token, Value, Location)
+# define YY_STACK_PRINT(Bottom, Top)
+# define YY_REDUCE_PRINT(Rule)
+#endif /* !YYDEBUG */
+
+
+/* YYINITDEPTH -- initial size of the parser's stacks.  */
+#ifndef	YYINITDEPTH
+# define YYINITDEPTH 200
+#endif
+
+/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only
+   if the built-in stack extension method is used).
+
+   Do not make this value too large; the results are undefined if
+   SIZE_MAX < YYSTACK_BYTES (YYMAXDEPTH)
+   evaluated with infinite-precision integer arithmetic.  */
+
+#if YYMAXDEPTH == 0
+# undef YYMAXDEPTH
+#endif
+
+#ifndef YYMAXDEPTH
+# define YYMAXDEPTH 10000
+#endif
+
+
+
+#if YYERROR_VERBOSE
+
+# ifndef yystrlen
+#  if defined (__GLIBC__) && defined (_STRING_H)
+#   define yystrlen strlen
+#  else
+/* Return the length of YYSTR.  */
+static YYSIZE_T
+#   if defined (__STDC__) || defined (__cplusplus)
+yystrlen (const char *yystr)
+#   else
+yystrlen (yystr)
+     const char *yystr;
+#   endif
+{
+  register const char *yys = yystr;
+
+  while (*yys++ != '\0')
+    continue;
+
+  return yys - yystr - 1;
+}
+#  endif
+# endif
+
+# ifndef yystpcpy
+#  if defined (__GLIBC__) && defined (_STRING_H) && defined (_GNU_SOURCE)
+#   define yystpcpy stpcpy
+#  else
+/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in
+   YYDEST.  */
+static char *
+#   if defined (__STDC__) || defined (__cplusplus)
+yystpcpy (char *yydest, const char *yysrc)
+#   else
+yystpcpy (yydest, yysrc)
+     char *yydest;
+     const char *yysrc;
+#   endif
+{
+  register char *yyd = yydest;
+  register const char *yys = yysrc;
+
+  while ((*yyd++ = *yys++) != '\0')
+    continue;
+
+  return yyd - 1;
+}
+#  endif
+# endif
+
+#endif /* !YYERROR_VERBOSE */
+
+
+
+#if YYDEBUG
+/*--------------------------------.
+| Print this symbol on YYOUTPUT.  |
+`--------------------------------*/
+
+#if defined (__STDC__) || defined (__cplusplus)
+static void
+yysymprint (FILE *yyoutput, int yytype, YYSTYPE *yyvaluep)
+#else
+static void
+yysymprint (yyoutput, yytype, yyvaluep)
+    FILE *yyoutput;
+    int yytype;
+    YYSTYPE *yyvaluep;
+#endif
+{
+  /* Pacify ``unused variable'' warnings.  */
+  (void) yyvaluep;
+
+  if (yytype < YYNTOKENS)
+    {
+      YYFPRINTF (yyoutput, "token %s (", yytname[yytype]);
+# ifdef YYPRINT
+      YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
+# endif
+    }
+  else
+    YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]);
+
+  switch (yytype)
+    {
+      default:
+        break;
+    }
+  YYFPRINTF (yyoutput, ")");
+}
+
+#endif /* ! YYDEBUG */
+/*-----------------------------------------------.
+| Release the memory associated to this symbol.  |
+`-----------------------------------------------*/
+
+#if defined (__STDC__) || defined (__cplusplus)
+static void
+yydestruct (int yytype, YYSTYPE *yyvaluep)
+#else
+static void
+yydestruct (yytype, yyvaluep)
+    int yytype;
+    YYSTYPE *yyvaluep;
+#endif
+{
+  /* Pacify ``unused variable'' warnings.  */
+  (void) yyvaluep;
+
+  switch (yytype)
+    {
+
+      default:
+        break;
+    }
+}
+
+
+/* Prevent warnings from -Wmissing-prototypes.  */
+
+#ifdef YYPARSE_PARAM
+# if defined (__STDC__) || defined (__cplusplus)
+int yyparse (void *YYPARSE_PARAM);
+# else
+int yyparse ();
+# endif
+#else /* ! YYPARSE_PARAM */
+#if defined (__STDC__) || defined (__cplusplus)
+int yyparse (void);
+#else
+int yyparse ();
+#endif
+#endif /* ! YYPARSE_PARAM */
+
+
+
+/* The lookahead symbol.  */
+int yychar;
+
+/* The semantic value of the lookahead symbol.  */
+YYSTYPE yylval;
+
+/* Number of syntax errors so far.  */
+int yynerrs;
+
+
+
+/*----------.
+| yyparse.  |
+`----------*/
+
+#ifdef YYPARSE_PARAM
+# if defined (__STDC__) || defined (__cplusplus)
+int yyparse (void *YYPARSE_PARAM)
+# else
+int yyparse (YYPARSE_PARAM)
+  void *YYPARSE_PARAM;
+# endif
+#else /* ! YYPARSE_PARAM */
+#if defined (__STDC__) || defined (__cplusplus)
+int
+yyparse (void)
+#else
+int
+yyparse ()
+
+#endif
+#endif
+{
+  
+  register int yystate;
+  register int yyn;
+  int yyresult;
+  /* Number of tokens to shift before error messages enabled.  */
+  int yyerrstatus;
+  /* Lookahead token as an internal (translated) token number.  */
+  int yytoken = 0;
+
+  /* Three stacks and their tools:
+     `yyss': related to states,
+     `yyvs': related to semantic values,
+     `yyls': related to locations.
+
+     Refer to the stacks thru separate pointers, to allow yyoverflow
+     to reallocate them elsewhere.  */
+
+  /* The state stack.  */
+  short	yyssa[YYINITDEPTH];
+  short *yyss = yyssa;
+  register short *yyssp;
+
+  /* The semantic value stack.  */
+  YYSTYPE yyvsa[YYINITDEPTH];
+  YYSTYPE *yyvs = yyvsa;
+  register YYSTYPE *yyvsp;
+
+
+
+#define YYPOPSTACK   (yyvsp--, yyssp--)
+
+  YYSIZE_T yystacksize = YYINITDEPTH;
+
+  /* The variables used to return semantic value and location from the
+     action routines.  */
+  YYSTYPE yyval;
+
+
+  /* When reducing, the number of symbols on the RHS of the reduced
+     rule.  */
+  int yylen;
+
+  YYDPRINTF ((stderr, "Starting parse\n"));
+
+  yystate = 0;
+  yyerrstatus = 0;
+  yynerrs = 0;
+  yychar = YYEMPTY;		/* Cause a token to be read.  */
+
+  /* Initialize stack pointers.
+     Waste one element of value and location stack
+     so that they stay on the same level as the state stack.
+     The wasted elements are never initialized.  */
+
+  yyssp = yyss;
+  yyvsp = yyvs;
+
+  goto yysetstate;
+
+/*------------------------------------------------------------.
+| yynewstate -- Push a new state, which is found in yystate.  |
+`------------------------------------------------------------*/
+ yynewstate:
+  /* In all cases, when you get here, the value and location stacks
+     have just been pushed. so pushing a state here evens the stacks.
+     */
+  yyssp++;
+
+ yysetstate:
+  *yyssp = yystate;
+
+  if (yyss + yystacksize - 1 <= yyssp)
+    {
+      /* Get the current used size of the three stacks, in elements.  */
+      YYSIZE_T yysize = yyssp - yyss + 1;
+
+#ifdef yyoverflow
+      {
+	/* Give user a chance to reallocate the stack. Use copies of
+	   these so that the &'s don't force the real ones into
+	   memory.  */
+	YYSTYPE *yyvs1 = yyvs;
+	short *yyss1 = yyss;
+
+
+	/* Each stack pointer address is followed by the size of the
+	   data in use in that stack, in bytes.  This used to be a
+	   conditional around just the two extra args, but that might
+	   be undefined if yyoverflow is a macro.  */
+	yyoverflow ("parser stack overflow",
+		    &yyss1, yysize * sizeof (*yyssp),
+		    &yyvs1, yysize * sizeof (*yyvsp),
+
+		    &yystacksize);
+
+	yyss = yyss1;
+	yyvs = yyvs1;
+      }
+#else /* no yyoverflow */
+# ifndef YYSTACK_RELOCATE
+      goto yyoverflowlab;
+# else
+      /* Extend the stack our own way.  */
+      if (YYMAXDEPTH <= yystacksize)
+	goto yyoverflowlab;
+      yystacksize *= 2;
+      if (YYMAXDEPTH < yystacksize)
+	yystacksize = YYMAXDEPTH;
+
+      {
+	short *yyss1 = yyss;
+	union yyalloc *yyptr =
+	  (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
+	if (! yyptr)
+	  goto yyoverflowlab;
+	YYSTACK_RELOCATE (yyss);
+	YYSTACK_RELOCATE (yyvs);
+
+#  undef YYSTACK_RELOCATE
+	if (yyss1 != yyssa)
+	  YYSTACK_FREE (yyss1);
+      }
+# endif
+#endif /* no yyoverflow */
+
+      yyssp = yyss + yysize - 1;
+      yyvsp = yyvs + yysize - 1;
+
+
+      YYDPRINTF ((stderr, "Stack size increased to %lu\n",
+		  (unsigned long int) yystacksize));
+
+      if (yyss + yystacksize - 1 <= yyssp)
+	YYABORT;
+    }
+
+  YYDPRINTF ((stderr, "Entering state %d\n", yystate));
+
+  goto yybackup;
+
+/*-----------.
+| yybackup.  |
+`-----------*/
+yybackup:
+
+/* Do appropriate processing given the current state.  */
+/* Read a lookahead token if we need one and don't already have one.  */
+/* yyresume: */
+
+  /* First try to decide what to do without reference to lookahead token.  */
+
+  yyn = yypact[yystate];
+  if (yyn == YYPACT_NINF)
+    goto yydefault;
+
+  /* Not known => get a lookahead token if don't already have one.  */
+
+  /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol.  */
+  if (yychar == YYEMPTY)
+    {
+      YYDPRINTF ((stderr, "Reading a token: "));
+      yychar = YYLEX;
+    }
+
+  if (yychar <= YYEOF)
+    {
+      yychar = yytoken = YYEOF;
+      YYDPRINTF ((stderr, "Now at end of input.\n"));
+    }
+  else
+    {
+      yytoken = YYTRANSLATE (yychar);
+      YYDSYMPRINTF ("Next token is", yytoken, &yylval, &yylloc);
+    }
+
+  /* If the proper action on seeing token YYTOKEN is to reduce or to
+     detect an error, take that action.  */
+  yyn += yytoken;
+  if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken)
+    goto yydefault;
+  yyn = yytable[yyn];
+  if (yyn <= 0)
+    {
+      if (yyn == 0 || yyn == YYTABLE_NINF)
+	goto yyerrlab;
+      yyn = -yyn;
+      goto yyreduce;
+    }
+
+  if (yyn == YYFINAL)
+    YYACCEPT;
+
+  /* Shift the lookahead token.  */
+  YYDPRINTF ((stderr, "Shifting token %s, ", yytname[yytoken]));
+
+  /* Discard the token being shifted unless it is eof.  */
+  if (yychar != YYEOF)
+    yychar = YYEMPTY;
+
+  *++yyvsp = yylval;
+
+
+  /* Count tokens shifted since error; after three, turn off error
+     status.  */
+  if (yyerrstatus)
+    yyerrstatus--;
+
+  yystate = yyn;
+  goto yynewstate;
+
+
+/*-----------------------------------------------------------.
+| yydefault -- do the default action for the current state.  |
+`-----------------------------------------------------------*/
+yydefault:
+  yyn = yydefact[yystate];
+  if (yyn == 0)
+    goto yyerrlab;
+  goto yyreduce;
+
+
+/*-----------------------------.
+| yyreduce -- Do a reduction.  |
+`-----------------------------*/
+yyreduce:
+  /* yyn is the number of a rule to reduce with.  */
+  yylen = yyr2[yyn];
+
+  /* If YYLEN is nonzero, implement the default value of the action:
+     `$$ = $1'.
+
+     Otherwise, the following line sets YYVAL to garbage.
+     This behavior is undocumented and Bison
+     users should not rely upon it.  Assigning to YYVAL
+     unconditionally makes the parser a bit smaller, and it avoids a
+     GCC warning that YYVAL may be used uninitialized.  */
+  yyval = yyvsp[1-yylen];
+
+
+  YY_REDUCE_PRINT (yyn);
+  switch (yyn)
+    {
+        case 3:
+#line 142 "jamgram.y"
+    { parse_save( yyvsp[0].parse ); }
+    break;
+
+  case 4:
+#line 153 "jamgram.y"
+    { yyval.parse = yyvsp[0].parse; }
+    break;
+
+  case 5:
+#line 155 "jamgram.y"
+    { yyval.parse = yyvsp[0].parse; }
+    break;
+
+  case 6:
+#line 159 "jamgram.y"
+    { yyval.parse = yyvsp[0].parse; }
+    break;
+
+  case 7:
+#line 161 "jamgram.y"
+    { yyval.parse = prules( yyvsp[-1].parse, yyvsp[0].parse ); }
+    break;
+
+  case 8:
+#line 163 "jamgram.y"
+    { yyval.parse = plocal( yyvsp[-3].parse, yyvsp[-2].parse, yyvsp[0].parse ); }
+    break;
+
+  case 9:
+#line 167 "jamgram.y"
+    { yyval.parse = pnull(); }
+    break;
+
+  case 10:
+#line 171 "jamgram.y"
+    { yyval.parse = yyvsp[0].parse; yyval.number = ASSIGN_SET; }
+    break;
+
+  case 11:
+#line 173 "jamgram.y"
+    { yyval.parse = yyvsp[0].parse; yyval.number = ASSIGN_APPEND; }
+    break;
+
+  case 12:
+#line 177 "jamgram.y"
+    { yyval.parse = yyvsp[-1].parse; }
+    break;
+
+  case 13:
+#line 179 "jamgram.y"
+    { yyval.parse = P0; }
+    break;
+
+  case 14:
+#line 183 "jamgram.y"
+    { yyval.number = 1; }
+    break;
+
+  case 15:
+#line 185 "jamgram.y"
+    { yyval.number = 0; }
+    break;
+
+  case 16:
+#line 189 "jamgram.y"
+    { yyval.parse = yyvsp[-1].parse; }
+    break;
+
+  case 17:
+#line 191 "jamgram.y"
+    { yyval.parse = pincl( yyvsp[-1].parse ); }
+    break;
+
+  case 18:
+#line 193 "jamgram.y"
+    { yyval.parse = prule( yyvsp[-2].string, yyvsp[-1].parse ); }
+    break;
+
+  case 19:
+#line 195 "jamgram.y"
+    { yyval.parse = pset( yyvsp[-3].parse, yyvsp[-1].parse, yyvsp[-2].number ); }
+    break;
+
+  case 20:
+#line 197 "jamgram.y"
+    { yyval.parse = pset1( yyvsp[-5].parse, yyvsp[-3].parse, yyvsp[-1].parse, yyvsp[-2].number ); }
+    break;
+
+  case 21:
+#line 199 "jamgram.y"
+    { yyval.parse = yyvsp[-1].parse; }
+    break;
+
+  case 22:
+#line 201 "jamgram.y"
+    { yyval.parse = pfor( yyvsp[-5].string, yyvsp[-3].parse, yyvsp[-1].parse, yyvsp[-6].number ); }
+    break;
+
+  case 23:
+#line 203 "jamgram.y"
+    { yyval.parse = pswitch( yyvsp[-3].parse, yyvsp[-1].parse ); }
+    break;
+
+  case 24:
+#line 205 "jamgram.y"
+    { yyval.parse = pif( yyvsp[-3].parse, yyvsp[-1].parse, pnull() ); }
+    break;
+
+  case 25:
+#line 207 "jamgram.y"
+    { yyval.parse = pmodule( yyvsp[-3].parse, yyvsp[-1].parse ); }
+    break;
+
+  case 26:
+#line 209 "jamgram.y"
+    { yyval.parse = pclass( yyvsp[-3].parse, yyvsp[-1].parse ); }
+    break;
+
+  case 27:
+#line 211 "jamgram.y"
+    { yyval.parse = pwhile( yyvsp[-3].parse, yyvsp[-1].parse ); }
+    break;
+
+  case 28:
+#line 213 "jamgram.y"
+    { yyval.parse = pif( yyvsp[-5].parse, yyvsp[-3].parse, yyvsp[0].parse ); }
+    break;
+
+  case 29:
+#line 215 "jamgram.y"
+    { yyval.parse = psetc( yyvsp[-2].string, yyvsp[0].parse, yyvsp[-1].parse, yyvsp[-4].number ); }
+    break;
+
+  case 30:
+#line 217 "jamgram.y"
+    { yyval.parse = pon( yyvsp[-1].parse, yyvsp[0].parse ); }
+    break;
+
+  case 31:
+#line 219 "jamgram.y"
+    { yymode( SCAN_STRING ); }
+    break;
+
+  case 32:
+#line 221 "jamgram.y"
+    { yymode( SCAN_NORMAL ); }
+    break;
+
+  case 33:
+#line 223 "jamgram.y"
+    { yyval.parse = psete( yyvsp[-6].string,yyvsp[-5].parse,yyvsp[-2].string,yyvsp[-7].number ); }
+    break;
+
+  case 34:
+#line 231 "jamgram.y"
+    { yyval.number = ASSIGN_SET; }
+    break;
+
+  case 35:
+#line 233 "jamgram.y"
+    { yyval.number = ASSIGN_APPEND; }
+    break;
+
+  case 36:
+#line 235 "jamgram.y"
+    { yyval.number = ASSIGN_DEFAULT; }
+    break;
+
+  case 37:
+#line 237 "jamgram.y"
+    { yyval.number = ASSIGN_DEFAULT; }
+    break;
+
+  case 38:
+#line 244 "jamgram.y"
+    { yyval.parse = peval( EXPR_EXISTS, yyvsp[0].parse, pnull() ); }
+    break;
+
+  case 39:
+#line 246 "jamgram.y"
+    { yyval.parse = peval( EXPR_EQUALS, yyvsp[-2].parse, yyvsp[0].parse ); }
+    break;
+
+  case 40:
+#line 248 "jamgram.y"
+    { yyval.parse = peval( EXPR_NOTEQ, yyvsp[-2].parse, yyvsp[0].parse ); }
+    break;
+
+  case 41:
+#line 250 "jamgram.y"
+    { yyval.parse = peval( EXPR_LESS, yyvsp[-2].parse, yyvsp[0].parse ); }
+    break;
+
+  case 42:
+#line 252 "jamgram.y"
+    { yyval.parse = peval( EXPR_LESSEQ, yyvsp[-2].parse, yyvsp[0].parse ); }
+    break;
+
+  case 43:
+#line 254 "jamgram.y"
+    { yyval.parse = peval( EXPR_MORE, yyvsp[-2].parse, yyvsp[0].parse ); }
+    break;
+
+  case 44:
+#line 256 "jamgram.y"
+    { yyval.parse = peval( EXPR_MOREEQ, yyvsp[-2].parse, yyvsp[0].parse ); }
+    break;
+
+  case 45:
+#line 258 "jamgram.y"
+    { yyval.parse = peval( EXPR_AND, yyvsp[-2].parse, yyvsp[0].parse ); }
+    break;
+
+  case 46:
+#line 260 "jamgram.y"
+    { yyval.parse = peval( EXPR_AND, yyvsp[-2].parse, yyvsp[0].parse ); }
+    break;
+
+  case 47:
+#line 262 "jamgram.y"
+    { yyval.parse = peval( EXPR_OR, yyvsp[-2].parse, yyvsp[0].parse ); }
+    break;
+
+  case 48:
+#line 264 "jamgram.y"
+    { yyval.parse = peval( EXPR_OR, yyvsp[-2].parse, yyvsp[0].parse ); }
+    break;
+
+  case 49:
+#line 266 "jamgram.y"
+    { yyval.parse = peval( EXPR_IN, yyvsp[-2].parse, yyvsp[0].parse ); }
+    break;
+
+  case 50:
+#line 268 "jamgram.y"
+    { yyval.parse = peval( EXPR_NOT, yyvsp[0].parse, pnull() ); }
+    break;
+
+  case 51:
+#line 270 "jamgram.y"
+    { yyval.parse = yyvsp[-1].parse; }
+    break;
+
+  case 52:
+#line 281 "jamgram.y"
+    { yyval.parse = P0; }
+    break;
+
+  case 53:
+#line 283 "jamgram.y"
+    { yyval.parse = pnode( yyvsp[-1].parse, yyvsp[0].parse ); }
+    break;
+
+  case 54:
+#line 287 "jamgram.y"
+    { yyval.parse = psnode( yyvsp[-2].string, yyvsp[0].parse ); }
+    break;
+
+  case 55:
+#line 296 "jamgram.y"
+    { yyval.parse = pnode( P0, yyvsp[0].parse ); }
+    break;
+
+  case 56:
+#line 298 "jamgram.y"
+    { yyval.parse = pnode( yyvsp[0].parse, yyvsp[-2].parse ); }
+    break;
+
+  case 57:
+#line 308 "jamgram.y"
+    { yyval.parse = yyvsp[0].parse; yymode( SCAN_NORMAL ); }
+    break;
+
+  case 58:
+#line 312 "jamgram.y"
+    { yyval.parse = pnull(); yymode( SCAN_PUNCT ); }
+    break;
+
+  case 59:
+#line 314 "jamgram.y"
+    { yyval.parse = pappend( yyvsp[-1].parse, yyvsp[0].parse ); }
+    break;
+
+  case 60:
+#line 318 "jamgram.y"
+    { yyval.parse = plist( yyvsp[0].string ); }
+    break;
+
+  case 61:
+#line 319 "jamgram.y"
+    { yymode( SCAN_NORMAL ); }
+    break;
+
+  case 62:
+#line 320 "jamgram.y"
+    { yyval.parse = yyvsp[-1].parse; }
+    break;
+
+  case 63:
+#line 329 "jamgram.y"
+    { yyval.parse = prule( yyvsp[-1].string, yyvsp[0].parse ); }
+    break;
+
+  case 64:
+#line 331 "jamgram.y"
+    { yyval.parse = pon( yyvsp[-2].parse, prule( yyvsp[-1].string, yyvsp[0].parse ) ); }
+    break;
+
+  case 65:
+#line 333 "jamgram.y"
+    { yyval.parse = pon( yyvsp[-2].parse, yyvsp[0].parse ); }
+    break;
+
+  case 66:
+#line 343 "jamgram.y"
+    { yyval.number = 0; }
+    break;
+
+  case 67:
+#line 345 "jamgram.y"
+    { yyval.number = yyvsp[-1].number | yyvsp[0].number; }
+    break;
+
+  case 68:
+#line 349 "jamgram.y"
+    { yyval.number = EXEC_UPDATED; }
+    break;
+
+  case 69:
+#line 351 "jamgram.y"
+    { yyval.number = EXEC_TOGETHER; }
+    break;
+
+  case 70:
+#line 353 "jamgram.y"
+    { yyval.number = EXEC_IGNORE; }
+    break;
+
+  case 71:
+#line 355 "jamgram.y"
+    { yyval.number = EXEC_QUIETLY; }
+    break;
+
+  case 72:
+#line 357 "jamgram.y"
+    { yyval.number = EXEC_PIECEMEAL; }
+    break;
+
+  case 73:
+#line 359 "jamgram.y"
+    { yyval.number = EXEC_EXISTING; }
+    break;
+
+  case 74:
+#line 368 "jamgram.y"
+    { yyval.parse = pnull(); }
+    break;
+
+  case 75:
+#line 370 "jamgram.y"
+    { yyval.parse = yyvsp[0].parse; }
+    break;
+
+
+    }
+
+/* Line 991 of yacc.c.  */
+#line 1621 "y.tab.c"
+
+  yyvsp -= yylen;
+  yyssp -= yylen;
+
+
+  YY_STACK_PRINT (yyss, yyssp);
+
+  *++yyvsp = yyval;
+
+
+  /* Now `shift' the result of the reduction.  Determine what state
+     that goes to, based on the state we popped back to and the rule
+     number reduced by.  */
+
+  yyn = yyr1[yyn];
+
+  yystate = yypgoto[yyn - YYNTOKENS] + *yyssp;
+  if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp)
+    yystate = yytable[yystate];
+  else
+    yystate = yydefgoto[yyn - YYNTOKENS];
+
+  goto yynewstate;
+
+
+/*------------------------------------.
+| yyerrlab -- here on detecting error |
+`------------------------------------*/
+yyerrlab:
+  /* If not already recovering from an error, report this error.  */
+  if (!yyerrstatus)
+    {
+      ++yynerrs;
+#if YYERROR_VERBOSE
+      yyn = yypact[yystate];
+
+      if (YYPACT_NINF < yyn && yyn < YYLAST)
+	{
+	  YYSIZE_T yysize = 0;
+	  int yytype = YYTRANSLATE (yychar);
+	  char *yymsg;
+	  int yyx, yycount;
+
+	  yycount = 0;
+	  /* Start YYX at -YYN if negative to avoid negative indexes in
+	     YYCHECK.  */
+	  for (yyx = yyn < 0 ? -yyn : 0;
+	       yyx < (int) (sizeof (yytname) / sizeof (char *)); yyx++)
+	    if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
+	      yysize += yystrlen (yytname[yyx]) + 15, yycount++;
+	  yysize += yystrlen ("syntax error, unexpected ") + 1;
+	  yysize += yystrlen (yytname[yytype]);
+	  yymsg = (char *) YYSTACK_ALLOC (yysize);
+	  if (yymsg != 0)
+	    {
+	      char *yyp = yystpcpy (yymsg, "syntax error, unexpected ");
+	      yyp = yystpcpy (yyp, yytname[yytype]);
+
+	      if (yycount < 5)
+		{
+		  yycount = 0;
+		  for (yyx = yyn < 0 ? -yyn : 0;
+		       yyx < (int) (sizeof (yytname) / sizeof (char *));
+		       yyx++)
+		    if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
+		      {
+			const char *yyq = ! yycount ? ", expecting " : " or ";
+			yyp = yystpcpy (yyp, yyq);
+			yyp = yystpcpy (yyp, yytname[yyx]);
+			yycount++;
+		      }
+		}
+	      yyerror (yymsg);
+	      YYSTACK_FREE (yymsg);
+	    }
+	  else
+	    yyerror ("syntax error; also virtual memory exhausted");
+	}
+      else
+#endif /* YYERROR_VERBOSE */
+	yyerror ("syntax error");
+    }
+
+
+
+  if (yyerrstatus == 3)
+    {
+      /* If just tried and failed to reuse lookahead token after an
+	 error, discard it.  */
+
+      /* Return failure if at end of input.  */
+      if (yychar == YYEOF)
+        {
+	  /* Pop the error token.  */
+          YYPOPSTACK;
+	  /* Pop the rest of the stack.  */
+	  while (yyss < yyssp)
+	    {
+	      YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp);
+	      yydestruct (yystos[*yyssp], yyvsp);
+	      YYPOPSTACK;
+	    }
+	  YYABORT;
+        }
+
+      YYDSYMPRINTF ("Error: discarding", yytoken, &yylval, &yylloc);
+      yydestruct (yytoken, &yylval);
+      yychar = YYEMPTY;
+
+    }
+
+  /* Else will try to reuse lookahead token after shifting the error
+     token.  */
+  goto yyerrlab2;
+
+
+/*----------------------------------------------------.
+| yyerrlab1 -- error raised explicitly by an action.  |
+`----------------------------------------------------*/
+yyerrlab1:
+
+  /* Suppress GCC warning that yyerrlab1 is unused when no action
+     invokes YYERROR.  */
+#if defined (__GNUC_MINOR__) && 2093 <= (__GNUC__ * 1000 + __GNUC_MINOR__)
+  __attribute__ ((__unused__))
+#endif
+
+
+  goto yyerrlab2;
+
+
+/*---------------------------------------------------------------.
+| yyerrlab2 -- pop states until the error token can be shifted.  |
+`---------------------------------------------------------------*/
+yyerrlab2:
+  yyerrstatus = 3;	/* Each real token shifted decrements this.  */
+
+  for (;;)
+    {
+      yyn = yypact[yystate];
+      if (yyn != YYPACT_NINF)
+	{
+	  yyn += YYTERROR;
+	  if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR)
+	    {
+	      yyn = yytable[yyn];
+	      if (0 < yyn)
+		break;
+	    }
+	}
+
+      /* Pop the current state because it cannot handle the error token.  */
+      if (yyssp == yyss)
+	YYABORT;
+
+      YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp);
+      yydestruct (yystos[yystate], yyvsp);
+      yyvsp--;
+      yystate = *--yyssp;
+
+      YY_STACK_PRINT (yyss, yyssp);
+    }
+
+  if (yyn == YYFINAL)
+    YYACCEPT;
+
+  YYDPRINTF ((stderr, "Shifting error token, "));
+
+  *++yyvsp = yylval;
+
+
+  yystate = yyn;
+  goto yynewstate;
+
+
+/*-------------------------------------.
+| yyacceptlab -- YYACCEPT comes here.  |
+`-------------------------------------*/
+yyacceptlab:
+  yyresult = 0;
+  goto yyreturn;
+
+/*-----------------------------------.
+| yyabortlab -- YYABORT comes here.  |
+`-----------------------------------*/
+yyabortlab:
+  yyresult = 1;
+  goto yyreturn;
+
+#ifndef yyoverflow
+/*----------------------------------------------.
+| yyoverflowlab -- parser overflow comes here.  |
+`----------------------------------------------*/
+yyoverflowlab:
+  yyerror ("parser stack overflow");
+  yyresult = 2;
+  /* Fall through.  */
+#endif
+
+yyreturn:
+#ifndef yyoverflow
+  if (yyss != yyssa)
+    YYSTACK_FREE (yyss);
+#endif
+  return yyresult;
+}
+
+
+

Added: boost-jam/boost-build/branches/upstream/current/jam_src/jamgram.h
===================================================================
--- boost-jam/boost-build/branches/upstream/current/jam_src/jamgram.h	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/jam_src/jamgram.h	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,140 @@
+/* A Bison parser, made by GNU Bison 1.875.  */
+
+/* Skeleton parser for Yacc-like parsing with Bison,
+   Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+/* As a special exception, when this file is copied by Bison into a
+   Bison output file, you may use that output file without restriction.
+   This special exception was added by the Free Software Foundation
+   in version 1.24 of Bison.  */
+
+/* Tokens.  */
+#ifndef YYTOKENTYPE
+# define YYTOKENTYPE
+   /* Put the tokens into the symbol table, so that GDB and other debuggers
+      know about them.  */
+   enum yytokentype {
+     _BANG_t = 258,
+     _BANG_EQUALS_t = 259,
+     _AMPER_t = 260,
+     _AMPERAMPER_t = 261,
+     _LPAREN_t = 262,
+     _RPAREN_t = 263,
+     _PLUS_EQUALS_t = 264,
+     _COLON_t = 265,
+     _SEMIC_t = 266,
+     _LANGLE_t = 267,
+     _LANGLE_EQUALS_t = 268,
+     _EQUALS_t = 269,
+     _RANGLE_t = 270,
+     _RANGLE_EQUALS_t = 271,
+     _QUESTION_EQUALS_t = 272,
+     _LBRACKET_t = 273,
+     _RBRACKET_t = 274,
+     ACTIONS_t = 275,
+     BIND_t = 276,
+     CASE_t = 277,
+     CLASS_t = 278,
+     DEFAULT_t = 279,
+     ELSE_t = 280,
+     EXISTING_t = 281,
+     FOR_t = 282,
+     IF_t = 283,
+     IGNORE_t = 284,
+     IN_t = 285,
+     INCLUDE_t = 286,
+     LOCAL_t = 287,
+     MODULE_t = 288,
+     ON_t = 289,
+     PIECEMEAL_t = 290,
+     QUIETLY_t = 291,
+     RETURN_t = 292,
+     RULE_t = 293,
+     SWITCH_t = 294,
+     TOGETHER_t = 295,
+     UPDATED_t = 296,
+     WHILE_t = 297,
+     _LBRACE_t = 298,
+     _BAR_t = 299,
+     _BARBAR_t = 300,
+     _RBRACE_t = 301,
+     ARG = 302,
+     STRING = 303
+   };
+#endif
+#define _BANG_t 258
+#define _BANG_EQUALS_t 259
+#define _AMPER_t 260
+#define _AMPERAMPER_t 261
+#define _LPAREN_t 262
+#define _RPAREN_t 263
+#define _PLUS_EQUALS_t 264
+#define _COLON_t 265
+#define _SEMIC_t 266
+#define _LANGLE_t 267
+#define _LANGLE_EQUALS_t 268
+#define _EQUALS_t 269
+#define _RANGLE_t 270
+#define _RANGLE_EQUALS_t 271
+#define _QUESTION_EQUALS_t 272
+#define _LBRACKET_t 273
+#define _RBRACKET_t 274
+#define ACTIONS_t 275
+#define BIND_t 276
+#define CASE_t 277
+#define CLASS_t 278
+#define DEFAULT_t 279
+#define ELSE_t 280
+#define EXISTING_t 281
+#define FOR_t 282
+#define IF_t 283
+#define IGNORE_t 284
+#define IN_t 285
+#define INCLUDE_t 286
+#define LOCAL_t 287
+#define MODULE_t 288
+#define ON_t 289
+#define PIECEMEAL_t 290
+#define QUIETLY_t 291
+#define RETURN_t 292
+#define RULE_t 293
+#define SWITCH_t 294
+#define TOGETHER_t 295
+#define UPDATED_t 296
+#define WHILE_t 297
+#define _LBRACE_t 298
+#define _BAR_t 299
+#define _BARBAR_t 300
+#define _RBRACE_t 301
+#define ARG 302
+#define STRING 303
+
+
+
+
+#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED)
+typedef int YYSTYPE;
+# define yystype YYSTYPE /* obsolescent; will be withdrawn */
+# define YYSTYPE_IS_DECLARED 1
+# define YYSTYPE_IS_TRIVIAL 1
+#endif
+
+extern YYSTYPE yylval;
+
+
+

Added: boost-jam/boost-build/branches/upstream/current/jam_src/jamgram.y
===================================================================
--- boost-jam/boost-build/branches/upstream/current/jam_src/jamgram.y	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/jam_src/jamgram.y	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,373 @@
+%token _BANG_t
+%token _BANG_EQUALS_t
+%token _AMPER_t
+%token _AMPERAMPER_t
+%token _LPAREN_t
+%token _RPAREN_t
+%token _PLUS_EQUALS_t
+%token _COLON_t
+%token _SEMIC_t
+%token _LANGLE_t
+%token _LANGLE_EQUALS_t
+%token _EQUALS_t
+%token _RANGLE_t
+%token _RANGLE_EQUALS_t
+%token _QUESTION_EQUALS_t
+%token _LBRACKET_t
+%token _RBRACKET_t
+%token ACTIONS_t
+%token BIND_t
+%token CASE_t
+%token CLASS_t
+%token DEFAULT_t
+%token ELSE_t
+%token EXISTING_t
+%token FOR_t
+%token IF_t
+%token IGNORE_t
+%token IN_t
+%token INCLUDE_t
+%token LOCAL_t
+%token MODULE_t
+%token ON_t
+%token PIECEMEAL_t
+%token QUIETLY_t
+%token RETURN_t
+%token RULE_t
+%token SWITCH_t
+%token TOGETHER_t
+%token UPDATED_t
+%token WHILE_t
+%token _LBRACE_t
+%token _BAR_t
+%token _BARBAR_t
+%token _RBRACE_t
+/*
+ * Copyright 1993, 2000 Christopher Seiwald.
+ *
+ * This file is part of Jam - see jam.c for Copyright information.
+ */
+
+/*  This file is ALSO:
+ *  Copyright 2001-2004 David Abrahams.
+ *  Distributed under the Boost Software License, Version 1.0.
+ *  (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+ */
+
+/*
+ * jamgram.yy - jam grammar
+ *
+ * 04/13/94 (seiwald) - added shorthand L0 for null list pointer
+ * 06/01/94 (seiwald) - new 'actions existing' does existing sources
+ * 08/23/94 (seiwald) - Support for '+=' (append to variable)
+ * 08/31/94 (seiwald) - Allow ?= as alias for "default =".
+ * 09/15/94 (seiwald) - if conditionals take only single arguments, so
+ *			that 'if foo == bar' gives syntax error (use =).
+ * 02/11/95 (seiwald) - when scanning arguments to rules, only treat
+ *			punctuation keywords as keywords.  All arg lists
+ *			are terminated with punctuation keywords.
+ *
+ * 09/11/00 (seiwald) - Support for function calls:
+ *
+ *		Rules now return lists (LIST *), rather than void.
+ *
+ *		New "[ rule ]" syntax evals rule into a LIST.
+ *
+ *		Lists are now generated by compile_list() and 
+ *		compile_append(), and any other rule that indirectly
+ *		makes a list, rather than being built directly here,
+ *		so that lists values can contain rule evaluations.
+ *
+ *		New 'return' rule sets the return value, though
+ *		other statements also may have return values.
+ *
+ *		'run' production split from 'block' production so 
+ *		that empty blocks can be handled separately.
+ */
+
+%token ARG STRING
+
+%left _BARBAR_t _BAR_t
+%left _AMPERAMPER_t _AMPER_t
+%left _EQUALS_t _BANG_EQUALS_t IN_t
+%left _LANGLE_t _LANGLE_EQUALS_t _RANGLE_t _RANGLE_EQUALS_t
+%left _BANG_t
+
+%{
+#include "jam.h"
+
+#include "lists.h"
+#include "parse.h"
+#include "scan.h"
+#include "compile.h"
+#include "newstr.h"
+#include "rules.h"
+
+# define YYMAXDEPTH 10000	/* for OSF and other less endowed yaccs */
+
+# define F0 (LIST *(*)(PARSE *, FRAME *))0
+# define P0 (PARSE *)0
+# define S0 (char *)0
+
+# define pappend( l,r )    	parse_make( compile_append,l,r,P0,S0,S0,0 )
+# define peval( c,l,r )	parse_make( compile_eval,l,r,P0,S0,S0,c )
+# define pfor( s,l,r,x )    	parse_make( compile_foreach,l,r,P0,s,S0,x )
+# define pif( l,r,t )	  	parse_make( compile_if,l,r,t,S0,S0,0 )
+# define pincl( l )       	parse_make( compile_include,l,P0,P0,S0,S0,0 )
+# define plist( s )	  	parse_make( compile_list,P0,P0,P0,s,S0,0 )
+# define plocal( l,r,t )  	parse_make( compile_local,l,r,t,S0,S0,0 )
+# define pmodule( l,r )	  	parse_make( compile_module,l,r,P0,S0,S0,0 )
+# define pclass( l,r )	  	parse_make( compile_class,l,r,P0,S0,S0,0 )
+# define pnull()	  	parse_make( compile_null,P0,P0,P0,S0,S0,0 )
+# define pon( l,r )	  	parse_make( compile_on,l,r,P0,S0,S0,0 )
+# define prule( s,p )     	parse_make( compile_rule,p,P0,P0,s,S0,0 )
+# define prules( l,r )	  	parse_make( compile_rules,l,r,P0,S0,S0,0 )
+# define pset( l,r,a )          parse_make( compile_set,l,r,P0,S0,S0,a )
+# define pset1( l,r,t,a )	parse_make( compile_settings,l,r,t,S0,S0,a )
+# define psetc( s,p,a,l )     	parse_make( compile_setcomp,p,a,P0,s,S0,l )
+# define psete( s,l,s1,f ) 	parse_make( compile_setexec,l,P0,P0,s,s1,f )
+# define pswitch( l,r )   	parse_make( compile_switch,l,r,P0,S0,S0,0 )
+# define pwhile( l,r )   	parse_make( compile_while,l,r,P0,S0,S0,0 )
+
+# define pnode( l,r )    	parse_make( F0,l,r,P0,S0,S0,0 )
+# define psnode( s,l )     	parse_make( F0,l,P0,P0,s,S0,0 )
+
+%}
+
+%%
+
+run	: /* empty */
+		/* do nothing */
+	| rules
+		{ parse_save( $1.parse ); }
+	;
+
+/*
+ * block - zero or more rules
+ * rules - one or more rules
+ * rule - any one of jam's rules
+ * right-recursive so rules execute in order.
+ */
+
+block	: null
+                { $$.parse = $1.parse; }
+	| rules
+		{ $$.parse = $1.parse; }
+	;
+
+rules	: rule
+		{ $$.parse = $1.parse; }
+	| rule rules
+		{ $$.parse = prules( $1.parse, $2.parse ); }
+	| LOCAL_t list assign_list_opt _SEMIC_t block
+		{ $$.parse = plocal( $2.parse, $3.parse, $5.parse ); }
+	;
+
+null    : /* empty */
+        { $$.parse = pnull(); }
+        ;
+
+assign_list_opt : _EQUALS_t list
+                { $$.parse = $2.parse; $$.number = ASSIGN_SET; }
+        | null
+		{ $$.parse = $1.parse; $$.number = ASSIGN_APPEND; }
+        ;
+
+arglist_opt : _LPAREN_t lol _RPAREN_t
+                { $$.parse = $2.parse; }
+        |
+                { $$.parse = P0; }
+        ;
+
+local_opt : LOCAL_t
+                { $$.number = 1; }
+          | /* empty */
+                { $$.number = 0; }
+          ;
+
+rule	: _LBRACE_t block _RBRACE_t
+		{ $$.parse = $2.parse; }
+	| INCLUDE_t list _SEMIC_t
+		{ $$.parse = pincl( $2.parse ); }
+	| ARG lol _SEMIC_t
+		{ $$.parse = prule( $1.string, $2.parse ); }
+	| arg assign list _SEMIC_t
+		{ $$.parse = pset( $1.parse, $3.parse, $2.number ); }
+	| arg ON_t list assign list _SEMIC_t
+		{ $$.parse = pset1( $1.parse, $3.parse, $5.parse, $4.number ); }
+	| RETURN_t list _SEMIC_t
+		{ $$.parse = $2.parse; }
+	| FOR_t local_opt ARG IN_t list _LBRACE_t block _RBRACE_t
+		{ $$.parse = pfor( $3.string, $5.parse, $7.parse, $2.number ); }
+	| SWITCH_t list _LBRACE_t cases _RBRACE_t
+		{ $$.parse = pswitch( $2.parse, $4.parse ); }
+	| IF_t expr _LBRACE_t block _RBRACE_t 
+		{ $$.parse = pif( $2.parse, $4.parse, pnull() ); }
+	| MODULE_t list _LBRACE_t block _RBRACE_t 
+		{ $$.parse = pmodule( $2.parse, $4.parse ); }
+	| CLASS_t lol _LBRACE_t block _RBRACE_t 
+		{ $$.parse = pclass( $2.parse, $4.parse ); }
+	| WHILE_t expr _LBRACE_t block _RBRACE_t 
+		{ $$.parse = pwhile( $2.parse, $4.parse ); }
+	| IF_t expr _LBRACE_t block _RBRACE_t ELSE_t rule
+		{ $$.parse = pif( $2.parse, $4.parse, $7.parse ); }
+     | local_opt RULE_t ARG arglist_opt rule
+		{ $$.parse = psetc( $3.string, $5.parse, $4.parse, $1.number ); }
+	| ON_t arg rule
+		{ $$.parse = pon( $2.parse, $3.parse ); }
+	| ACTIONS_t eflags ARG bindlist _LBRACE_t
+		{ yymode( SCAN_STRING ); }
+	  STRING 
+		{ yymode( SCAN_NORMAL ); }
+	  _RBRACE_t
+		{ $$.parse = psete( $3.string,$4.parse,$7.string,$2.number ); }
+	;
+
+/*
+ * assign - = or +=
+ */
+
+assign	: _EQUALS_t
+		{ $$.number = ASSIGN_SET; }
+	| _PLUS_EQUALS_t
+		{ $$.number = ASSIGN_APPEND; }
+	| _QUESTION_EQUALS_t
+		{ $$.number = ASSIGN_DEFAULT; }
+	| DEFAULT_t _EQUALS_t
+		{ $$.number = ASSIGN_DEFAULT; }
+	;
+
+/*
+ * expr - an expression for if
+ */
+expr	: arg 
+		{ $$.parse = peval( EXPR_EXISTS, $1.parse, pnull() ); }
+	| expr _EQUALS_t expr 
+		{ $$.parse = peval( EXPR_EQUALS, $1.parse, $3.parse ); }
+	| expr _BANG_EQUALS_t expr
+		{ $$.parse = peval( EXPR_NOTEQ, $1.parse, $3.parse ); }
+	| expr _LANGLE_t expr
+		{ $$.parse = peval( EXPR_LESS, $1.parse, $3.parse ); }
+	| expr _LANGLE_EQUALS_t expr 
+		{ $$.parse = peval( EXPR_LESSEQ, $1.parse, $3.parse ); }
+	| expr _RANGLE_t expr 
+		{ $$.parse = peval( EXPR_MORE, $1.parse, $3.parse ); }
+	| expr _RANGLE_EQUALS_t expr 
+		{ $$.parse = peval( EXPR_MOREEQ, $1.parse, $3.parse ); }
+	| expr _AMPER_t expr 
+		{ $$.parse = peval( EXPR_AND, $1.parse, $3.parse ); }
+	| expr _AMPERAMPER_t expr 
+		{ $$.parse = peval( EXPR_AND, $1.parse, $3.parse ); }
+	| expr _BAR_t expr
+		{ $$.parse = peval( EXPR_OR, $1.parse, $3.parse ); }
+	| expr _BARBAR_t expr
+		{ $$.parse = peval( EXPR_OR, $1.parse, $3.parse ); }
+	| arg IN_t list
+		{ $$.parse = peval( EXPR_IN, $1.parse, $3.parse ); }
+	| _BANG_t expr
+		{ $$.parse = peval( EXPR_NOT, $2.parse, pnull() ); }
+	| _LPAREN_t expr _RPAREN_t
+		{ $$.parse = $2.parse; }
+	;
+
+
+/*
+ * cases - action elements inside a 'switch'
+ * case - a single action element inside a 'switch'
+ * right-recursive rule so cases can be examined in order.
+ */
+
+cases	: /* empty */
+		{ $$.parse = P0; }
+	| case cases
+		{ $$.parse = pnode( $1.parse, $2.parse ); }
+	;
+
+case	: CASE_t ARG _COLON_t block
+		{ $$.parse = psnode( $2.string, $4.parse ); }
+	;
+
+/*
+ * lol - list of lists
+ * right-recursive rule so that lists can be added in order.
+ */
+
+lol	: list
+		{ $$.parse = pnode( P0, $1.parse ); }
+	| list _COLON_t lol
+		{ $$.parse = pnode( $3.parse, $1.parse ); }
+	;
+
+/*
+ * list - zero or more args in a LIST
+ * listp - list (in puncutation only mode)
+ * arg - one ARG or function call
+ */
+
+list	: listp
+		{ $$.parse = $1.parse; yymode( SCAN_NORMAL ); }
+	;
+
+listp	: /* empty */
+		{ $$.parse = pnull(); yymode( SCAN_PUNCT ); }
+	| listp arg
+        	{ $$.parse = pappend( $1.parse, $2.parse ); }
+	;
+
+arg	: ARG 
+		{ $$.parse = plist( $1.string ); }
+	| _LBRACKET_t { yymode( SCAN_NORMAL ); } func _RBRACKET_t
+		{ $$.parse = $3.parse; }
+	;
+
+/*
+ * func - a function call (inside [])
+ * This needs to be split cleanly out of 'rule'
+ */
+
+func	: arg lol
+		{ $$.parse = prule( $1.string, $2.parse ); }
+	| ON_t arg arg lol
+		{ $$.parse = pon( $2.parse, prule( $3.string, $4.parse ) ); }
+	| ON_t arg RETURN_t list 
+		{ $$.parse = pon( $2.parse, $4.parse ); }
+	;
+
+
+/*
+ * eflags - zero or more modifiers to 'executes'
+ * eflag - a single modifier to 'executes'
+ */
+
+eflags	: /* empty */
+		{ $$.number = 0; }
+	| eflags eflag
+		{ $$.number = $1.number | $2.number; }
+	;
+
+eflag	: UPDATED_t
+		{ $$.number = EXEC_UPDATED; }
+	| TOGETHER_t
+		{ $$.number = EXEC_TOGETHER; }
+	| IGNORE_t
+		{ $$.number = EXEC_IGNORE; }
+	| QUIETLY_t
+		{ $$.number = EXEC_QUIETLY; }
+	| PIECEMEAL_t
+		{ $$.number = EXEC_PIECEMEAL; }
+	| EXISTING_t
+		{ $$.number = EXEC_EXISTING; }
+	;
+
+
+/*
+ * bindlist - list of variable to bind for an action
+ */
+
+bindlist : /* empty */
+		{ $$.parse = pnull(); }
+	| BIND_t list
+		{ $$.parse = $2.parse; }
+	;
+
+

Added: boost-jam/boost-build/branches/upstream/current/jam_src/jamgram.yy
===================================================================
--- boost-jam/boost-build/branches/upstream/current/jam_src/jamgram.yy	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/jam_src/jamgram.yy	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,329 @@
+/*
+ * Copyright 1993, 2000 Christopher Seiwald.
+ *
+ * This file is part of Jam - see jam.c for Copyright information.
+ */
+
+/*  This file is ALSO:
+ *  Copyright 2001-2004 David Abrahams.
+ *  Distributed under the Boost Software License, Version 1.0.
+ *  (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+ */
+
+/*
+ * jamgram.yy - jam grammar
+ *
+ * 04/13/94 (seiwald) - added shorthand L0 for null list pointer
+ * 06/01/94 (seiwald) - new 'actions existing' does existing sources
+ * 08/23/94 (seiwald) - Support for '+=' (append to variable)
+ * 08/31/94 (seiwald) - Allow ?= as alias for "default =".
+ * 09/15/94 (seiwald) - if conditionals take only single arguments, so
+ *			that 'if foo == bar' gives syntax error (use =).
+ * 02/11/95 (seiwald) - when scanning arguments to rules, only treat
+ *			punctuation keywords as keywords.  All arg lists
+ *			are terminated with punctuation keywords.
+ *
+ * 09/11/00 (seiwald) - Support for function calls:
+ *
+ *		Rules now return lists (LIST *), rather than void.
+ *
+ *		New "[ rule ]" syntax evals rule into a LIST.
+ *
+ *		Lists are now generated by compile_list() and 
+ *		compile_append(), and any other rule that indirectly
+ *		makes a list, rather than being built directly here,
+ *		so that lists values can contain rule evaluations.
+ *
+ *		New 'return' rule sets the return value, though
+ *		other statements also may have return values.
+ *
+ *		'run' production split from 'block' production so 
+ *		that empty blocks can be handled separately.
+ */
+
+%token ARG STRING
+
+%left `||` `|`
+%left `&&` `&`
+%left `=` `!=` `in`
+%left `<` `<=` `>` `>=`
+%left `!`
+
+%{
+#include "jam.h"
+
+#include "lists.h"
+#include "parse.h"
+#include "scan.h"
+#include "compile.h"
+#include "newstr.h"
+#include "rules.h"
+
+# define YYMAXDEPTH 10000	/* for OSF and other less endowed yaccs */
+
+# define F0 (LIST *(*)(PARSE *, FRAME *))0
+# define P0 (PARSE *)0
+# define S0 (char *)0
+
+# define pappend( l,r )    	parse_make( compile_append,l,r,P0,S0,S0,0 )
+# define peval( c,l,r )	parse_make( compile_eval,l,r,P0,S0,S0,c )
+# define pfor( s,l,r,x )    	parse_make( compile_foreach,l,r,P0,s,S0,x )
+# define pif( l,r,t )	  	parse_make( compile_if,l,r,t,S0,S0,0 )
+# define pincl( l )       	parse_make( compile_include,l,P0,P0,S0,S0,0 )
+# define plist( s )	  	parse_make( compile_list,P0,P0,P0,s,S0,0 )
+# define plocal( l,r,t )  	parse_make( compile_local,l,r,t,S0,S0,0 )
+# define pmodule( l,r )	  	parse_make( compile_module,l,r,P0,S0,S0,0 )
+# define pclass( l,r )	  	parse_make( compile_class,l,r,P0,S0,S0,0 )
+# define pnull()	  	parse_make( compile_null,P0,P0,P0,S0,S0,0 )
+# define pon( l,r )	  	parse_make( compile_on,l,r,P0,S0,S0,0 )
+# define prule( s,p )     	parse_make( compile_rule,p,P0,P0,s,S0,0 )
+# define prules( l,r )	  	parse_make( compile_rules,l,r,P0,S0,S0,0 )
+# define pset( l,r,a )          parse_make( compile_set,l,r,P0,S0,S0,a )
+# define pset1( l,r,t,a )	parse_make( compile_settings,l,r,t,S0,S0,a )
+# define psetc( s,p,a,l )     	parse_make( compile_setcomp,p,a,P0,s,S0,l )
+# define psete( s,l,s1,f ) 	parse_make( compile_setexec,l,P0,P0,s,s1,f )
+# define pswitch( l,r )   	parse_make( compile_switch,l,r,P0,S0,S0,0 )
+# define pwhile( l,r )   	parse_make( compile_while,l,r,P0,S0,S0,0 )
+
+# define pnode( l,r )    	parse_make( F0,l,r,P0,S0,S0,0 )
+# define psnode( s,l )     	parse_make( F0,l,P0,P0,s,S0,0 )
+
+%}
+
+%%
+
+run	: /* empty */
+		/* do nothing */
+	| rules
+		{ parse_save( $1.parse ); }
+	;
+
+/*
+ * block - zero or more rules
+ * rules - one or more rules
+ * rule - any one of jam's rules
+ * right-recursive so rules execute in order.
+ */
+
+block	: null
+                { $$.parse = $1.parse; }
+	| rules
+		{ $$.parse = $1.parse; }
+	;
+
+rules	: rule
+		{ $$.parse = $1.parse; }
+	| rule rules
+		{ $$.parse = prules( $1.parse, $2.parse ); }
+	| `local` list assign_list_opt `;` block
+		{ $$.parse = plocal( $2.parse, $3.parse, $5.parse ); }
+	;
+
+null    : /* empty */
+        { $$.parse = pnull(); }
+        ;
+
+assign_list_opt : `=` list
+                { $$.parse = $2.parse; $$.number = ASSIGN_SET; }
+        | null
+		{ $$.parse = $1.parse; $$.number = ASSIGN_APPEND; }
+        ;
+
+arglist_opt : `(` lol `)`
+                { $$.parse = $2.parse; }
+        |
+                { $$.parse = P0; }
+        ;
+
+local_opt : `local`
+                { $$.number = 1; }
+          | /* empty */
+                { $$.number = 0; }
+          ;
+
+rule	: `{` block `}`
+		{ $$.parse = $2.parse; }
+	| `include` list `;`
+		{ $$.parse = pincl( $2.parse ); }
+	| ARG lol `;`
+		{ $$.parse = prule( $1.string, $2.parse ); }
+	| arg assign list `;`
+		{ $$.parse = pset( $1.parse, $3.parse, $2.number ); }
+	| arg `on` list assign list `;`
+		{ $$.parse = pset1( $1.parse, $3.parse, $5.parse, $4.number ); }
+	| `return` list `;`
+		{ $$.parse = $2.parse; }
+	| `for` local_opt ARG `in` list `{` block `}`
+		{ $$.parse = pfor( $3.string, $5.parse, $7.parse, $2.number ); }
+	| `switch` list `{` cases `}`
+		{ $$.parse = pswitch( $2.parse, $4.parse ); }
+	| `if` expr `{` block `}` 
+		{ $$.parse = pif( $2.parse, $4.parse, pnull() ); }
+	| `module` list `{` block `}` 
+		{ $$.parse = pmodule( $2.parse, $4.parse ); }
+	| `class` lol `{` block `}` 
+		{ $$.parse = pclass( $2.parse, $4.parse ); }
+	| `while` expr `{` block `}` 
+		{ $$.parse = pwhile( $2.parse, $4.parse ); }
+	| `if` expr `{` block `}` `else` rule
+		{ $$.parse = pif( $2.parse, $4.parse, $7.parse ); }
+     | local_opt `rule` ARG arglist_opt rule
+		{ $$.parse = psetc( $3.string, $5.parse, $4.parse, $1.number ); }
+	| `on` arg rule
+		{ $$.parse = pon( $2.parse, $3.parse ); }
+	| `actions` eflags ARG bindlist `{`
+		{ yymode( SCAN_STRING ); }
+	  STRING 
+		{ yymode( SCAN_NORMAL ); }
+	  `}`
+		{ $$.parse = psete( $3.string,$4.parse,$7.string,$2.number ); }
+	;
+
+/*
+ * assign - = or +=
+ */
+
+assign	: `=`
+		{ $$.number = ASSIGN_SET; }
+	| `+=`
+		{ $$.number = ASSIGN_APPEND; }
+	| `?=`
+		{ $$.number = ASSIGN_DEFAULT; }
+	| `default` `=`
+		{ $$.number = ASSIGN_DEFAULT; }
+	;
+
+/*
+ * expr - an expression for if
+ */
+expr	: arg 
+		{ $$.parse = peval( EXPR_EXISTS, $1.parse, pnull() ); }
+	| expr `=` expr 
+		{ $$.parse = peval( EXPR_EQUALS, $1.parse, $3.parse ); }
+	| expr `!=` expr
+		{ $$.parse = peval( EXPR_NOTEQ, $1.parse, $3.parse ); }
+	| expr `<` expr
+		{ $$.parse = peval( EXPR_LESS, $1.parse, $3.parse ); }
+	| expr `<=` expr 
+		{ $$.parse = peval( EXPR_LESSEQ, $1.parse, $3.parse ); }
+	| expr `>` expr 
+		{ $$.parse = peval( EXPR_MORE, $1.parse, $3.parse ); }
+	| expr `>=` expr 
+		{ $$.parse = peval( EXPR_MOREEQ, $1.parse, $3.parse ); }
+	| expr `&` expr 
+		{ $$.parse = peval( EXPR_AND, $1.parse, $3.parse ); }
+	| expr `&&` expr 
+		{ $$.parse = peval( EXPR_AND, $1.parse, $3.parse ); }
+	| expr `|` expr
+		{ $$.parse = peval( EXPR_OR, $1.parse, $3.parse ); }
+	| expr `||` expr
+		{ $$.parse = peval( EXPR_OR, $1.parse, $3.parse ); }
+	| arg `in` list
+		{ $$.parse = peval( EXPR_IN, $1.parse, $3.parse ); }
+	| `!` expr
+		{ $$.parse = peval( EXPR_NOT, $2.parse, pnull() ); }
+	| `(` expr `)`
+		{ $$.parse = $2.parse; }
+	;
+
+
+/*
+ * cases - action elements inside a 'switch'
+ * case - a single action element inside a 'switch'
+ * right-recursive rule so cases can be examined in order.
+ */
+
+cases	: /* empty */
+		{ $$.parse = P0; }
+	| case cases
+		{ $$.parse = pnode( $1.parse, $2.parse ); }
+	;
+
+case	: `case` ARG `:` block
+		{ $$.parse = psnode( $2.string, $4.parse ); }
+	;
+
+/*
+ * lol - list of lists
+ * right-recursive rule so that lists can be added in order.
+ */
+
+lol	: list
+		{ $$.parse = pnode( P0, $1.parse ); }
+	| list `:` lol
+		{ $$.parse = pnode( $3.parse, $1.parse ); }
+	;
+
+/*
+ * list - zero or more args in a LIST
+ * listp - list (in puncutation only mode)
+ * arg - one ARG or function call
+ */
+
+list	: listp
+		{ $$.parse = $1.parse; yymode( SCAN_NORMAL ); }
+	;
+
+listp	: /* empty */
+		{ $$.parse = pnull(); yymode( SCAN_PUNCT ); }
+	| listp arg
+        	{ $$.parse = pappend( $1.parse, $2.parse ); }
+	;
+
+arg	: ARG 
+		{ $$.parse = plist( $1.string ); }
+	| `[` { yymode( SCAN_NORMAL ); } func `]`
+		{ $$.parse = $3.parse; }
+	;
+
+/*
+ * func - a function call (inside [])
+ * This needs to be split cleanly out of 'rule'
+ */
+
+func	: arg lol
+		{ $$.parse = prule( $1.string, $2.parse ); }
+	| `on` arg arg lol
+		{ $$.parse = pon( $2.parse, prule( $3.string, $4.parse ) ); }
+	| `on` arg `return` list 
+		{ $$.parse = pon( $2.parse, $4.parse ); }
+	;
+
+
+/*
+ * eflags - zero or more modifiers to 'executes'
+ * eflag - a single modifier to 'executes'
+ */
+
+eflags	: /* empty */
+		{ $$.number = 0; }
+	| eflags eflag
+		{ $$.number = $1.number | $2.number; }
+	;
+
+eflag	: `updated`
+		{ $$.number = EXEC_UPDATED; }
+	| `together`
+		{ $$.number = EXEC_TOGETHER; }
+	| `ignore`
+		{ $$.number = EXEC_IGNORE; }
+	| `quietly`
+		{ $$.number = EXEC_QUIETLY; }
+	| `piecemeal`
+		{ $$.number = EXEC_PIECEMEAL; }
+	| `existing`
+		{ $$.number = EXEC_EXISTING; }
+	;
+
+
+/*
+ * bindlist - list of variable to bind for an action
+ */
+
+bindlist : /* empty */
+		{ $$.parse = pnull(); }
+	| `bind` list
+		{ $$.parse = $2.parse; }
+	;
+
+

Added: boost-jam/boost-build/branches/upstream/current/jam_src/jamgramtab.h
===================================================================
--- boost-jam/boost-build/branches/upstream/current/jam_src/jamgramtab.h	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/jam_src/jamgramtab.h	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,44 @@
+    { "!", _BANG_t },
+    { "!=", _BANG_EQUALS_t },
+    { "&", _AMPER_t },
+    { "&&", _AMPERAMPER_t },
+    { "(", _LPAREN_t },
+    { ")", _RPAREN_t },
+    { "+=", _PLUS_EQUALS_t },
+    { ":", _COLON_t },
+    { ";", _SEMIC_t },
+    { "<", _LANGLE_t },
+    { "<=", _LANGLE_EQUALS_t },
+    { "=", _EQUALS_t },
+    { ">", _RANGLE_t },
+    { ">=", _RANGLE_EQUALS_t },
+    { "?=", _QUESTION_EQUALS_t },
+    { "[", _LBRACKET_t },
+    { "]", _RBRACKET_t },
+    { "actions", ACTIONS_t },
+    { "bind", BIND_t },
+    { "case", CASE_t },
+    { "class", CLASS_t },
+    { "default", DEFAULT_t },
+    { "else", ELSE_t },
+    { "existing", EXISTING_t },
+    { "for", FOR_t },
+    { "if", IF_t },
+    { "ignore", IGNORE_t },
+    { "in", IN_t },
+    { "include", INCLUDE_t },
+    { "local", LOCAL_t },
+    { "module", MODULE_t },
+    { "on", ON_t },
+    { "piecemeal", PIECEMEAL_t },
+    { "quietly", QUIETLY_t },
+    { "return", RETURN_t },
+    { "rule", RULE_t },
+    { "switch", SWITCH_t },
+    { "together", TOGETHER_t },
+    { "updated", UPDATED_t },
+    { "while", WHILE_t },
+    { "{", _LBRACE_t },
+    { "|", _BAR_t },
+    { "||", _BARBAR_t },
+    { "}", _RBRACE_t },

Added: boost-jam/boost-build/branches/upstream/current/jam_src/lists.c
===================================================================
--- boost-jam/boost-build/branches/upstream/current/jam_src/lists.c	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/jam_src/lists.c	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,369 @@
+/*
+ * Copyright 1993, 1995 Christopher Seiwald.
+ *
+ * This file is part of Jam - see jam.c for Copyright information.
+ */
+
+# include "jam.h"
+# include "newstr.h"
+# include "lists.h"
+
+/*
+ * lists.c - maintain lists of strings
+ *
+ * This implementation essentially uses a singly linked list, but
+ * guarantees that the head element of every list has a valid pointer
+ * to the tail of the list, so the new elements can efficiently and 
+ * properly be appended to the end of a list.
+ *
+ * To avoid massive allocation, list_free() just tacks the whole freed
+ * chain onto freelist and list_new() looks on freelist first for an
+ * available list struct.  list_free() does not free the strings in the 
+ * chain: it lazily lets list_new() do so.
+ *
+ * 08/23/94 (seiwald) - new list_append()
+ * 09/07/00 (seiwald) - documented lol_*() functions
+ */
+
+static LIST *freelist = 0;	/* junkpile for list_free() */
+
+/*
+ * list_append() - append a list onto another one, returning total
+ */
+
+LIST *
+list_append( 
+	LIST	*l,
+	LIST	*nl )
+{
+	if( !nl )
+	{
+	    /* Just return l */
+	}
+	else if( !l )
+	{
+	    l = nl;
+	}
+	else
+	{
+	    /* Graft two non-empty lists. */
+	    l->tail->next = nl;
+	    l->tail = nl->tail;
+	}
+
+	return l;
+}
+
+/*
+ * list_new() - tack a string onto the end of a list of strings
+ */
+
+LIST *
+list_new( 
+	LIST	*head,
+	char	*string )
+{
+	LIST *l;
+
+	if( DEBUG_LISTS )
+	    printf( "list > %s <\n", string );
+
+	/* Get list struct from freelist, if one available.  */
+	/* Otherwise allocate. */
+	/* If from freelist, must free string first */
+
+	if( freelist )
+	{
+	    l = freelist;
+	    freestr( l->string );
+	    freelist = freelist->next;
+	}
+	else
+	{
+	    l = (LIST *)malloc( sizeof( *l ) );
+	}
+
+	/* If first on chain, head points here. */
+	/* If adding to chain, tack us on. */
+	/* Tail must point to this new, last element. */
+
+	if( !head ) head = l;
+	else head->tail->next = l;
+	head->tail = l;
+	l->next = 0;
+
+	l->string = string;
+
+	return head;
+}
+
+/*
+ * list_copy() - copy a whole list of strings (nl) onto end of another (l)
+ */
+
+LIST *
+list_copy( 
+	LIST	*l,
+	LIST 	*nl )
+{
+	for( ; nl; nl = list_next( nl ) )
+	    l = list_new( l, copystr( nl->string ) );
+
+	return l;
+}
+
+/*
+ * list_sublist() - copy a subset of a list of strings
+ */
+
+LIST *
+list_sublist( 
+	LIST	*l,
+	int	start,
+	int	count )
+{
+	LIST	*nl = 0;
+
+	for( ; l && start--; l = list_next( l ) )
+	    ;
+
+	for( ; l && count--; l = list_next( l ) )
+	    nl = list_new( nl, copystr( l->string ) );
+
+	return nl;
+}
+
+LIST *
+list_sort(
+    LIST *l)
+{
+
+    LIST* first = 0;
+    LIST* second = 0;
+    LIST* merged = l;
+    LIST* result;
+
+    if (!l)
+        return L0;
+
+    for(;;) {
+        
+        /* Split the list in two */
+        LIST** dst = &first;
+        LIST* src = merged;
+        
+        for(;;) {
+            
+            *dst = list_append(*dst, list_new(0, src->string));
+            
+            if (!src->next)
+                break;
+
+            if (strcmp(src->string, src->next->string) > 0) 
+            {
+                if (dst == &first)
+                    dst = &second;
+                else
+                    dst = &first;
+            }
+            
+            src = src->next;
+        }
+
+        if (merged != l)
+            list_free( merged );
+        merged = 0;
+        
+        if (second == 0) {
+            result = first;
+            break;
+        }
+
+        
+        /* Merge lists 'first' and 'second' into 'merged' and free
+           'first'/'second'. */
+        {
+            LIST* f = first;
+            LIST* s = second;
+
+            while(f && s)
+            {
+                if (strcmp(f->string, s->string) < 0)
+                {
+                    merged = list_append( merged, list_new(0, f->string ));
+                    f = f->next;
+                }
+                else
+                {
+                    merged = list_append( merged, list_new(0, s->string ));
+                    s = s->next;
+                }
+            }
+
+            merged = list_copy( merged, f );
+            merged = list_copy( merged, s );
+            list_free( first );
+            list_free( second );
+            first = 0;
+            second = 0;
+        }                            
+    }
+
+    return result;
+}
+
+/*
+ * list_free() - free a list of strings
+ */
+
+void
+list_free( LIST	*head )
+{
+	/* Just tack onto freelist. */
+
+	if( head )
+	{
+	    head->tail->next = freelist;
+	    freelist = head;
+	}
+}
+
+/*
+ * list_pop_front() - remove the front element from a list of strings
+ */
+LIST *  list_pop_front( LIST *l )
+{
+    LIST * result = l->next;
+    if( result )
+    {
+        result->tail = l->tail;
+        l->next = L0;
+        l->tail = l;
+    }
+    list_free( l );
+    return result;
+}
+
+/*
+ * list_print() - print a list of strings to stdout
+ */
+
+void
+list_print( LIST *l )
+{
+        LIST *p = 0; 
+        for( ; l; p = l, l = list_next( l ) )
+            if ( p ) 
+                printf( "%s ", p->string );
+        if ( p )
+            printf( "%s", p->string );                
+}
+
+/*
+ * list_length() - return the number of items in the list
+ */
+
+int
+list_length( LIST *l )
+{
+	int n = 0;
+
+	for( ; l; l = list_next( l ), ++n )
+	    ;
+
+	return n;
+}
+
+int     
+list_in(LIST* l, char* value)
+{
+    for(; l; l = l->next)
+        if (strcmp(l->string, value) == 0)
+            return 1;
+    return 0;
+}
+
+LIST *  
+list_unique( LIST *sorted_list)
+{
+    LIST* result = 0;
+    LIST* last_added = 0;
+
+    for(; sorted_list; sorted_list = sorted_list->next)
+    {
+        if (!last_added || strcmp(sorted_list->string, last_added->string) != 0)
+        {
+            result = list_new(result, sorted_list->string);
+            last_added = sorted_list;
+        }
+    }
+    return result;    
+}
+
+
+/*
+ * lol_init() - initialize a LOL (list of lists)
+ */
+
+void
+lol_init( LOL *lol )
+{
+    lol->count = 0;
+}
+
+/*
+ * lol_add() - append a LIST onto an LOL
+ */
+
+void
+lol_add( 
+	LOL	*lol,
+	LIST	*l )
+{
+	if( lol->count < LOL_MAX )
+	    lol->list[ lol->count++ ] = l;
+}
+
+/*
+ * lol_free() - free the LOL and its LISTs
+ */
+
+void
+lol_free( LOL *lol )
+{
+	int i;
+
+	for( i = 0; i < lol->count; i++ )
+	    list_free( lol->list[i] );
+
+	lol->count = 0;
+}
+
+/*
+ * lol_get() - return one of the LISTs in the LOL
+ */
+
+LIST *
+lol_get( 
+	LOL	*lol,
+	int	i )
+{
+	return i < lol->count ? lol->list[i] : 0;
+}
+
+/*
+ * lol_print() - debug print LISTS separated by ":"
+ */
+
+void
+lol_print( LOL *lol )
+{
+	int i;
+
+	for( i = 0; i < lol->count; i++ )
+	{
+	    if( i )
+		printf( " : " );
+	    list_print( lol->list[i] );
+	}
+}

Added: boost-jam/boost-build/branches/upstream/current/jam_src/lists.h
===================================================================
--- boost-jam/boost-build/branches/upstream/current/jam_src/lists.h	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/jam_src/lists.h	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,96 @@
+/*
+ * Copyright 1993, 1995 Christopher Seiwald.
+ *
+ * This file is part of Jam - see jam.c for Copyright information.
+ */
+
+/*  This file is ALSO:
+ *  Copyright 2001-2004 David Abrahams.
+ *  Distributed under the Boost Software License, Version 1.0.
+ *  (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+ */
+
+/*
+ * lists.h - the LIST structure and routines to manipulate them
+ *
+ * The whole of jam relies on lists of strings as a datatype.  This
+ * module, in conjunction with newstr.c, handles these relatively
+ * efficiently.
+ *
+ * Structures defined:
+ *
+ *	LIST - list of strings
+ *	LOL - list of LISTs
+ *
+ * External routines:
+ *
+ *	list_append() - append a list onto another one, returning total
+ *	list_new() - tack a string onto the end of a list of strings
+ * 	list_copy() - copy a whole list of strings
+ *	list_sublist() - copy a subset of a list of strings
+ *	list_free() - free a list of strings
+ *	list_print() - print a list of strings to stdout
+ *	list_length() - return the number of items in the list
+ *
+ *	lol_init() - initialize a LOL (list of lists)
+ *	lol_add() - append a LIST onto an LOL
+ *	lol_free() - free the LOL and its LISTs
+ *	lol_get() - return one of the LISTs in the LOL
+ *	lol_print() - debug print LISTS separated by ":"
+ *
+ * 04/13/94 (seiwald) - added shorthand L0 for null list pointer
+ * 08/23/94 (seiwald) - new list_append()
+ */
+
+#ifndef LISTS_DWA20011022_H
+# define LISTS_DWA20011022_H
+
+/*
+ * LIST - list of strings
+ */
+
+typedef struct _list LIST;
+
+struct _list {
+	LIST	*next;
+	LIST	*tail;		/* only valid in head node */
+	char	*string;	/* private copy */
+} ;
+
+/*
+ * LOL - list of LISTs
+ */
+
+typedef struct _lol LOL;
+
+# define LOL_MAX 9
+
+struct _lol {
+	int	count;
+	LIST	*list[ LOL_MAX ];
+} ;
+
+LIST *	list_append( LIST *l, LIST *nl );
+LIST *	list_copy( LIST *l, LIST  *nl );
+void	list_free( LIST *head );
+LIST *	list_new( LIST *head, char *string );
+void	list_print( LIST *l );
+int	list_length( LIST *l );
+LIST *	list_sublist( LIST *l, int start, int count );
+LIST *  list_pop_front( LIST *l );
+LIST *  list_sort( LIST *l);
+LIST *  list_unique( LIST *sorted_list);
+int     list_in(LIST* l, char* value);
+
+# define list_next( l ) ((l)->next)
+
+# define L0 ((LIST *)0)
+
+void	lol_add( LOL *lol, LIST *l );
+void	lol_init( LOL *lol );
+void	lol_free( LOL *lol );
+LIST *	lol_get( LOL *lol, int i );
+void	lol_print( LOL *lol );
+
+#endif
+

Added: boost-jam/boost-build/branches/upstream/current/jam_src/make.c
===================================================================
--- boost-jam/boost-build/branches/upstream/current/jam_src/make.c	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/jam_src/make.c	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,779 @@
+/*
+ * Copyright 1993, 1995 Christopher Seiwald.
+ *
+ * This file is part of Jam - see jam.c for Copyright information.
+ */
+
+/*  This file is ALSO:
+ *  Copyright 2001-2004 David Abrahams.
+ *  Distributed under the Boost Software License, Version 1.0.
+ *  (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+ */
+
+/*
+ * make.c - bring a target up to date, once rules are in place
+ *
+ * This modules controls the execution of rules to bring a target and
+ * its dependencies up to date.  It is invoked after the targets, rules,
+ * et. al. described in rules.h are created by the interpreting of the
+ * jam files.
+ *
+ * This file contains the main make() entry point and the first pass
+ * make0().  The second pass, make1(), which actually does the command
+ * execution, is in make1.c.
+ *
+ * External routines:
+ *	make() - make a target, given its name
+ *
+ * Internal routines:
+ * 	make0() - bind and scan everything to make a TARGET
+ * 	make0sort() - reorder TARGETS chain by their time (newest to oldest)
+ *
+ * 12/26/93 (seiwald) - allow NOTIME targets to be expanded via $(<), $(>)
+ * 01/04/94 (seiwald) - print all targets, bounded, when tracing commands
+ * 04/08/94 (seiwald) - progress report now reflects only targets with actions
+ * 04/11/94 (seiwald) - Combined deps & headers into deps[2] in TARGET.
+ * 12/20/94 (seiwald) - NOTIME renamed NOTFILE.
+ * 12/20/94 (seiwald) - make0() headers after determining fate of target, so 
+ *			that headers aren't seen as dependents on themselves.
+ * 01/19/95 (seiwald) - distinguish between CANTFIND/CANTMAKE targets.
+ * 02/02/95 (seiwald) - propagate leaf source time for new LEAVES rule.
+ * 02/14/95 (seiwald) - NOUPDATE rule means don't update existing target.
+ * 08/22/95 (seiwald) - NOUPDATE targets immune to anyhow (-a) flag.
+ * 09/06/00 (seiwald) - NOCARE affects targets with sources/actions.
+ * 03/02/01 (seiwald) - reverse NOCARE change.
+ * 03/14/02 (seiwald) - TEMPORARY targets no longer take on parents age
+ * 03/16/02 (seiwald) - support for -g (reorder builds by source time)
+ */
+
+# include "jam.h"
+
+# include "lists.h"
+# include "parse.h"
+# include "variable.h"
+# include "rules.h"
+
+#ifdef OPT_HEADER_CACHE_EXT
+# include "hcache.h"
+#endif
+
+# include "search.h"
+# include "newstr.h"
+# include "make.h"
+# include "headers.h"
+# include "command.h"
+# include <assert.h>
+
+# ifndef max
+# define max( a,b ) ((a)>(b)?(a):(b))
+# endif
+
+static TARGETS *make0sort( TARGETS *c );
+
+#ifdef OPT_GRAPH_DEBUG_EXT
+static void dependGraphOutput( TARGET *t, int depth );
+#endif
+
+static const char *target_fate[] = 
+{
+	"init",		/* T_FATE_INIT */
+	"making", 	/* T_FATE_MAKING */
+	"stable", 	/* T_FATE_STABLE */
+	"newer",	/* T_FATE_NEWER */
+	"temp", 	/* T_FATE_ISTMP */
+	"touched", 	/* T_FATE_TOUCHED */
+	"missing", 	/* T_FATE_MISSING */
+	"needtmp", 	/* T_FATE_NEEDTMP */
+	"old", 		/* T_FATE_OUTDATED */
+	"update", 	/* T_FATE_UPDATE */
+	"nofind", 	/* T_FATE_CANTFIND */
+	"nomake" 	/* T_FATE_CANTMAKE */
+} ;
+
+static const char *target_bind[] = 
+{
+	"unbound",
+	"missing",
+	"parents",
+	"exists",
+} ;
+
+# define spaces(x) ( "                    " + ( x > 20 ? 0 : 20-x ) )
+
+/*
+ * make() - make a target, given its name
+ */
+
+int
+make( 
+	int		n_targets,
+	const char	**targets,
+	int		anyhow )
+{
+	int i;
+	COUNTS counts[1];
+	int status = 0;		/* 1 if anything fails */
+
+#ifdef OPT_HEADER_CACHE_EXT
+	hcache_init();
+#endif
+
+	memset( (char *)counts, 0, sizeof( *counts ) );
+
+    /* First bind all targets with LOCATE_TARGET setting. This is
+       needed to correctly handle dependencies to generated headers.       
+    */
+    bind_explicitly_located_targets();
+
+	for( i = 0; i < n_targets; i++ )
+	{
+	    TARGET *t = bindtarget( targets[i] );
+
+	    make0( t, 0, 0, counts, anyhow );
+	}
+        
+#ifdef OPT_GRAPH_DEBUG_EXT
+	if( DEBUG_GRAPH )
+	{
+	    for( i = 0; i < n_targets; i++ )
+	    {
+		TARGET *t = bindtarget( targets[i] );
+		dependGraphOutput( t, 0 );
+	    }
+	}
+#endif
+
+	if( DEBUG_MAKE )
+	{
+	    if( counts->targets )
+		printf( "...found %d target%s...\n", counts->targets,
+		        counts->targets > 1 ? "s" : "" );
+	    if( counts->temp )
+		printf( "...using %d temp target%s...\n", counts->temp,
+		        counts->temp > 1 ? "s" : "" );
+	    if( counts->updating )
+		printf( "...updating %d target%s...\n", counts->updating,
+		        counts->updating > 1 ? "s" : "" );
+	    if( counts->cantfind )
+		printf( "...can't find %d target%s...\n", counts->cantfind,
+		        counts->cantfind > 1 ? "s" : "" );
+	    if( counts->cantmake )
+		printf( "...can't make %d target%s...\n", counts->cantmake,
+		        counts->cantmake > 1 ? "s" : "" );
+	}
+
+#ifdef OPT_HEADER_CACHE_EXT
+	hcache_done();
+#endif
+
+	status = counts->cantfind || counts->cantmake;
+
+	for( i = 0; i < n_targets; i++ )
+	    status |= make1( bindtarget( targets[i] ) );
+
+	return status;
+}
+
+/*
+ * make0() - bind and scan everything to make a TARGET
+ *
+ * Make0() recursively binds a target, searches for #included headers,
+ * calls itself on those headers, and calls itself on any dependents.
+ */
+
+void
+make0( 
+	TARGET	*t,
+	TARGET  *p,		/* parent */
+	int	depth,		/* for display purposes */
+	COUNTS	*counts,	/* for reporting */
+	int	anyhow )	/* forcibly touch all (real) targets */
+{
+	TARGETS	*c, *d, *incs;
+	TARGET 	*ptime = t;
+	time_t	last, leaf, hlast;
+	int	fate;
+	const char *flag = "";
+	SETTINGS *s;
+
+#ifdef OPT_GRAPH_DEBUG_EXT
+	int	savedFate, oldTimeStamp;
+#endif
+
+	if( DEBUG_MAKEPROG )
+	    printf( "make\t--\t%s%s\n", spaces( depth ), t->name );
+
+	/* 
+	 * Step 1: initialize
+	 */
+
+	if( DEBUG_MAKEPROG )
+	    printf( "make\t--\t%s%s\n", spaces( depth ), t->name );
+
+	t->fate = T_FATE_MAKING;
+
+	/*
+	 * Step 2: under the influence of "on target" variables,
+	 * bind the target and search for headers.
+	 */
+
+	/* Step 2a: set "on target" variables. */
+
+	s = copysettings( t->settings );
+	pushsettings( s );
+
+	/* Step 2b: find and timestamp the target file (if it's a file). */
+
+	if( t->binding == T_BIND_UNBOUND && !( t->flags & T_FLAG_NOTFILE ) )
+	{
+            char* another_target;
+            t->boundname = search( t->name, &t->time, &another_target );
+            /* If it was detected that this target refers to an already
+               existing and bound one, we add include dependency, so that
+               every target which depends on us will depend on that other 
+               target. */
+            if( another_target )
+            {
+                TARGET* includes;
+                if (!t->includes) {
+                    t->includes = copytarget(t);
+                    t->includes->original_target = t;
+                }
+                includes = t->includes;
+                includes->depends = targetlist( includes->depends,
+                                              list_new( L0, another_target ) );
+            }
+        
+	    t->binding = t->time ? T_BIND_EXISTS : T_BIND_MISSING;
+	}
+
+	/* INTERNAL, NOTFILE header nodes have the time of their parents */
+
+	if( p && t->flags & T_FLAG_INTERNAL )
+	    ptime = p;
+
+	/* If temp file doesn't exist but parent does, use parent */
+	if( p && t->flags & T_FLAG_TEMP && 
+	    t->binding == T_BIND_MISSING && 
+	    p->binding != T_BIND_MISSING )
+    {
+	    t->binding = T_BIND_PARENTS;
+	    ptime = p;
+    }
+
+#ifdef OPT_SEMAPHORE
+	{
+	    LIST *var = var_get( "JAM_SEMAPHORE" );
+	    if( var )
+	    {
+		TARGET *semaphore = bindtarget( var->string );
+
+		semaphore->progress = T_MAKE_SEMAPHORE;
+		t->semaphore = semaphore;
+	    }
+	}
+#endif
+
+	/* Step 2c: If its a file, search for headers. */
+
+	if( t->binding == T_BIND_EXISTS )
+	    headers( t );
+
+	/* Step 2d: reset "on target" variables */
+
+	popsettings( s );
+	freesettings( s );
+
+	/* 
+	 * Pause for a little progress reporting 
+	 */
+
+	if( DEBUG_BIND )
+
+	{
+	    if( strcmp( t->name, t->boundname ) )
+	    {
+		printf( "bind\t--\t%s%s: %s\n",
+			spaces( depth ), t->name, t->boundname );
+	    }
+
+	    switch( t->binding )
+	    {
+	    case T_BIND_UNBOUND:
+	    case T_BIND_MISSING:
+	    case T_BIND_PARENTS:
+		printf( "time\t--\t%s%s: %s\n",
+			spaces( depth ), t->name, target_bind[ t->binding ] );
+		break;
+
+	    case T_BIND_EXISTS:
+		printf( "time\t--\t%s%s: %s",
+			spaces( depth ), t->name, ctime( &t->time ) );
+		break;
+	    }
+	}
+
+	/* 
+	 * Step 3: recursively make0() dependents & headers
+	 */
+
+	/* Step 3a: recursively make0() dependents */
+
+	for( c = t->depends; c; c = c->next )
+	{
+	    int internal = t->flags & T_FLAG_INTERNAL;
+/* Seems like it's not relevant for us....
+	    if( DEBUG_DEPENDS )
+		printf( "%s \"%s\" : \"%s\" ;\n", 
+		    internal ? "Includes" : "Depends",
+		    t->name, c->target->name );
+*/
+
+	    /* Warn about circular deps, except for includes, */
+	    /* which include each other alot. */
+
+	    if( c->target->fate == T_FATE_INIT )
+		make0( c->target, ptime, depth + 1, counts, anyhow );
+	    else if( c->target->fate == T_FATE_MAKING && !internal )
+		printf( "warning: %s depends on itself\n", c->target->name );
+	}
+
+	/* Step 3b: recursively make0() internal includes node */
+
+	if( t->includes )
+	    make0( t->includes, p, depth + 1, counts, anyhow );
+
+	/* Step 3c: add dependents' includes to our direct dependencies */
+
+	incs = 0;
+
+	for( c = t->depends; c; c = c->next )
+	    if( c->target->includes )
+		incs = targetentry( incs, c->target->includes );
+
+	t->depends = targetchain( t->depends, incs );
+
+	/*
+	 * Step 4: compute time & fate 
+	 */
+
+	/* Step 4a: pick up dependents' time and fate */
+
+
+	last = 0;
+	leaf = 0;
+	fate = T_FATE_STABLE;
+
+	for( c = t->depends; c; c = c->next )
+	{
+	    /* If LEAVES has been applied, we only heed the timestamps of */
+	    /* the leaf source nodes. */
+
+	    leaf = max( leaf, c->target->leaf );
+
+	    if( t->flags & T_FLAG_LEAVES )
+	    {
+		last = leaf;
+		continue;
+	    }
+
+	    last = max( last, c->target->time );
+	    fate = max( fate, c->target->fate );
+
+#ifdef OPT_GRAPH_DEBUG_EXT
+	    if( DEBUG_FATE )
+		if( fate < c->target->fate )
+		    printf( "fate change  %s from %s to %s by dependency %s\n",
+			    t->name,
+			    target_fate[fate], target_fate[c->target->fate],
+			    c->target->name);
+#endif
+
+	}
+
+	/* Step 4b: pick up included headers time */
+
+	/* 
+	 * If a header is newer than a temp source that includes it, 
+	 * the temp source will need building.   
+	 */
+
+	hlast = t->includes ? t->includes->time : 0;
+
+	/* Step 4c: handle NOUPDATE oddity */
+
+	/*
+	 * If a NOUPDATE file exists, make dependents eternally old.
+	 * Don't inherit our fate from our dependents.  Decide fate
+	 * based only upon other flags and our binding (done later).
+	 */
+
+	if( t->flags & T_FLAG_NOUPDATE )
+	{
+#ifdef OPT_GRAPH_DEBUG_EXT
+	    if( DEBUG_FATE )
+		if( fate != T_FATE_STABLE )
+		    printf( "fate change  %s back to stable, NOUPDATE.\n",
+			   t->name);
+#endif
+
+	    last = 0;
+	    t->time = 0;
+
+
+	    /*
+	     * Don't inherit our fate from our dependents.  Decide fate
+	     * based only upon other flags and our binding (done later).
+	     */
+
+	    fate = T_FATE_STABLE;
+	}
+
+	/* Step 4d: determine fate: rebuild target or what? */
+
+	/* 
+	    In English:
+		If can't find or make child, can't make target.
+		If children changed, make target.
+		If target missing, make it.
+		If children newer, make target.
+		If temp's children newer than parent, make temp.
+		If temp's headers newer than parent, make temp.
+		If deliberately touched, make it.
+		If up-to-date temp file present, use it.
+		If target newer than non-notfile parent, mark target newer.
+		Otherwise, stable!
+
+		Note this block runs from least to most stable:
+		as we make it further down the list, the target's
+		fate is getting stabler.
+	*/
+
+#ifdef OPT_GRAPH_DEBUG_EXT
+	savedFate = fate;
+	oldTimeStamp = 0;
+#endif
+
+	if( fate >= T_FATE_BROKEN )
+	{
+	    fate = T_FATE_CANTMAKE;
+	}
+	else if( fate >= T_FATE_SPOIL )
+	{
+	    fate = T_FATE_UPDATE;
+	}
+	else if( t->binding == T_BIND_MISSING )
+	{
+	    fate = T_FATE_MISSING;
+	}
+	else if( t->binding == T_BIND_EXISTS && last > t->time )
+	{
+#ifdef OPT_GRAPH_DEBUG_EXT
+	    oldTimeStamp = 1;
+#endif
+	    fate = T_FATE_OUTDATED;
+	}
+	else if( t->binding == T_BIND_PARENTS && last > p->time )
+	{
+#ifdef OPT_GRAPH_DEBUG_EXT
+	    oldTimeStamp = 1;
+#endif
+	    fate = T_FATE_NEEDTMP;
+	}
+	else if( t->binding == T_BIND_PARENTS && hlast > p->time )
+	{
+	    fate = T_FATE_NEEDTMP;
+	}
+	else if( t->flags & T_FLAG_TOUCHED )
+	{
+	    fate = T_FATE_TOUCHED;
+	}
+	else if( anyhow && !( t->flags & T_FLAG_NOUPDATE ) )
+	{
+	    fate = T_FATE_TOUCHED;
+	}
+	else if( t->binding == T_BIND_EXISTS && t->flags & T_FLAG_TEMP )
+	{
+	    fate = T_FATE_ISTMP;
+	}
+	else if( t->binding == T_BIND_EXISTS && p && 
+		 p->binding != T_BIND_UNBOUND && t->time > p->time )
+	{
+#ifdef OPT_GRAPH_DEBUG_EXT
+	    oldTimeStamp = 1;
+#endif
+	    fate = T_FATE_NEWER;
+	}
+	else
+	{
+	    fate = T_FATE_STABLE;
+	}
+#ifdef OPT_GRAPH_DEBUG_EXT
+	if( DEBUG_FATE && fate != savedFate )
+	    if( savedFate == T_FATE_STABLE )
+		printf( "fate change  %s set to %s%s\n",
+		       t->name, target_fate[fate],
+		       oldTimeStamp ? " (by timestamp)" : "" );
+	    else
+		printf( "fate change  %s adjusted from %s to %s%s\n",
+		       t->name, target_fate[savedFate], target_fate[fate],
+		       oldTimeStamp ? " (by timestamp)" : "" );
+#endif
+
+	/* Step 4e: handle missing files */
+	/* If it's missing and there are no actions to create it, boom. */
+	/* If we can't make a target we don't care about, 'sokay */
+	/* We could insist that there are updating actions for all missing */
+	/* files, but if they have dependents we just pretend it's NOTFILE. */
+
+	if( fate == T_FATE_MISSING && !t->actions && !t->depends )
+	{
+	    if( t->flags & T_FLAG_NOCARE )
+	    {
+#ifdef OPT_GRAPH_DEBUG_EXT
+		if( DEBUG_FATE )
+		    printf( "fate change  %s to STABLE from %s, "
+			    "no actions, no dependents and don't care\n",
+			    t->name, target_fate[fate]);
+#endif
+		fate = T_FATE_STABLE;
+	    }
+	    else
+	    {
+		printf( "don't know how to make %s\n", t->name );
+
+		fate = T_FATE_CANTFIND;
+	    }
+	}
+
+	/* Step 4f: propagate dependents' time & fate. */
+	/* Set leaf time to be our time only if this is a leaf. */
+
+	t->time = max( t->time, last );
+	t->leaf = leaf ? leaf : t->time ;
+	t->fate = fate;
+
+	/* 
+	 * Step 5: sort dependents by their update time. 
+	 */
+
+	if( globs.newestfirst )
+	    t->depends = make0sort( t->depends );
+
+	/* 
+	 * Step 6: a little harmless tabulating for tracing purposes 
+	 */
+
+	/* Don't count or report interal includes nodes. */
+
+	if( t->flags & T_FLAG_INTERNAL )
+	    return;
+
+    if (counts) {
+#ifdef OPT_IMPROVED_PATIENCE_EXT
+        ++counts->targets;
+#else	
+        if( !( ++counts->targets % 1000 ) && DEBUG_MAKE )
+            printf( "...patience...\n" );
+#endif
+
+        if( fate == T_FATE_ISTMP )
+            counts->temp++;
+        else if( fate == T_FATE_CANTFIND )
+            counts->cantfind++;
+        else if( fate == T_FATE_CANTMAKE && t->actions )
+            counts->cantmake++;
+        else if( fate >= T_FATE_BUILD && fate < T_FATE_BROKEN && t->actions )
+            counts->updating++;
+    }
+
+	if( !( t->flags & T_FLAG_NOTFILE ) && fate >= T_FATE_SPOIL )
+	    flag = "+";
+	else if( t->binding == T_BIND_EXISTS && p && t->time > p->time )
+	    flag = "*";
+
+	if( DEBUG_MAKEPROG )
+	    printf( "made%s\t%s\t%s%s\n", 
+		flag, target_fate[ t->fate ], 
+		spaces( depth ), t->name );
+
+/* We don't have DEBUG_CAUSES. 
+	if( DEBUG_CAUSES && 
+	    t->fate >= T_FATE_NEWER && 
+	    t->fate <= T_FATE_MISSING )
+		printf( "%s %s\n", target_fate[ t->fate ], t->name );
+*/
+}
+
+#ifdef OPT_GRAPH_DEBUG_EXT
+
+static const char* target_name( TARGET* t )
+{
+    static char buf[1000];
+    if (t->flags & T_FLAG_INTERNAL) {
+        sprintf(buf, "%s (internal node)", t->name);
+        return buf;
+    } else {
+        return t->name;
+    }
+}
+
+/*
+ * dependGraphOutput() - output the DG after make0 has run
+ */
+
+static void
+dependGraphOutput( TARGET *t, int depth )
+{
+    TARGETS	*c;
+
+    if (   (t->flags & T_FLAG_VISITED) != 0
+	|| !t->name
+	|| !t->boundname)
+	return;
+
+    t->flags |= T_FLAG_VISITED;
+
+    switch (t->fate)
+    {
+      case T_FATE_TOUCHED:
+      case T_FATE_MISSING:
+      case T_FATE_OUTDATED:
+      case T_FATE_UPDATE:
+	printf( "->%s%2d Name: %s\n", spaces(depth), depth, target_name(t) );
+	break;
+      default:
+	printf( "  %s%2d Name: %s\n", spaces(depth), depth, target_name(t) );
+	break;
+    }
+
+    if( strcmp (t->name, t->boundname) )
+    {
+	printf( "  %s    Loc: %s\n", spaces(depth), t->boundname );
+    }
+
+    switch( t->fate )
+    {
+      case T_FATE_STABLE:
+	printf( "  %s       : Stable\n", spaces(depth) );
+	break;
+      case T_FATE_NEWER:
+	printf( "  %s       : Newer\n", spaces(depth) );
+	break;
+      case T_FATE_ISTMP:
+	printf( "  %s       : Up to date temp file\n", spaces(depth) );
+      case T_FATE_NEEDTMP:
+	printf( "  %s       : Temporary file, to be updated\n", spaces(depth) );
+	break;
+      case T_FATE_TOUCHED:
+        printf( "  %s       : Been touched, updating it\n", spaces(depth) );
+	break;
+      case T_FATE_MISSING:
+	printf( "  %s       : Missing, creating it\n", spaces(depth) );
+	break;
+      case T_FATE_OUTDATED:
+	printf( "  %s       : Outdated, updating it\n", spaces(depth) );
+	break;
+      case T_FATE_UPDATE:
+	printf( "  %s       : Updating it\n", spaces(depth) );
+	break;
+      case T_FATE_CANTFIND:
+	printf( "  %s       : Can't find it\n", spaces(depth) );
+	break;
+      case T_FATE_CANTMAKE:
+	printf( "  %s       : Can't make it\n", spaces(depth) );
+	break;
+    }
+
+    if( t->flags & ~T_FLAG_VISITED )
+    {
+	printf( "  %s       : ", spaces(depth) );
+	if( t->flags & T_FLAG_TEMP ) printf ("TEMPORARY ");
+	if( t->flags & T_FLAG_NOCARE ) printf ("NOCARE ");
+	if( t->flags & T_FLAG_NOTFILE ) printf ("NOTFILE ");
+	if( t->flags & T_FLAG_TOUCHED ) printf ("TOUCHED ");
+	if( t->flags & T_FLAG_LEAVES ) printf ("LEAVES ");
+	if( t->flags & T_FLAG_NOUPDATE ) printf ("NOUPDATE ");
+	printf( "\n" );
+    }
+
+    for( c = t->depends; c; c = c->next )
+    {
+	printf( "  %s       : Depends on %s (%s)", spaces(depth),
+	       target_name(c->target), target_fate[ c->target->fate ] );
+    if (c->target->time == t->time)
+        printf( " (max time)");
+    printf("\n");
+    
+    }
+
+
+    for( c = t->depends; c; c = c->next )
+    {
+
+	dependGraphOutput( c->target, depth + 1 );
+    }
+}
+
+#endif
+/*
+ * make0sort() - reorder TARGETS chain by their time (newest to oldest)
+ */
+
+static TARGETS *
+make0sort( TARGETS *chain )
+{
+	TARGETS *result = 0;
+
+	/* We walk chain, taking each item and inserting it on the */
+	/* sorted result, with newest items at the front.  This involves */
+	/* updating each TARGETS' c->next and c->tail.  Note that we */
+	/* make c->tail a valid prev pointer for every entry.  Normally, */
+	/* it is only valid at the head, where prev == tail.  Note also */
+	/* that while tail is a loop, next ends at the end of the chain. */
+
+	/* Walk current target list */
+
+	while( chain )
+	{
+	    TARGETS *c = chain;
+	    TARGETS *s = result;
+
+	    chain = chain->next;
+
+	    /* Find point s in result for c */
+
+	    while( s && s->target->time > c->target->time )
+		s = s->next;
+
+	    /* Insert c in front of s (might be 0). */
+	    /* Don't even think of deciphering this. */
+
+	    c->next = s;			/* good even if s = 0 */
+	    if( result == s ) result = c;	/* new head of chain? */
+	    if( !s ) s = result;		/* wrap to ensure a next */
+	    if( result != c ) s->tail->next = c; /* not head? be prev's next */
+	    c->tail = s->tail;			/* take on next's prev */
+	    s->tail = c;			/* make next's prev us */
+	}
+
+	return result;
+}
+
+static LIST *targets_to_update_ = 0;
+
+void mark_target_for_updating(char *target)
+{
+    targets_to_update_ = list_new( targets_to_update_, target );
+}
+
+LIST *targets_to_update()
+{
+    return targets_to_update_;
+}
+
+void clear_targets_to_update()
+{
+    list_free(targets_to_update_);
+    targets_to_update_ = 0;
+}

Added: boost-jam/boost-build/branches/upstream/current/jam_src/make.h
===================================================================
--- boost-jam/boost-build/branches/upstream/current/jam_src/make.h	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/jam_src/make.h	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,41 @@
+/*
+ * Copyright 1993, 1995 Christopher Seiwald.
+ *
+ * This file is part of Jam - see jam.c for Copyright information.
+ */
+
+/*
+ * make.h - bring a target up to date, once rules are in place
+ */
+
+#include "lists.h"
+
+int make( int n_targets, const char **targets, int anyhow );
+int make1( TARGET *t );
+
+typedef struct {
+	int	temp;
+	int	updating;
+	int	cantfind;
+	int	cantmake;
+	int	targets;
+	int	made;
+} COUNTS ;
+
+
+void make0( TARGET *t, TARGET  *p, int depth, 
+            COUNTS *counts, int anyhow );
+
+
+/*
+ * Specifies that the target should be updated.
+ */
+void mark_target_for_updating(char *target);
+/* 
+ * Returns the list of all the target previously passed to 'mark_target_for_updating'.
+ */
+LIST *targets_to_update();
+/*
+ * Cleasr/unmarks all targets that are currently marked for update.
+ */
+void clear_targets_to_update();

Added: boost-jam/boost-build/branches/upstream/current/jam_src/make1.c
===================================================================
--- boost-jam/boost-build/branches/upstream/current/jam_src/make1.c	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/jam_src/make1.c	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,1046 @@
+/*
+ * Copyright 1993-2002 Christopher Seiwald and Perforce Software, Inc.
+ *
+ * This file is part of Jam - see jam.c for Copyright information.
+ */
+
+/*  This file is ALSO:
+ *  Copyright 2001-2004 David Abrahams.
+ *  Distributed under the Boost Software License, Version 1.0.
+ *  (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+ */
+
+/*
+ * make1.c - execute command to bring targets up to date
+ *
+ * This module contains make1(), the entry point called by make() to 
+ * recursively decend the dependency graph executing update actions as
+ * marked by make0().
+ *
+ * External routines:
+ *
+ *	make1() - execute commands to update a TARGET and all its dependents
+ *
+ * Internal routines, the recursive/asynchronous command executors:
+ *
+ *	make1a() - recursively traverse target tree, calling make1b()
+ *	make1b() - dependents of target built, now build target with make1c()
+ *	make1c() - launch target's next command, call make1b() when done
+ *	make1d() - handle command execution completion and call back make1c()
+ *
+ * Internal support routines:
+ *
+ *	make1cmds() - turn ACTIONS into CMDs, grouping, splitting, etc
+ *	make1list() - turn a list of targets into a LIST, for $(<) and $(>)
+ * 	make1settings() - for vars that get bound values, build up replacement lists
+ * 	make1bind() - bind targets that weren't bound in dependency analysis
+ *
+ * 04/16/94 (seiwald) - Split from make.c.
+ * 04/21/94 (seiwald) - Handle empty "updated" actions.
+ * 05/04/94 (seiwald) - async multiprocess (-j) support
+ * 06/01/94 (seiwald) - new 'actions existing' does existing sources
+ * 12/20/94 (seiwald) - NOTIME renamed NOTFILE.
+ * 01/19/95 (seiwald) - distinguish between CANTFIND/CANTMAKE targets.
+ * 01/22/94 (seiwald) - pass per-target JAMSHELL down to execcmd().
+ * 02/28/95 (seiwald) - Handle empty "existing" actions.
+ * 03/10/95 (seiwald) - Fancy counts.
+ */
+
+# include "jam.h"
+
+# include "lists.h"
+# include "parse.h"
+# include "assert.h"
+# include "variable.h"
+# include "rules.h"
+# include "headers.h"
+
+# include "search.h"
+# include "newstr.h"
+# include "make.h"
+# include "command.h"
+# include "execcmd.h"
+
+#if defined(sun) || defined(__sun)
+#include <unistd.h> /* for unlink */
+#endif
+
+static CMD *make1cmds( TARGET *t );
+static LIST *make1list( LIST *l, TARGETS *targets, int flags );
+static SETTINGS *make1settings( LIST *vars );
+static void make1bind( TARGET *t, int warn );
+
+/* Ugly static - it's too hard to carry it through the callbacks. */
+
+static struct {
+	int	failed;
+	int	skipped;
+	int	total;
+	int	made;
+} counts[1] ;
+
+/*
+ * Target state - remove recursive calls by just keeping track of state target is in
+ */
+typedef struct _state
+{
+  struct _state *prev; /* previous state on stack */
+  TARGET *t; /* current target */
+  TARGET *parent; /* parent argument necessary for make1a() */
+#define T_STATE_MAKE1A 0 /* make1a() should be called */
+#define T_STATE_MAKE1ATAIL 1 /* make1atail() should be called */
+#define T_STATE_MAKE1B 2 /* make1b() should be called */
+#define T_STATE_MAKE1C 3 /* make1c() should be called */
+#define T_STATE_MAKE1D 4 /* make1d() should be called */
+  int curstate; /* current state */
+  int status;
+} state;
+
+static void make1a( state *pState);
+static void make1atail(state *pState);
+static void make1b( state *pState );
+static void make1c( state *pState );
+static void make1d( state *pState );
+static void make_closure(void *closure, int status);
+
+typedef struct _stack
+{
+	state *stack;
+} stack;
+
+static stack state_stack = { NULL };
+
+static state *state_freelist = NULL;
+
+static state *alloc_state()
+{
+	if(state_freelist != NULL)
+	{
+		state *pState;
+
+		pState = state_freelist;
+		state_freelist = pState->prev;
+		memset(pState, 0, sizeof(state));
+		return pState;
+	}
+	else
+	{
+		return (state *)malloc(sizeof(state));
+	}
+}
+
+static void free_state(state *pState)
+{
+	pState->prev = state_freelist;
+	state_freelist = pState;
+}
+
+static void clear_state_freelist()
+{
+	while(state_freelist != NULL)
+	{
+		state *pState = state_freelist;
+		state_freelist = state_freelist->prev;
+		free(pState);
+	}
+}
+
+static state *current_state(stack *pStack)
+{
+	return pStack->stack;
+}
+
+static void pop_state(stack *pStack)
+{
+	state *pState;
+
+	if(pStack->stack != NULL)
+	{
+		pState = pStack->stack->prev;
+		free_state(pStack->stack);
+		pStack->stack = pState;
+	}
+}
+
+static state *push_state(stack *pStack, TARGET *t, TARGET *parent, int curstate)
+{
+	state *pState;
+
+	pState = alloc_state();
+
+	pState->t = t;
+	pState->parent = parent;
+	pState->prev = pStack->stack;
+	pState->curstate = curstate;
+
+	pStack->stack = pState;
+
+	return pStack->stack;
+}
+
+/* pushes a stack onto another stack, effectively reversing the order */
+static void push_stack_on_stack(stack *pDest, stack *pSrc)
+{
+	while(pSrc->stack != NULL)
+	{
+		state *pState;
+
+		pState = pSrc->stack;
+		pSrc->stack = pSrc->stack->prev;
+		pState->prev = pDest->stack;
+		pDest->stack = pState;
+	}
+}
+
+/*
+ * make1() - execute commands to update a TARGET and all its dependents
+ */
+
+static int intr = 0;
+
+int
+make1( TARGET *t )
+{
+	state *pState;
+
+	memset( (char *)counts, 0, sizeof( *counts ) );
+
+	/* Recursively make the target and its dependents */
+	push_state(&state_stack, t, NULL, T_STATE_MAKE1A);
+
+	do
+	{
+		while((pState = current_state(&state_stack)) != NULL)
+		{
+            if (intr) 
+                pop_state(&state_stack);
+
+			switch(pState->curstate)
+			{
+			case T_STATE_MAKE1A:
+				make1a(pState);
+				break;
+			case T_STATE_MAKE1ATAIL:
+				make1atail(pState);
+				break;
+			case T_STATE_MAKE1B:
+				make1b(pState);
+				break;
+			case T_STATE_MAKE1C:
+				make1c(pState);
+				break;
+			case T_STATE_MAKE1D:
+				make1d(pState);
+				break;
+			default:
+				break;
+			}
+		}
+	
+
+	/* Wait for any outstanding commands to finish running. */
+	} while( execwait() );
+
+	clear_state_freelist();
+
+	/* Talk about it */
+	if( counts->failed )
+	    printf( "...failed updating %d target%s...\n", counts->failed,
+		        counts->failed > 1 ? "s" : "" );
+
+	if( DEBUG_MAKE && counts->skipped )
+	    printf( "...skipped %d target%s...\n", counts->skipped,
+		        counts->skipped > 1 ? "s" : "" );
+
+	if( DEBUG_MAKE && counts->made )
+	    printf( "...updated %d target%s...\n", counts->made,
+		        counts->made > 1 ? "s" : "" );
+
+	return counts->total != counts->made;
+}
+
+/*
+ * make1a() - recursively traverse target tree, calling make1b()
+ */
+
+static void
+make1a( state *pState)
+{
+    TARGET* t = pState->t;
+	TARGETS	*c;
+    TARGETS   *inc;
+
+	/* If the parent is the first to try to build this target */
+	/* or this target is in the make1c() quagmire, arrange for the */
+	/* parent to be notified when this target is built. */
+
+	if( pState->parent )
+	    switch( pState->t->progress )
+	{
+	case T_MAKE_INIT:
+	case T_MAKE_ACTIVE:
+	case T_MAKE_RUNNING:
+	    pState->t->parents = targetentry( pState->t->parents, pState->parent );
+	    pState->parent->asynccnt++;
+	}
+
+	if( pState->t->progress != T_MAKE_INIT )
+	{
+		pop_state(&state_stack);
+		return;
+	}
+
+	/* Asynccnt counts the dependents preventing this target from */
+	/* proceeding to make1b() for actual building.  We start off with */
+	/* a count of 1 to prevent anything from happening until we can */
+	/* call all dependents.  This 1 is accounted for when we call */
+	/* make1b() ourselves, below. */
+
+	pState->t->asynccnt = 1;
+
+    /* Add header node that was created during building process. */
+
+    inc = 0;
+    for (c = t->depends; c; c = c->next) {        
+        if (c->target->rescanned && c->target->includes)
+            inc = targetentry(inc, c->target->includes);           
+    }
+    t->depends = targetchain(t->depends, inc);
+
+	/* against circular dependency. */
+
+	pState->t->progress = T_MAKE_ONSTACK;
+
+	{
+		stack temp_stack = { NULL };
+        for( c = t->depends; c && !intr; c = c->next )            
+            push_state(&temp_stack, c->target, pState->t, T_STATE_MAKE1A);
+
+		/* using stacks reverses the order of execution. Reverse it back */
+		push_stack_on_stack(&state_stack, &temp_stack);
+	}
+
+	pState->curstate = T_STATE_MAKE1ATAIL;
+}
+
+static void make1atail(state *pState)
+{
+	pState->t->progress = T_MAKE_ACTIVE;
+
+	/* Now that all dependents have bumped asynccnt, we now allow */
+	/* decrement our reference to asynccnt. */ 
+	pState->curstate = T_STATE_MAKE1B;
+}
+
+/*
+ * make1b() - dependents of target built, now build target with make1c()
+ */
+
+static void
+make1b( state *pState )
+{
+    TARGET      *t = pState->t;
+    TARGETS     *c;
+    TARGET      *failed = 0;
+    char* failed_name = "dependencies";
+
+    /* If any dependents are still outstanding, wait until they */
+    /* call make1b() to signal their completion. */
+
+    if( --(pState->t->asynccnt) )
+	{
+		pop_state(&state_stack);
+		return;
+	}
+    
+    /* Try to aquire a semaphore. If it's locked, wait until the target
+       that locked it is build and signals completition. */
+#ifdef OPT_SEMAPHORE
+	if( t->semaphore && t->semaphore->asynccnt )
+	{
+        /* Append 't' to the list of targets waiting on semaphore. */
+	    t->semaphore->parents = targetentry( t->semaphore->parents, t );
+	    t->asynccnt++;
+
+	    if( DEBUG_EXECCMD )
+		printf( "SEM: %s is busy, delaying launch of %s\n",
+			t->semaphore->name, t->name);
+		pop_state(&state_stack);
+	    return;
+	}
+#endif
+
+
+    /* Now ready to build target 't'... if dependents built ok. */
+
+    /* Collect status from dependents */
+
+
+    for( c = t->depends; c; c = c->next )
+        if( c->target->status > t->status && !( c->target->flags & T_FLAG_NOCARE ))
+        {
+            failed = c->target;
+            pState->t->status = c->target->status;
+        }
+    /* If a internal header node failed to build, we'd want to output the 
+       target that it failed on. */
+    if (failed && (failed->flags & T_FLAG_INTERNAL)) {
+        failed_name = failed->failed;
+    } else if (failed) {
+        failed_name = failed->name;
+    }
+    t->failed = failed_name;
+
+    /* If actions on deps have failed, bail. */
+    /* Otherwise, execute all actions to make target */
+
+    if( pState->t->status == EXEC_CMD_FAIL && pState->t->actions )
+    {
+        ++counts->skipped;
+        if ( ( pState->t->flags & ( T_FLAG_RMOLD | T_FLAG_NOTFILE ) ) == T_FLAG_RMOLD )
+        {
+            if( !unlink( pState->t->boundname ) )
+                printf( "...removing outdated %s\n", pState->t->boundname );
+        }
+        else {
+            printf( "...skipped %s for lack of %s...\n", pState->t->name, failed_name );
+        }
+    }
+
+    if( pState->t->status == EXEC_CMD_OK )
+        switch( pState->t->fate )
+        {
+        case T_FATE_INIT:
+        case T_FATE_MAKING:
+            /* shouldn't happen */
+
+        case T_FATE_STABLE:
+        case T_FATE_NEWER:
+            break;
+
+        case T_FATE_CANTFIND:
+        case T_FATE_CANTMAKE:
+            pState->t->status = EXEC_CMD_FAIL;
+            break;
+
+        case T_FATE_ISTMP:
+            if( DEBUG_MAKE )
+                printf( "...using %s...\n", pState->t->name );
+            break;
+
+        case T_FATE_TOUCHED:
+        case T_FATE_MISSING:
+        case T_FATE_NEEDTMP:
+        case T_FATE_OUTDATED:
+        case T_FATE_UPDATE:
+
+            /* Set "on target" vars, build actions, unset vars */
+            /* Set "progress" so that make1c() counts this target among */
+            /* the successes/failures. */
+
+            if( pState->t->actions )
+            {
+                ++counts->total;
+                if( DEBUG_MAKE && !( counts->total % 100 ) )
+                    printf( "...on %dth target...\n", counts->total );
+
+                pState->t->cmds = (char *)make1cmds( pState->t );
+                pState->t->progress = T_MAKE_RUNNING;
+            }
+
+            break;
+        }
+
+		/* Call make1c() to begin the execution of the chain of commands */
+		/* needed to build target.  If we're not going to build target */
+		/* (because of dependency failures or because no commands need to */
+		/* be run) the chain will be empty and make1c() will directly */
+		/* signal the completion of target. */
+
+	/* Recurse on our dependents, manipulating progress to guard */
+
+#ifdef OPT_SEMAPHORE
+	/* If there is a semaphore, indicate that its in use */
+	if( pState->t->semaphore )
+	{
+	    ++(pState->t->semaphore->asynccnt);
+
+	    if( DEBUG_EXECCMD )
+		printf( "SEM: %s now used by %s\n", pState->t->semaphore->name,
+		       pState->t->name );
+	}
+#endif
+
+	pState->curstate = T_STATE_MAKE1C;
+}
+
+/*
+ * make1c() - launch target's next command, call make1b() when done
+ */
+
+static void
+make1c( state *pState )
+{
+	CMD	*cmd = (CMD *)pState->t->cmds;
+
+	/* If there are (more) commands to run to build this target */
+	/* (and we haven't hit an error running earlier comands) we */
+	/* launch the command with execcmd(). */
+	
+	/* If there are no more commands to run, we collect the status */
+	/* from all the actions then report our completion to all the */
+	/* parents. */
+
+	if( cmd && pState->t->status == EXEC_CMD_OK )
+	{
+		if( DEBUG_MAKEQ || 
+            ! ( cmd->rule->actions->flags & RULE_QUIETLY ) && DEBUG_MAKE)
+	    {
+		printf( "%s ", cmd->rule->name );
+		list_print( lol_get( &cmd->args, 0 ) );
+		printf( "\n" );
+	    }
+
+	    if( DEBUG_EXEC )
+		printf( "%s\n", cmd->buf );
+
+	    if( globs.cmdout )
+		fprintf( globs.cmdout, "%s", cmd->buf );
+
+	    if( globs.noexec )
+	    {
+			pState->curstate = T_STATE_MAKE1D;
+			pState->status = EXEC_CMD_OK;
+	    } 
+	    else
+	    {
+			TARGET *t = pState->t;
+			fflush( stdout );
+
+			pop_state(&state_stack); /* pop state first because execcmd could push state */
+			execcmd( cmd->buf, make_closure, t, cmd->shell );
+	    }
+	}
+	else
+	{
+	    TARGETS	*c;
+	    ACTIONS	*actions;
+
+	    /* Collect status from actions, and distribute it as well */
+
+	    for( actions = pState->t->actions; actions; actions = actions->next )
+		if( actions->action->status > pState->t->status )
+		    pState->t->status = actions->action->status;
+
+	    for( actions = pState->t->actions; actions; actions = actions->next )
+		if( pState->t->status > actions->action->status )
+		    actions->action->status = pState->t->status;
+
+	    /* Tally success/failure for those we tried to update. */
+
+	    if( pState->t->progress == T_MAKE_RUNNING )
+		switch( pState->t->status )
+	    {
+	    case EXEC_CMD_OK:
+		++counts->made;
+		break;
+	    case EXEC_CMD_FAIL:
+		++counts->failed;
+		break;
+	    }
+
+	    /* Tell parents dependent has been built */
+		{
+			stack temp_stack = { NULL };
+			TARGET *t = pState->t;            
+            TARGET* additional_includes = NULL;
+
+			t->progress = T_MAKE_DONE;
+
+            /* Target was updated. Rescan dependencies. */
+            if (t->fate >= T_FATE_MISSING &&
+                t->status == EXEC_CMD_OK &&
+                !t->rescanned) {
+
+                TARGET *target_to_rescan = t;
+                SETTINGS *s;               
+
+                target_to_rescan->rescanned = 1;
+
+                if (target_to_rescan->flags & T_FLAG_INTERNAL) {
+                    target_to_rescan = t->original_target;                    
+                }
+
+                /* Clean current includes */
+                if (target_to_rescan->includes) {
+                    target_to_rescan->includes = 0;
+                }
+
+                s = copysettings( target_to_rescan->settings );
+                pushsettings( s );
+                headers(target_to_rescan);
+                popsettings( s );
+                freesettings( s );
+
+                if (target_to_rescan->includes) {
+                    target_to_rescan->includes->rescanned = 1;
+                    /* Tricky. The parents were already processed, but they
+                       did not seen the internal node, because it was just 
+                       created. We need to make the calls to make1a that would
+                       have been done by parents here, and also make sure all
+                       unprocessed parents will pick up the includes. We must
+                       make sure processing of the additional make1a invocations
+                       is done before make1b which means this target is built,
+                       otherwise the parent will be considered built before this
+                       make1a processing is even started.
+                    */
+                    make0(target_to_rescan->includes, target_to_rescan->parents->target, 0, 0, 0);
+                    for( c = target_to_rescan->parents; c; c = c->next) {
+                        c->target->depends = targetentry( c->target->depends, 
+                                                          target_to_rescan->includes );
+                    }
+                    /* Will be processed below. */
+                    additional_includes = target_to_rescan->includes;
+                }                
+            }
+
+            if (additional_includes)
+                for ( c = t->parents; c; c = c->next ) {                            
+                    push_state(&temp_stack, additional_includes, c->target, T_STATE_MAKE1A);
+                    
+                }
+
+			for( c = t->parents; c; c = c->next ) {
+				push_state(&temp_stack, c->target, NULL, T_STATE_MAKE1B);
+            }
+             
+
+
+#ifdef OPT_SEMAPHORE
+	    /* If there is a semaphore, its now free */
+	    if( t->semaphore )
+	    {
+		assert( t->semaphore->asynccnt == 1 );
+		--(t->semaphore->asynccnt);
+
+		if( DEBUG_EXECCMD )
+		    printf( "SEM: %s is now free\n", t->semaphore->name);
+
+		/* If anything is waiting, notify the next target. There's no
+            point in notifying all waiting targets, since they'll be
+            serialized again. */
+		if( t->semaphore->parents )
+		{
+		    TARGETS *first = t->semaphore->parents;
+		    if( first->next )
+			first->next->tail = first->tail;
+		    t->semaphore->parents = first->next;
+
+		    if( DEBUG_EXECCMD )
+			printf( "SEM: placing %s on stack\n", first->target->name);
+            push_state(&temp_stack, first->target, NULL, T_STATE_MAKE1B);
+		    free( first );
+		}
+	    }
+#endif
+
+		
+			/* must pop state before pushing any more */
+			pop_state(&state_stack);
+		
+			/* using stacks reverses the order of execution. Reverse it back */
+			push_stack_on_stack(&state_stack, &temp_stack);
+
+		}
+	}
+}
+
+static void make_closure(void *closure, int status)
+{
+	push_state(&state_stack, (TARGET *)closure, NULL, T_STATE_MAKE1D)->status = status;
+}
+
+/*
+ * make1d() - handle command execution completion and call back make1c()
+ */
+
+static void
+make1d(state *pState)
+{
+	TARGET	*t = pState->t;
+	CMD	*cmd = (CMD *)t->cmds;
+	int status = pState->status;
+
+	/* Execcmd() has completed.  All we need to do is fiddle with the */
+	/* status and signal our completion so make1c() can run the next */
+	/* command.  On interrupts, we bail heavily. */
+
+        if ( t->flags & T_FLAG_FAIL_EXPECTED )
+        {
+          /* invert execution result when FAIL_EXPECTED was applied */
+          switch (status)
+          {
+            case EXEC_CMD_FAIL: status = EXEC_CMD_OK; break;
+            case EXEC_CMD_OK:   status = EXEC_CMD_FAIL; break;
+            default:
+              ;
+          }
+        }
+        
+	if( status == EXEC_CMD_FAIL && ( cmd->rule->actions->flags & RULE_IGNORE ) )
+	    status = EXEC_CMD_OK;
+
+	/* On interrupt, set intr so _everything_ fails */
+
+	if( status == EXEC_CMD_INTR )
+	    ++intr;
+
+	if( status == EXEC_CMD_FAIL && DEBUG_MAKE )
+	{
+	    /* Print command text on failure */
+
+	    if( !DEBUG_EXEC )
+		printf( "%s\n", cmd->buf );
+
+	    printf( "...failed %s ", cmd->rule->name );
+	    list_print( lol_get( &cmd->args, 0 ) );
+	    printf( "...\n" );
+	}
+
+	if (status == EXEC_CMD_FAIL)
+		if( globs.quitquick ) ++intr;
+
+	/* If the command was interrupted or failed and the target */
+	/* is not "precious", remove the targets */
+
+	if( status != EXEC_CMD_OK && !( cmd->rule->actions->flags & RULE_TOGETHER ) )
+	{
+	    LIST *targets = lol_get( &cmd->args, 0 );
+
+	    for( ; targets; targets = list_next( targets ) )
+		if( !unlink( targets->string ) )
+		    printf( "...removing %s\n", targets->string );
+	}
+
+	/* Free this command and call make1c() to move onto next command. */
+
+	t->status = status;
+	t->cmds = (char *)cmd_next( cmd );
+
+	cmd_free( cmd );
+
+	pState->curstate = T_STATE_MAKE1C;
+}
+
+/*
+ * swap_settings() - replace the settings from the current module and
+ *                   target with those from the new module and target
+ */
+static void swap_settings(
+    module_t** current_module
+    , TARGET** current_target
+    , module_t* new_module
+    , TARGET* new_target)
+{
+    if (new_module == root_module())
+        new_module = 0;
+    
+    if (new_target == *current_target && new_module == *current_module)
+        return;
+
+    if (*current_target)
+        popsettings( (*current_target)->settings );
+        
+    if (new_module != *current_module)
+    {
+        if (*current_module)
+            exit_module( *current_module );
+
+        *current_module = new_module;
+        
+        if (new_module)
+            enter_module( new_module );
+    }
+
+    *current_target = new_target;
+    if (new_target)
+        pushsettings( new_target->settings );
+}
+
+/*
+ * make1cmds() - turn ACTIONS into CMDs, grouping, splitting, etc
+ *
+ * Essentially copies a chain of ACTIONs to a chain of CMDs, 
+ * grouping RULE_TOGETHER actions, splitting RULE_PIECEMEAL actions,
+ * and handling RULE_NEWSRCS actions.  The result is a chain of
+ * CMDs which can be expanded by var_string() and executed with
+ * execcmd().
+ */
+
+static CMD *
+make1cmds( TARGET *t )
+{
+	CMD *cmds = 0;
+	LIST *shell = 0;
+        
+        module_t *settings_module = 0;
+        TARGET *settings_target = 0;
+        
+	/* Step through actions */
+	/* Actions may be shared with other targets or grouped with */
+	/* RULE_TOGETHER, so actions already seen are skipped. */
+        
+        ACTIONS* a0;
+	for(a0 = t->actions ; a0; a0 = a0->next )
+	{
+	    RULE    *rule = a0->action->rule;
+            rule_actions *actions = rule->actions;
+	    SETTINGS *boundvars;
+	    LIST    *nt, *ns;
+	    ACTIONS *a1;
+	    int	    start, chunk, length;
+
+	    /* Only do rules with commands to execute. */
+	    /* If this action has already been executed, use saved status */
+
+	    if( !actions || a0->action->running )
+		continue;
+
+	    a0->action->running = 1;
+	    
+	    /* Make LISTS of targets and sources */
+	    /* If `execute together` has been specified for this rule, tack */
+	    /* on sources from each instance of this rule for this target. */
+
+	    nt = make1list( L0, a0->action->targets, 0 );
+	    ns = make1list( L0, a0->action->sources, actions->flags );
+
+	    if( actions->flags & RULE_TOGETHER )
+		for( a1 = a0->next; a1; a1 = a1->next )
+		    if( a1->action->rule == rule && !a1->action->running )
+	    {
+		ns = make1list( ns, a1->action->sources, actions->flags );
+		a1->action->running = 1;
+	    }
+
+	    /* If doing only updated (or existing) sources, but none have */
+	    /* been updated (or exist), skip this action. */
+
+	    if( !ns && ( actions->flags & ( RULE_NEWSRCS | RULE_EXISTING ) ) )
+	    {
+		list_free( nt );
+		continue;
+	    }
+
+            swap_settings( &settings_module, &settings_target, rule->module, t );
+            if (!shell)
+                shell = var_get( "JAMSHELL" );	/* shell is per-target */
+                
+	    /* If we had 'actions xxx bind vars' we bind the vars now */
+
+	    boundvars = make1settings( actions->bindlist );
+	    pushsettings( boundvars );
+
+	    /*
+	     * Build command, starting with all source args. 
+	     *
+	     * If cmd_new returns 0, it's because the resulting command
+	     * length is > MAXLINE.  In this case, we'll slowly reduce
+	     * the number of source arguments presented until it does
+	     * fit.  This only applies to actions that allow PIECEMEAL 
+	     * commands.
+	     *
+	     * While reducing slowly takes a bit of compute time to get
+	     * things just right, it's worth it to get as close to MAXLINE
+	     * as possible, because launching the commands we're executing 
+	     * is likely to be much more compute intensive!
+	     *
+	     * Note we loop through at least once, for sourceless actions.
+	     */
+
+	    start = 0;
+	    chunk = length = list_length( ns );
+
+	    do
+	    {
+		/* Build cmd: cmd_new consumes its lists. */
+
+		CMD *cmd = cmd_new( rule, 
+			list_copy( L0, nt ), 
+			list_sublist( ns, start, chunk ),
+			list_copy( L0, shell ) );
+
+		if( cmd )
+		{
+		    /* It fit: chain it up. */
+
+		    if( !cmds ) cmds = cmd;
+		    else cmds->tail->next = cmd;
+		    cmds->tail = cmd;
+		    start += chunk;
+		}
+		else if( ( actions->flags & RULE_PIECEMEAL ) && chunk > 1 )
+		{
+		    /* Reduce chunk size slowly. */
+
+		    chunk = chunk * 9 / 10;
+		}
+		else
+		{
+		    /* Too long and not splittable. */
+
+		    printf( "%s actions too long (max %d):\n", 
+			rule->name, MAXLINE );
+
+                    /* Tell the user what didn't fit */
+                    cmd = cmd_new(
+                        rule, list_copy( L0, nt ), 
+			list_sublist( ns, start, chunk ),
+			list_new( L0, newstr( "%" ) ) );
+
+                    printf( cmd->buf );
+                
+		    exit( EXITBAD );
+		}
+	    }
+	    while( start < length );
+
+	    /* These were always copied when used. */
+
+	    list_free( nt );
+	    list_free( ns );
+
+	    /* Free the variables whose values were bound by */
+	    /* 'actions xxx bind vars' */
+
+	    popsettings( boundvars );
+	    freesettings( boundvars );
+	}
+
+        swap_settings( &settings_module, &settings_target, 0, 0 );
+	return cmds;
+}
+
+/*
+ * make1list() - turn a list of targets into a LIST, for $(<) and $(>)
+ */
+
+static LIST *
+make1list( 
+	LIST	*l,
+	TARGETS	*targets,
+	int	flags )
+{
+    for( ; targets; targets = targets->next )
+    {
+	TARGET *t = targets->target;
+
+	/* Sources to 'actions existing' are never in the dependency */
+	/* graph (if they were, they'd get built and 'existing' would */
+	/* be superfluous, so throttle warning message about independent */
+	/* targets. */
+
+	if( t->binding == T_BIND_UNBOUND )
+	    make1bind( t, !( flags & RULE_EXISTING ) );
+
+    if ( ( flags & RULE_EXISTING ) && ( flags & RULE_NEWSRCS ) )
+    {
+        if ( t->binding != T_BIND_EXISTS && t->fate <= T_FATE_STABLE)
+            continue;
+    }
+    else
+    { 
+        if( ( flags & RULE_EXISTING ) && t->binding != T_BIND_EXISTS )
+            continue;
+
+        if( ( flags & RULE_NEWSRCS ) && t->fate <= T_FATE_STABLE )
+            continue;
+    }
+
+	/* Prohibit duplicates for RULE_TOGETHER */
+
+	if( flags & RULE_TOGETHER )
+	{
+	    LIST *m;
+
+	    for( m = l; m; m = m->next )
+		if( !strcmp( m->string, t->boundname ) )
+		    break;
+
+	    if( m )
+		continue;
+	}
+
+	/* Build new list */
+
+	l = list_new( l, copystr( t->boundname ) );
+    }
+
+    return l;
+}
+
+/*
+ * make1settings() - for vars that get bound values, build up replacement lists
+ */
+
+static SETTINGS *
+make1settings( LIST *vars )
+{
+	SETTINGS *settings = 0;
+
+	for( ; vars; vars = list_next( vars ) )
+	{
+	    LIST *l = var_get( vars->string );
+	    LIST *nl = 0;
+
+	    for( ; l; l = list_next( l ) ) 
+	    {
+		TARGET *t = bindtarget( l->string );
+
+		/* Make sure the target is bound, warning if it is not in the */
+		/* dependency graph. */
+
+		if( t->binding == T_BIND_UNBOUND )
+		    make1bind( t, 1 );
+
+		/* Build new list */
+
+		nl = list_new( nl, copystr( t->boundname ) );
+	    }
+
+	    /* Add to settings chain */
+
+	    settings = addsettings( settings, 0, vars->string, nl );
+	}
+
+	return settings;
+}
+
+/*
+ * make1bind() - bind targets that weren't bound in dependency analysis
+ *
+ * Spot the kludge!  If a target is not in the dependency tree, it didn't 
+ * get bound by make0(), so we have to do it here.  Ugly.
+ */
+
+static void
+make1bind( 
+	TARGET	*t,
+	int	warn )
+{
+	if( t->flags & T_FLAG_NOTFILE )
+	    return;
+
+	/* Sources to 'actions existing' are never in the dependency */
+	/* graph (if they were, they'd get built and 'existing' would */
+	/* be superfluous, so throttle warning message about independent */
+	/* targets. */
+
+	if( warn )
+	    printf( "warning: using independent target %s\n", t->name );
+
+	pushsettings( t->settings );
+	t->boundname = search( t->name, &t->time, 0 );
+	t->binding = t->time ? T_BIND_EXISTS : T_BIND_MISSING;
+	popsettings( t->settings );
+}

Added: boost-jam/boost-build/branches/upstream/current/jam_src/mkjambase.c
===================================================================
--- boost-jam/boost-build/branches/upstream/current/jam_src/mkjambase.c	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/jam_src/mkjambase.c	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,131 @@
+/*
+ * Copyright 1993, 1995 Christopher Seiwald.
+ *
+ * This file is part of Jam - see jam.c for Copyright information.
+ */
+
+/*  This file is ALSO:
+ *  Copyright 2001-2004 David Abrahams.
+ *  Distributed under the Boost Software License, Version 1.0.
+ *  (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+ */
+
+/*
+ * mkjambase.c - turn Jambase into a big C structure
+ *
+ * Usage: mkjambase jambase.c Jambase ...
+ *
+ * Results look like this:
+ *
+ *	 char *jambase[] = {
+ *	 "...\n",
+ *	 ...
+ *	 0 };
+ *
+ * Handles \'s and "'s specially; knows to delete blank and comment lines.
+ *
+ */
+
+# include <stdio.h>
+# include <string.h>
+
+int main( int argc, char **argv, char **envp )
+{
+	char buf[ 1024 ];
+	FILE *fin;
+	FILE *fout;
+	char *p;
+	int doDotC = 0;
+
+	if( argc < 3 )
+	{
+	    fprintf( stderr, "usage: %s jambase.c Jambase ...\n", argv[0] );
+	    return -1;
+	}
+
+	if( !( fout = fopen( argv[1], "w" ) ) )
+	{
+	    perror( argv[1] );
+	    return -1;
+	}
+
+	/* If the file ends in .c generate a C source file */
+
+	if( ( p = strrchr( argv[1], '.' ) ) && !strcmp( p, ".c" ) )
+	    doDotC++;
+
+	/* Now process the files */
+
+	argc -= 2, argv += 2;
+
+	if( doDotC )
+	{
+	    fprintf( fout, "/* Generated by mkjambase from Jambase */\n" );
+	    fprintf( fout, "char *jambase[] = {\n" );
+	}
+
+	for( ; argc--; argv++ )
+	{
+	    if( !( fin = fopen( *argv, "r" ) ) )
+	    {
+		perror( *argv );
+		return -1;
+	    }
+
+	    if( doDotC )
+	    {
+		fprintf( fout, "/* %s */\n", *argv );
+	    }
+	    else
+	    {
+		fprintf( fout, "### %s ###\n", *argv );
+	    }
+
+	    while( fgets( buf, sizeof( buf ), fin ) )
+	    {
+		if( doDotC )
+		{
+		    char *p = buf;
+
+		    /* Strip leading whitespace. */
+
+		    while( *p == ' ' || *p == '\t' || *p == '\n' )
+			p++;
+
+		    /* Drop comments and empty lines. */
+
+		    if( *p == '#' || !*p )
+			continue;
+
+		    /* Copy */
+
+		    putc( '"', fout );
+
+		    for( ; *p && *p != '\n'; p++ )
+			switch( *p )
+		    {
+		    case '\\': putc( '\\', fout ); putc( '\\', fout ); break;
+		    case '"': putc( '\\', fout ); putc( '"', fout ); break;
+                    case '\r': break;
+		    default: putc( *p, fout ); break;
+		    }
+
+		    fprintf( fout, "\\n\",\n" );
+		}
+		else
+		{
+		    fprintf( fout, "%s", buf );
+		}
+
+	    }
+
+	    fclose( fin );
+	}
+	    
+	if( doDotC )
+	    fprintf( fout, "0 };\n" );
+
+	fclose( fout );
+
+	return 0;
+}

Added: boost-jam/boost-build/branches/upstream/current/jam_src/modules/order.c
===================================================================
--- boost-jam/boost-build/branches/upstream/current/jam_src/modules/order.c	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/jam_src/modules/order.c	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,142 @@
+/* Copyright Vladimir Prus 2004. Distributed under the Boost */
+/* Software License, Version 1.0. (See accompanying */
+/* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */
+
+#include "../native.h"
+#include "../lists.h"
+#include "../strings.h"
+#include "../newstr.h"
+#include "../variable.h"
+
+
+/* Use quite klugy approach: when we add order dependency from 'a' to 'b',
+   just append 'b' to of value of variable 'a'.
+*/
+LIST *add_pair( PARSE *parse, FRAME *frame )
+{
+    LIST* arg = lol_get( frame->args, 0 );    
+
+    var_set(arg->string, list_copy(0, arg->next), VAR_APPEND);
+
+    return L0;
+}
+
+/** Given a list and a value, returns position of that value in
+    the list, or -1 if not found.
+*/
+int list_index(LIST* list, const char* value)
+{
+    int result = 0;
+    for(; list; list = list->next, ++result) {
+        if (strcmp(list->string, value) == 0)
+            return result;
+    }
+    return -1;
+}
+
+enum colors { white, gray, black };
+
+/* Main routite of topological sort. Calls itself recursively on all
+   adjacent vertices which were not yet visited. After that, 'current_vertex'
+   is added to '*result_ptr'.
+*/
+void do_ts(int** graph, int current_vertex, int* colors, int** result_ptr)
+{
+    int i;
+
+    colors[current_vertex] = gray;
+    for(i = 0; graph[current_vertex][i] != -1; ++i) {
+        int adjacent_vertex = graph[current_vertex][i];
+
+        if (colors[adjacent_vertex] == white)
+            do_ts(graph, adjacent_vertex, colors, result_ptr);
+        else if (colors[adjacent_vertex] == gray)
+            ; /* This is loop. Not sure what to do... */
+    }
+    colors[current_vertex] = black;
+    **result_ptr = current_vertex;    
+    (*result_ptr)++;
+}
+
+void topological_sort(int** graph, int num_vertices, int* result)
+{
+    int i;
+    int* colors = (int*)calloc(num_vertices, sizeof(int));
+    for (i = 0; i < num_vertices; ++i)
+        colors[i] = white;
+
+    for(i = 0; i < num_vertices; ++i)
+        if (colors[i] == white)
+            do_ts(graph, i, colors, &result);
+
+    free(colors);
+}
+
+LIST *order( PARSE *parse, FRAME *frame )
+{
+    LIST* arg = lol_get( frame->args, 0 );  
+    LIST* tmp;
+    LIST* result = 0;
+    int src, dst;
+
+    /* We need to create a graph of order dependencies between
+       the passed objects. We assume that there are no duplicates
+       passed to 'add_pair'.
+    */
+    int length = list_length(arg);
+    int** graph = (int**)calloc(length, sizeof(int*));
+    int* order = (int*)malloc((length+1)*sizeof(int));
+   
+    for(tmp = arg, src = 0; tmp; tmp = tmp->next, ++src) {
+        /* For all object this one depend upon, add elements
+           to 'graph' */
+        LIST* dependencies = var_get(tmp->string);
+        int index = 0;
+
+        graph[src] = (int*)calloc(list_length(dependencies)+1, sizeof(int));
+        for(; dependencies; dependencies = dependencies->next) {          
+            int dst = list_index(arg, dependencies->string);
+            if (dst != -1)
+                graph[src][index++] = dst;
+        }
+        graph[src][index] = -1;               
+    }
+
+    topological_sort(graph, length, order);
+
+    {
+        int index = length-1;
+        for(; index >= 0; --index) {
+            int i;
+            tmp = arg;
+            for (i = 0; i < order[index]; ++i, tmp = tmp->next);
+            result = list_new(result, tmp->string);
+        }
+    }
+
+    /* Clean up */
+    {
+        int i;
+        for(i = 0; i < length; ++i)
+            free(graph[i]);
+        free(graph);
+        free(order);
+    }
+
+    return result;
+}
+
+void init_order()
+{
+    {
+        char* args[] = { "first", "second", 0 };
+        declare_native_rule("class at order", "add-pair", args, add_pair);
+    }
+
+    {
+        char* args[] = { "objects", "*", 0 };
+        declare_native_rule("class at order", "order", args, order);
+    }
+
+
+}

Added: boost-jam/boost-build/branches/upstream/current/jam_src/modules/path.c
===================================================================
--- boost-jam/boost-build/branches/upstream/current/jam_src/modules/path.c	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/jam_src/modules/path.c	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,32 @@
+/* Copyright Vladimir Prus 2003. Distributed under the Boost */
+/* Software License, Version 1.0. (See accompanying */
+/* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */
+
+#include "../native.h"
+#include "../timestamp.h"
+#include "../newstr.h"
+
+LIST *path_exists( PARSE *parse, FRAME *frame )
+{
+    LIST* l = lol_get( frame->args, 0 );    
+
+    time_t time;
+    timestamp(l->string, &time);
+    if (time != 0)
+    {
+        return list_new(0, newstr("true"));
+    }
+    else
+    {
+        return L0;
+    }
+}
+
+void init_path()
+{
+    {
+        char* args[] = { "location", 0 };
+        declare_native_rule("path", "exists", args, path_exists);
+    }
+
+}

Added: boost-jam/boost-build/branches/upstream/current/jam_src/modules/property-set.c
===================================================================
--- boost-jam/boost-build/branches/upstream/current/jam_src/modules/property-set.c	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/jam_src/modules/property-set.c	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,109 @@
+/* Copyright Vladimir Prus 2003. Distributed under the Boost */
+/* Software License, Version 1.0. (See accompanying */
+/* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */
+
+#include "../native.h"
+#include "../timestamp.h"
+#include "../newstr.h"
+#include "../strings.h"
+#include "../lists.h"
+#include "../variable.h"
+#include "../compile.h"
+
+LIST* get_grist(char* f)
+{
+    char* end = strchr(f, '>');
+    string s[1];
+    LIST* result;
+    
+    string_new(s);
+
+    string_append_range(s, f, end+1);
+    result = list_new(0, newstr(s->value));
+        
+    string_free(s);
+    return result;
+}
+
+/*
+rule create ( raw-properties * )
+{
+    raw-properties = [ sequence.unique 
+        [ sequence.insertion-sort $(raw-properties) ] ] ;
+         
+    local key = $(raw-properties:J=-:E=) ;
+    
+    if ! $(.ps.$(key)) 
+    {
+        .ps.$(key) = [ new property-set $(raw-properties) ] ;
+    }
+    return $(.ps.$(key)) ;    
+}
+*/
+
+LIST *property_set_create( PARSE *parse, FRAME *frame )
+{
+    LIST* properties = lol_get( frame->args, 0 );    
+    LIST* sorted = 0;
+    LIST* order_sensitive = 0;
+    LIST* unique;
+    LIST* tmp;
+    LIST* val;
+    string var[1];
+
+#if 0
+    /* Sort all properties which are not order sensitive */
+    for(tmp = properties; tmp; tmp = tmp->next) {
+        LIST* g = get_grist(tmp->string);
+        LIST* att = call_rule("feature.attributes", frame, g, 0);
+        if (list_in(att, "order-sensitive")) {
+            order_sensitive = list_new( order_sensitive, tmp->string);
+        } else {
+            sorted = list_new( sorted, tmp->string);
+        }
+        list_free(att);
+    }
+    
+    sorted = list_sort(sorted);
+    sorted = list_append(sorted, order_sensitive);
+    unique = list_unique(sorted);
+#endif
+    sorted = list_sort(properties);
+    unique = list_unique(sorted);
+
+    string_new(var);
+    string_append(var, ".ps.");
+    
+    for(tmp = unique; tmp; tmp = tmp->next) {
+        string_append(var, tmp->string);
+        string_push_back(var, '-');
+    }
+    val = var_get(var->value);
+    if (val == 0) 
+    {          
+        val = call_rule("new", frame, 
+                        list_append(list_new(0, "property-set"), unique), 0);                
+        
+        var_set(newstr(var->value), list_copy(0, val), VAR_SET);
+    }
+    else
+    {
+        val = list_copy(0, val);
+    }
+    
+    string_free(var);
+    /* The 'unique' variable is freed in 'call_rule'. */
+    list_free(sorted);
+
+    return val;
+
+}
+
+void init_property_set()
+{
+    {
+        char* args[] = { "raw-properties", "*", 0 };
+        declare_native_rule("property-set", "create", args, property_set_create);
+    }
+
+}

Added: boost-jam/boost-build/branches/upstream/current/jam_src/modules/readme.txt
===================================================================
--- boost-jam/boost-build/branches/upstream/current/jam_src/modules/readme.txt	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/jam_src/modules/readme.txt	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,3 @@
+
+This directory constains sources which declare native
+rules for Boost.Build modules.
\ No newline at end of file

Added: boost-jam/boost-build/branches/upstream/current/jam_src/modules/regex.c
===================================================================
--- boost-jam/boost-build/branches/upstream/current/jam_src/modules/regex.c	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/jam_src/modules/regex.c	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,65 @@
+/* Copyright Vladimir Prus 2003. Distributed under the Boost */
+/* Software License, Version 1.0. (See accompanying */
+/* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */
+
+#include "../native.h"
+#include "../timestamp.h"
+#include "../newstr.h"
+#include "../strings.h"
+#include "../regexp.h"
+#include "../compile.h"
+
+/*
+rule transform ( list * : pattern )
+{
+    local result ;
+    for local e in $(list)
+    {
+        local m = [ MATCH $(pattern) : $(e) ] ;
+        if $(m)
+        {
+            result += $(m[1]) ;
+        }        
+    }
+    return $(result) ;
+}
+*/
+LIST *regex_transform( PARSE *parse, FRAME *frame )
+{
+    LIST* l = lol_get( frame->args, 0 );    
+    LIST* pattern = lol_get( frame->args, 1 );    
+    LIST* result = 0;
+
+    string buf[1];
+    string_new(buf);
+
+
+    /* Result is cached and intentionally never freed */
+    {
+        regexp *re = regex_compile( pattern->string );
+
+        for(; l; l = l->next)
+        {
+            if( regexec( re, l->string ) )
+            {
+                if (re->startp[1])
+                {
+                    string_append_range( buf, re->startp[1], re->endp[1] );
+                    result = list_new( result, newstr( buf->value ) );                
+                    string_truncate( buf, 0 );
+                }
+            }
+        }
+        string_free( buf );
+    }
+    
+    return result;
+}
+
+void init_regex()
+{
+    {
+        char* args[] = { "list", "*", ":", "pattern", 0 };
+        declare_native_rule("regex", "transform", args, regex_transform);
+    }
+}

Added: boost-jam/boost-build/branches/upstream/current/jam_src/modules/sequence.c
===================================================================
--- boost-jam/boost-build/branches/upstream/current/jam_src/modules/sequence.c	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/jam_src/modules/sequence.c	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,42 @@
+/* Copyright Vladimir Prus 2003. Distributed under the Boost */
+/* Software License, Version 1.0. (See accompanying */
+/* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */
+
+#include "../native.h"
+
+# ifndef max
+# define max( a,b ) ((a)>(b)?(a):(b))
+# endif
+
+
+LIST *sequence_select_highest_ranked( PARSE *parse, FRAME *frame )
+{
+   /* Returns all of 'elements' for which corresponding element in parallel */
+   /* list 'rank' is equal to the maximum value in 'rank'.                  */
+
+    LIST* elements = lol_get( frame->args, 0 );    
+    LIST* rank = lol_get( frame->args, 1 );    
+    
+    LIST* result = 0;
+    LIST* tmp;
+    int highest_rank = -1;
+
+    for (tmp = rank; tmp; tmp = tmp->next)
+        highest_rank = max(highest_rank, atoi(tmp->string));
+
+    for (; rank; rank = rank->next, elements = elements->next)
+        if (atoi(rank->string) == highest_rank)
+            result = list_new(result, elements->string);
+
+    return result;
+}
+
+void init_sequence()
+{
+    {
+        char* args[] = { "elements", "*", ":", "rank", "*", 0 };
+        declare_native_rule("sequence", "select-highest-ranked", args, 
+                            sequence_select_highest_ranked);
+    }
+
+}

Added: boost-jam/boost-build/branches/upstream/current/jam_src/modules/set.c
===================================================================
--- boost-jam/boost-build/branches/upstream/current/jam_src/modules/set.c	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/jam_src/modules/set.c	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,41 @@
+/* Copyright Vladimir Prus 2003. Distributed under the Boost */
+/* Software License, Version 1.0. (See accompanying */
+/* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */
+
+#include "../native.h"
+
+/*
+    local result = ;
+    local element ;
+    for element in $(B)
+    {
+        if ! ( $(element) in $(A) )
+        {
+            result += $(element) ;
+        }
+    }
+    return $(result) ;
+*/
+LIST *set_difference( PARSE *parse, FRAME *frame )
+{
+
+    LIST* b = lol_get( frame->args, 0 );    
+    LIST* a = lol_get( frame->args, 1 );    
+
+    LIST* result = 0;
+    for(; b; b = b->next)
+    {
+        if (!list_in(a, b->string))
+            result = list_new(result, b->string);
+    }
+    return result;
+}
+
+void init_set()
+{
+    {
+        char* args[] = { "B", "*", ":", "A", "*", 0 };
+        declare_native_rule("set", "difference", args, set_difference);
+    }
+
+}

Added: boost-jam/boost-build/branches/upstream/current/jam_src/modules.c
===================================================================
--- boost-jam/boost-build/branches/upstream/current/jam_src/modules.c	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/jam_src/modules.c	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,150 @@
+/*
+ *  Copyright 2001-2004 David Abrahams.
+ *  Distributed under the Boost Software License, Version 1.0.
+ *  (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+ */
+#include "modules.h"
+#include "jam.h"
+#include "string.h"
+#include "hash.h"
+#include "newstr.h"
+#include "lists.h"
+#include "parse.h"
+#include "rules.h"
+#include "variable.h"
+#include "strings.h"
+#include <assert.h>
+
+static struct hash* module_hash = 0;
+
+static char* new_module_str( module_t* m, char* suffix )
+{
+    char* result;
+    string s;
+    string_copy( &s, m->name );
+    string_append( &s, suffix );
+    result = newstr( s.value );
+    string_free( &s );
+    return result;
+}
+
+module_t* bindmodule( char* name )
+{
+    string s;
+    module_t m_, *m = &m_;
+
+    if( !module_hash )
+        module_hash = hashinit( sizeof( module_t ), "modules" );
+
+    string_new( &s );
+    if (name)
+    {
+        string_append( &s, name );
+        string_push_back( &s, '.' );
+    }
+        
+    m->name = s.value;
+    
+    if ( hashenter( module_hash, (HASHDATA **)&m ) )
+    {
+        m->name = newstr( m->name );
+        m->variables = 0;
+        m->rules = 0;
+        m->imported_modules = 0;
+        m->class_module = 0;
+        m->native_rules = 0;
+    }
+    string_free( &s );
+    return m;
+}
+
+/*
+ * demand_rules() - Get the module's "rules" hash on demand
+ */
+struct hash* demand_rules( module_t* m )
+{
+    if ( !m->rules )
+        m->rules = hashinit( sizeof( RULE ), new_module_str( m, "rules" ) );
+    return m->rules;
+}
+
+/*
+ * delete_module() - wipe out the module's rules and variables
+ */
+static void delete_rule_( void* xrule, void* data )
+{
+    rule_free( (RULE*)xrule );
+}
+
+void delete_module( module_t* m )
+{
+    /* clear out all the rules */
+    if ( m->rules )
+    {
+        hashenumerate( m->rules, delete_rule_, (void*)0 );
+        hashdone( m->rules );
+        m->rules = 0;
+    }
+
+    if ( m->variables )
+    {
+        var_hash_swap( &m->variables );
+        var_done();
+        var_hash_swap( &m->variables );
+        m->variables = 0;
+    }
+}
+
+module_t* root_module()
+{
+    static module_t* root = 0;
+    if ( !root )
+        root = bindmodule(0);
+    return root;
+}
+
+void enter_module( module_t* m )
+{
+    var_hash_swap( &m->variables );
+}
+
+void exit_module( module_t* m )
+{
+    var_hash_swap( &m->variables );
+}
+
+void import_module(LIST* module_names, module_t* target_module)
+{ 
+    struct hash* h;
+
+    if (!target_module->imported_modules)
+        target_module->imported_modules = hashinit( sizeof(char*), "imported");
+    h = target_module->imported_modules;
+
+    for(;module_names; module_names = module_names->next) {
+        
+        char* s = module_names->string;
+        char** ss = &s;
+        
+        hashenter(h, (HASHDATA**)&ss);
+    }
+}
+
+static void add_module_name( void* r_, void* result_ )
+{
+    char** r = (char**)r_;
+    LIST** result = (LIST**)result_;
+
+    *result = list_new( *result, copystr( *r ) );
+}
+
+LIST* imported_modules(module_t* module)
+{
+    LIST *result = L0;
+
+    if ( module->imported_modules )
+        hashenumerate( module->imported_modules, add_module_name, &result );
+
+    return result;
+}
+

Added: boost-jam/boost-build/branches/upstream/current/jam_src/modules.h
===================================================================
--- boost-jam/boost-build/branches/upstream/current/jam_src/modules.h	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/jam_src/modules.h	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,37 @@
+/*
+ *  Copyright 2001-2004 David Abrahams.
+ *  Distributed under the Boost Software License, Version 1.0.
+ *  (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+ */
+#ifndef MODULES_DWA10182001_H
+# define MODULES_DWA10182001_H
+
+#include "lists.h"
+
+struct module_t
+{
+    char* name;
+    struct hash* rules;
+    struct hash* variables;
+    struct hash* imported_modules;
+    struct module_t* class_module;
+    struct hash* native_rules;
+};
+
+typedef struct module_t module_t ; /* MSVC debugger gets confused unless this is provided */
+
+module_t* bindmodule( char* name );
+module_t* root_module();
+void bind_module_var( module_t*, char* name );
+void enter_module( module_t* );
+void exit_module( module_t* );
+void delete_module( module_t* );
+
+void import_module(LIST* module_names, module_t* target_module);
+LIST* imported_modules(module_t* module);
+
+struct hash* demand_rules( module_t* );
+
+
+#endif
+

Added: boost-jam/boost-build/branches/upstream/current/jam_src/native.c
===================================================================
--- boost-jam/boost-build/branches/upstream/current/jam_src/native.c	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/jam_src/native.c	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,37 @@
+/* Copyright Vladimir Prus 2003. Distributed under the Boost */
+/* Software License, Version 1.0. (See accompanying */
+/* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */
+
+#include "native.h"
+#include "hash.h"
+
+# define P0 (PARSE *)0
+# define C0 (char *)0
+
+
+void declare_native_rule(char* module, char* rule, char** args, 
+                         LIST*(*f)(PARSE*, FRAME*))
+
+{
+    module_t* m = bindmodule(module);
+    if (m->native_rules == 0) {
+        m->native_rules = hashinit( sizeof( native_rule_t ), "native rules");
+    }
+    
+    {
+        native_rule_t n, *np = &n;
+        n.name = rule;
+        if (args)
+        {
+            n.arguments = args_new();
+            lol_build( n.arguments->data, args );
+        }   
+        else
+        {
+            n.arguments = 0;
+        }
+        n.procedure = parse_make( f, P0, P0, P0, C0, C0, 0 );        
+        hashenter(m->native_rules, (HASHDATA**)&np);
+    }
+}
+

Added: boost-jam/boost-build/branches/upstream/current/jam_src/native.h
===================================================================
--- boost-jam/boost-build/branches/upstream/current/jam_src/native.h	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/jam_src/native.h	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,25 @@
+/* Copyright David Abrahams 2003. Distributed under the Boost */
+/* Software License, Version 1.0. (See accompanying */
+/* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */
+
+#ifndef NATIVE_H_VP_2003_12_09
+#define NATIVE_H_VP_2003_12_09
+
+#include "rules.h"
+
+struct native_rule_t
+{
+    char* name;
+    argument_list* arguments;
+    PARSE* procedure;
+};
+
+/* MSVC debugger gets confused unless this is provided */
+typedef struct native_rule_t native_rule_t ; 
+
+void declare_native_rule(char* module, char* rule, char** args, 
+                         LIST*(*f)(PARSE*, FRAME*));
+
+
+
+#endif

Added: boost-jam/boost-build/branches/upstream/current/jam_src/newstr.c
===================================================================
--- boost-jam/boost-build/branches/upstream/current/jam_src/newstr.c	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/jam_src/newstr.c	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,158 @@
+/*
+ * Copyright 1993, 1995 Christopher Seiwald.
+ *
+ * This file is part of Jam - see jam.c for Copyright information.
+ */
+
+# include "jam.h"
+# include "newstr.h"
+# include "hash.h"
+# include <stddef.h>
+# include <stdlib.h>
+
+/*
+ * newstr.c - string manipulation routines
+ *
+ * To minimize string copying, string creation, copying, and freeing
+ * is done through newstr.
+ *
+ * External functions:
+ *
+ *    newstr() - return a dynamically allocated copy of a string
+ *    copystr() - return a copy of a string previously returned by newstr()
+ *    freestr() - free a string returned by newstr() or copystr()
+ *    donestr() - free string tables
+ *
+ * Once a string is passed to newstr(), the returned string is readonly.
+ *
+ * This implementation builds a hash table of all strings, so that multiple 
+ * calls of newstr() on the same string allocate memory for the string once.
+ * Strings are never actually freed.
+ */
+
+typedef char *STRING;
+
+static struct hash *strhash = 0;
+static int strtotal = 0;
+
+/*
+ * Immortal string allocator implementation speeds string allocation
+ * and cuts down on internal fragmentation
+ */
+
+# define STRING_BLOCK 4096
+typedef struct strblock
+{
+    struct strblock* next;
+    char data[STRING_BLOCK];
+} strblock;
+
+static strblock* strblock_chain = 0;
+
+/* Storage remaining in the current strblock */
+static char* storage_start = 0;
+static char* storage_finish = 0;
+
+/*
+ * allocate() - Allocate n bytes of immortal string storage
+ */
+static char* allocate(size_t n)
+{
+    /* See if we can grab storage from an existing block */
+    size_t remaining = storage_finish - storage_start;
+    if ( remaining >= n )
+    {
+        char* result = storage_start;
+        storage_start += n;
+        return result;
+    }
+    else /* Must allocate a new block */
+    {
+        strblock* new_block;
+        size_t nalloc = n;
+        if ( nalloc < STRING_BLOCK )
+            nalloc = STRING_BLOCK;
+
+        /* allocate a new block and link into the chain */
+        new_block = (strblock*)malloc( offsetof( strblock, data[0] ) + nalloc * sizeof(new_block->data[0]) );
+        if ( new_block == 0 )
+            return 0;
+        new_block->next = strblock_chain;
+        strblock_chain = new_block;
+
+        /* Take future allocations out of the larger remaining space */
+        if ( remaining < nalloc - n )
+        {
+            storage_start = new_block->data + n;
+            storage_finish = new_block->data + nalloc;
+        }
+        return new_block->data;
+    }
+}
+
+/*
+ * newstr() - return a dynamically allocated copy of a string
+ */
+
+char *
+newstr( char *string )
+{
+	STRING str, *s = &str;
+
+	if( !strhash )
+	    strhash = hashinit( sizeof( STRING ), "strings" );
+
+	*s = string;
+
+	if( hashenter( strhash, (HASHDATA **)&s ) )
+	{
+	    int l = strlen( string );
+	    char *m = (char *)allocate( l + 1 );
+
+	    strtotal += l + 1;
+	    memcpy( m, string, l + 1 );
+	    *s = m;
+	}
+
+	return *s;
+}
+
+/*
+ * copystr() - return a copy of a string previously returned by newstr()
+ */
+
+char *
+copystr( char *s )
+{
+	return s;
+}
+
+/*
+ * freestr() - free a string returned by newstr() or copystr()
+ */
+
+void
+freestr( char *s )
+{
+}
+
+/*
+ * donestr() - free string tables
+ */
+
+void
+donestr()
+{
+    /* Reclaim string blocks */
+    while ( strblock_chain != 0 )
+    {
+        strblock* n = strblock_chain->next;
+        free(strblock_chain);
+        strblock_chain = n;
+    }
+    
+    hashdone( strhash );
+    
+    if( DEBUG_MEM )
+        printf( "%dK in strings\n", strtotal / 1024 );
+}

Added: boost-jam/boost-build/branches/upstream/current/jam_src/newstr.h
===================================================================
--- boost-jam/boost-build/branches/upstream/current/jam_src/newstr.h	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/jam_src/newstr.h	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,14 @@
+/*
+ * Copyright 1993, 1995 Christopher Seiwald.
+ *
+ * This file is part of Jam - see jam.c for Copyright information.
+ */
+
+/*
+ * newstr.h - string manipulation routines
+ */
+
+char *newstr( char *string );
+char *copystr( char *s );
+void freestr( char *s );
+void donestr();

Added: boost-jam/boost-build/branches/upstream/current/jam_src/option.c
===================================================================
--- boost-jam/boost-build/branches/upstream/current/jam_src/option.c	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/jam_src/option.c	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,103 @@
+/*
+ * Copyright 1993, 1995 Christopher Seiwald.
+ *
+ * This file is part of Jam - see jam.c for Copyright information.
+ */
+
+# include "jam.h"
+# include "option.h"
+
+/*
+ * option.c - command line option processing
+ *
+ * {o >o
+ *  \<>) "Process command line options as defined in <option.h>.
+ *		  Return the number of argv[] elements used up by options,
+ *		  or -1 if an invalid option flag was given or an argument
+ *		  was supplied for an option that does not require one."
+ */
+
+int
+getoptions(
+    int argc,
+    char **argv,
+    char *opts,
+    option *optv )
+{
+    int i;
+    int optc = N_OPTS;
+
+    memset( (char *)optv, '\0', sizeof( *optv ) * N_OPTS );
+
+    for( i = 0; i < argc; i++ )
+    {
+	char *arg;
+
+	if( argv[i][0] != '-' || ( argv[i][1] != '-' && !isalpha( argv[i][1] ) ) )
+	    break;
+
+	if( !optc-- )
+	{
+	    printf( "too many options (%d max)\n", N_OPTS );
+	    return -1;
+	}
+
+	for( arg = &argv[i][1]; *arg; arg++ )
+	{
+	    char *f;
+
+	    for( f = opts; *f; f++ )
+		if( *f == *arg )
+		    break;
+
+	    if( !*f )
+	    {
+		printf( "Invalid option: -%c\n", *arg );
+		return -1;
+	    }
+
+	    optv->flag = *f;
+
+	    if( f[1] != ':' )
+	    {
+		optv++->val = "true";
+	    }
+	    else if( arg[1] )
+	    {
+		optv++->val = &arg[1];
+		break;
+	    }
+	    else if( ++i < argc )
+	    {
+		optv++->val = argv[i];
+		break;
+	    }
+	    else
+	    {
+		printf( "option: -%c needs argument\n", *f );
+		return -1;
+	    }
+	}
+    }
+
+    return i;
+}
+
+/*
+ * Name: getoptval() - find an option given its character
+ */
+
+char *
+getoptval( 
+	option *optv,
+	char opt,
+	int subopt )
+{
+	int i;
+
+	for( i = 0; i < N_OPTS; i++, optv++ )
+	    if( optv->flag == opt && !subopt-- )
+		return optv->val;
+
+	return 0;
+}

Added: boost-jam/boost-build/branches/upstream/current/jam_src/option.h
===================================================================
--- boost-jam/boost-build/branches/upstream/current/jam_src/option.h	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/jam_src/option.h	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,23 @@
+/*
+ * Copyright 1993, 1995 Christopher Seiwald.
+ *
+ * This file is part of Jam - see jam.c for Copyright information.
+ */
+
+/*
+ * option.h - command line option processing
+ *
+ * {o >o
+ *  \ -) "Command line option."
+ */
+
+typedef struct option
+{
+	char	flag;		/* filled in by getoption() */
+	char	*val;		/* set to random address if true */
+} option;
+
+# define N_OPTS 256
+
+int 	getoptions( int argc, char **argv, char *opts, option *optv );
+char *	getoptval( option *optv, char opt, int subopt );

Added: boost-jam/boost-build/branches/upstream/current/jam_src/parse.c
===================================================================
--- boost-jam/boost-build/branches/upstream/current/jam_src/parse.c	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/jam_src/parse.c	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,137 @@
+/*
+ * Copyright 1993, 2000 Christopher Seiwald.
+ *
+ * This file is part of Jam - see jam.c for Copyright information.
+ */
+
+/*  This file is ALSO:
+ *  Copyright 2001-2004 David Abrahams.
+ *  Distributed under the Boost Software License, Version 1.0.
+ *  (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+ */
+
+# include "jam.h"
+# include "lists.h"
+# include "parse.h"
+# include "scan.h"
+# include "newstr.h"
+# include "modules.h"
+# include "frames.h"
+
+/*
+ * parse.c - make and destroy parse trees as driven by the parser
+ *
+ * 09/07/00 (seiwald) - ref count on PARSE to avoid freeing when used,
+ *		as per Matt Armstrong.
+ * 09/11/00 (seiwald) - structure reworked to reflect that (*func)()
+ *		returns a LIST *.
+ */
+
+static PARSE *yypsave;
+
+void
+parse_file( char *f, FRAME* frame )
+{
+	/* Suspend scan of current file */
+	/* and push this new file in the stream */
+
+	yyfparse(f);
+
+	/* Now parse each block of rules and execute it. */
+	/* Execute it outside of the parser so that recursive */
+	/* calls to yyrun() work (no recursive yyparse's). */
+
+	for(;;)
+	{
+	    PARSE *p;
+
+	    /* Filled by yyparse() calling parse_save() */
+
+	    yypsave = 0;
+
+	    /* If parse error or empty parse, outta here */
+
+	    if( yyparse() || !( p = yypsave ) )
+		break;
+
+	    /* Run the parse tree. */
+
+            parse_evaluate( p, frame );
+	    parse_free( p );
+	}
+}
+
+void
+parse_save( PARSE *p )
+{
+	yypsave = p;
+}
+
+PARSE *
+parse_make( 
+	LIST	*(*func)( PARSE *p, FRAME *args ),
+	PARSE	*left,
+	PARSE	*right,
+	PARSE	*third,
+	char	*string,
+	char	*string1,
+	int	num )
+{
+	PARSE	*p = (PARSE *)malloc( sizeof( PARSE ) );
+
+	p->func = func;
+	p->left = left;
+	p->right = right;
+	p->third = third;
+	p->string = string;
+	p->string1 = string1;
+	p->num = num;
+	p->refs = 1;
+        p->rulename = 0;
+        
+        if ( left )
+        {
+            p->file = left->file;
+            p->line = left->line;
+        }
+        else
+        {
+            yyinput_stream( &p->file, &p->line );
+        }
+
+	return p;
+}
+
+void
+parse_refer( PARSE *p )
+{
+	++p->refs;
+}
+
+void
+parse_free( PARSE *p )
+{
+	if( --p->refs )
+	    return;
+
+	if( p->string )
+	    freestr( p->string );
+	if( p->string1 )
+	    freestr( p->string1 );
+	if( p->left )
+	    parse_free( p->left );
+	if( p->right )
+	    parse_free( p->right );
+	if( p->third )
+	    parse_free( p->third );
+        if ( p->rulename )
+            freestr( p->rulename );
+	
+	free( (char *)p );
+}
+
+LIST* parse_evaluate( PARSE *p, FRAME* frame )
+{
+    frame->procedure = p;
+    return (*p->func)(p, frame);
+}

Added: boost-jam/boost-build/branches/upstream/current/jam_src/parse.h
===================================================================
--- boost-jam/boost-build/branches/upstream/current/jam_src/parse.h	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/jam_src/parse.h	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,59 @@
+/*
+ * Copyright 1993, 2000 Christopher Seiwald.
+ *
+ * This file is part of Jam - see jam.c for Copyright information.
+ */
+
+/*  This file is ALSO:
+ *  Copyright 2001-2004 David Abrahams.
+ *  Distributed under the Boost Software License, Version 1.0.
+ *  (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+ */
+
+#ifndef PARSE_DWA20011020_H
+# define PARSE_DWA20011020_H
+# include "frames.h"
+# include "modules.h"
+# include "lists.h"
+
+/*
+ * parse.h - make and destroy parse trees as driven by the parser
+ */
+
+/*
+ * parse tree node
+ */
+
+struct _PARSE {
+    LIST    *(*func)( PARSE *p, FRAME *frame );
+    PARSE   *left;
+    PARSE   *right;
+    PARSE   *third;
+    char    *string;
+    char    *string1;
+    int      num;
+    int      refs;
+/*    module*  module; */
+    char*    rulename;
+    char*    file;
+    int      line;
+} ;
+
+void    parse_file( char *f, FRAME* frame );
+void    parse_save( PARSE *p );
+
+PARSE * parse_make( 
+    LIST    *(*func)( PARSE *p, FRAME* frame ),
+    PARSE   *left,
+    PARSE   *right,
+    PARSE   *third,
+    char    *string,
+    char    *string1,
+    int      num );
+
+void    parse_refer( PARSE *p );
+void    parse_free( PARSE *p );
+LIST*   parse_evaluate( PARSE *p, FRAME* frame );
+
+#endif
+

Added: boost-jam/boost-build/branches/upstream/current/jam_src/patchlevel.h
===================================================================
--- boost-jam/boost-build/branches/upstream/current/jam_src/patchlevel.h	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/jam_src/patchlevel.h	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,5 @@
+/* Keep JAMVERSYM in sync with VERSION. */
+/* It can be accessed as $(JAMVERSION) in the Jamfile. */
+
+#define VERSION "3.1.10"
+#define JAMVERSYM "JAMVERSION=3.1"

Added: boost-jam/boost-build/branches/upstream/current/jam_src/pathmac.c
===================================================================
--- boost-jam/boost-build/branches/upstream/current/jam_src/pathmac.c	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/jam_src/pathmac.c	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,261 @@
+/*
+ * Copyright 1993-2002 Christopher Seiwald and Perforce Software, Inc.
+ *
+ * This file is part of Jam - see jam.c for Copyright information.
+ */
+
+/*  This file is ALSO:
+ *  Copyright 2001-2004 David Abrahams.
+ *  Distributed under the Boost Software License, Version 1.0.
+ *  (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+ */
+
+# include "jam.h"
+# include "pathsys.h"
+
+# ifdef OS_MAC
+
+# define DELIM ':'
+
+/*
+ * pathunix.c - manipulate file names on UNIX, NT, OS2
+ *
+ * External routines:
+ *
+ *	path_parse() - split a file name into dir/base/suffix/member
+ *	path_build() - build a filename given dir/base/suffix/member
+ *	path_parent() - make a PATHNAME point to its parent dir
+ *
+ * File_parse() and path_build() just manipuate a string and a structure;
+ * they do not make system calls.
+ *
+ * 04/08/94 (seiwald) - Coherent/386 support added.
+ * 12/26/93 (seiwald) - handle dir/.suffix properly in path_build()
+ * 12/19/94 (mikem) - solaris string table insanity support
+ * 12/21/94 (wingerd) Use backslashes for pathnames - the NT way.
+ * 02/14/95 (seiwald) - parse and build /xxx properly
+ * 02/23/95 (wingerd) Compilers on NT can handle "/" in pathnames, so we
+ *                    should expect hdr searches to come up with strings
+ *                    like "thing/thing.h". So we need to test for "/" as
+ *                    well as "\" when parsing pathnames.
+ * 03/16/95 (seiwald) - fixed accursed typo on line 69.
+ * 05/03/96 (seiwald) - split from filent.c, fileunix.c
+ * 12/20/96 (seiwald) - when looking for the rightmost . in a file name,
+ *		      don't include the archive member name.
+ * 01/10/01 (seiwald) - path_parse now strips the trailing : from the
+ *			directory name, unless the directory name is all
+ *			:'s, so that $(d:P) works.
+ */
+
+/*
+ * path_parse() - split a file name into dir/base/suffix/member
+ */
+
+void
+path_parse( 
+	char	*file,
+	PATHNAME *f )
+{
+	char *p, *q;
+	char *end;
+	
+	memset( (char *)f, 0, sizeof( *f ) );
+
+	/* Look for <grist> */
+
+	if( file[0] == '<' && ( p = strchr( file, '>' ) ) )
+	{
+	    f->f_grist.ptr = file;
+	    f->f_grist.len = p - file;
+	    file = p + 1;
+	}
+
+	/* Look for dir: */
+
+	if( p = strrchr( file, DELIM ) )
+	{
+	    f->f_dir.ptr = file;
+	    f->f_dir.len = p - file;
+	    file = p + 1;
+
+	    /* All :'s? Include last : as part of directory name */
+
+	    while( p > f->f_dir.ptr && *--p == DELIM )
+		;
+	    
+	    if( p == f->f_dir.ptr )
+	    f->f_dir.len++;
+	}
+
+	end = file + strlen( file );
+
+	/* Look for (member) */
+
+	if( ( p = strchr( file, '(' ) ) && end[-1] == ')' )
+	{
+	    f->f_member.ptr = p + 1;
+	    f->f_member.len = end - p - 2;
+	    end = p;
+	} 
+
+	/* Look for .suffix */
+	/* This would be memrchr() */
+
+	p = 0;
+	q = file;
+
+	while( q = memchr( q, '.', end - q ) )
+	    p = q++;
+
+	if( p )
+	{
+	    f->f_suffix.ptr = p;
+	    f->f_suffix.len = end - p;
+	    end = p;
+	}
+
+	/* Leaves base */
+
+	f->f_base.ptr = file;
+	f->f_base.len = end - file;
+}
+
+/*
+ * path_build() - build a filename given dir/base/suffix/member
+ */
+ 
+# define DIR_EMPTY	0	/* "" */
+# define DIR_DOT	1	/* : */
+# define DIR_DOTDOT	2	/* :: */
+# define DIR_ABS	3	/* dira:dirb: */
+# define DIR_REL	4	/* :dira:dirb: */
+
+# define G_DIR		0	/* take dir */
+# define G_ROOT		1	/* take root */
+# define G_CAT		2	/* prepend root to dir */
+# define G_DTDR		3	/* :: of rel dir */
+# define G_DDDD		4	/* make it ::: (../..) */
+# define G_MT		5	/* leave it empty */
+
+char grid[5][5] = {
+/* 		EMPTY	DOT	DOTDOT	ABS	REL */
+/* EMPTY */   {	G_MT,	G_DIR,	G_DIR,	G_DIR,	G_DIR },
+/* DOT */     {	G_ROOT,	G_DIR,	G_DIR,	G_DIR,	G_DIR },
+/* DOTDOT */  {	G_ROOT,	G_ROOT,	G_DDDD,	G_DIR,	G_DTDR },
+/* ABS */     {	G_ROOT,	G_ROOT, G_ROOT,	G_DIR,	G_CAT },
+/* REL */     {	G_ROOT,	G_ROOT,	G_ROOT,	G_DIR,	G_CAT }
+} ;
+
+static int
+file_flags( 
+	char	*ptr,
+	int	len )
+{
+	if( !len )
+	    return DIR_EMPTY;
+	if( len == 1 && ptr[0] == DELIM )
+	    return DIR_DOT;
+	if( len == 2 && ptr[0] == DELIM && ptr[1] == DELIM )
+	    return DIR_DOTDOT;
+	if( ptr[0] == DELIM )
+	    return DIR_REL;
+	return DIR_ABS;
+}
+
+void
+path_build(
+	PATHNAME *f,
+	string* file,
+	int	binding )
+{
+    int dflag, rflag, act;
+
+    file_build1( f, file );
+	
+    /* Combine root & directory, according to the grid. */
+	
+    dflag = file_flags( f->f_dir.ptr, f->f_dir.len );
+    rflag = file_flags( f->f_root.ptr, f->f_root.len );
+	
+    switch( act = grid[ rflag ][ dflag ] )
+    {
+    case G_DTDR:
+        {
+            /* :: of rel dir */
+            string_push_back( file, DELIM );
+        }
+        /* fall through */
+		
+    case G_DIR: 	
+        /* take dir */
+        string_append_range( file, f->f_dir.ptr, f->f_dir.ptr + f->f_dir.len  );
+        break;
+		
+    case G_ROOT:	
+        /* take root */
+        string_append_range( file, f->f_root.ptr, f->f_root.ptr + f->f_root.len  );
+        break;
+	    
+    case G_CAT:	
+        /* prepend root to dir */
+        string_append_range( file, f->f_root.ptr, f->f_root.ptr + f->f_root.len  );
+        if( file->value[file->size - 1] == DELIM )
+            string_pop_back( file );
+        string_append_range( file, f->f_dir.ptr, f->f_dir.ptr + f->f_dir.len  );
+        break;
+	
+    case G_DDDD:	
+        /* make it ::: (../..) */
+        string_append( file, ":::" );
+        break;
+    }
+
+    /* Put : between dir and file (if none already) */
+	
+    if( act != G_MT && 
+        file->value[file->size - 1] != DELIM && 
+        ( f->f_base.len || f->f_suffix.len ) )
+    {
+        string_push_back( file, DELIM );
+    }
+
+    if( f->f_base.len )
+    {
+        string_append_range( file, f->f_base.ptr, f->f_base.ptr + f->f_base.len  );
+    }
+
+    if( f->f_suffix.len )
+    {
+        string_append_range( file, f->f_suffix.ptr, f->f_suffix.ptr + f->f_suffix.len  );
+    }
+
+    if( f->f_member.len )
+    {
+        string_push_back( file, '(' );
+        string_append_range( file, f->f_member.ptr, f->f_member.ptr + f->f_member.len  );
+        string_push_back( file, ')' );
+    }
+	
+    if( DEBUG_SEARCH )
+        printf(" -> '%s'\n", file->value);
+}
+
+/*
+ *	path_parent() - make a PATHNAME point to its parent dir
+ */
+
+void
+path_parent( PATHNAME *f )
+{
+	/* just set everything else to nothing */
+
+	f->f_base.ptr =
+	f->f_suffix.ptr =
+	f->f_member.ptr = "";
+
+	f->f_base.len = 
+	f->f_suffix.len = 
+	f->f_member.len = 0;
+}
+
+# endif /* OS_MAC */

Added: boost-jam/boost-build/branches/upstream/current/jam_src/pathsys.h
===================================================================
--- boost-jam/boost-build/branches/upstream/current/jam_src/pathsys.h	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/jam_src/pathsys.h	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,66 @@
+/*
+ * Copyright 1993-2002 Christopher Seiwald and Perforce Software, Inc.
+ *
+ * This file is part of Jam - see jam.c for Copyright information.
+ */
+
+/*
+ * pathsys.h - PATHNAME struct 
+ */
+
+/*
+ * PATHNAME - a name of a file, broken into <grist>dir/base/suffix(member)
+ *
+ * <grist> is salt to distinguish between targets that otherwise would
+ * have the same name:  it never appears in the bound name of a target.
+ * (member) is an archive member name: the syntax is arbitrary, but must 
+ * agree in path_parse(), path_build() and the Jambase.
+ *
+ * On VMS, we keep track of whether the original path was a directory
+ * (without a file), so that $(VAR:D) can climb to the parent.
+ */
+
+#ifndef PATHSYS_VP_20020211_H
+# define PATHSYS_VP_20020211_H
+
+#include "strings.h"
+
+typedef struct _pathname PATHNAME;
+typedef struct _pathpart PATHPART;
+
+struct _pathpart {
+	char	*ptr;
+	int	len;
+};
+
+struct _pathname {
+	PATHPART	part[6];
+# ifdef OS_VMS
+	int		parent;
+# endif
+
+# define f_grist	part[0]
+# define f_root		part[1]
+# define f_dir		part[2]
+# define f_base		part[3]
+# define f_suffix	part[4]
+# define f_member	part[5]
+
+} ;
+
+void path_build( PATHNAME *f, string *file, int binding );
+void path_build1( PATHNAME *f, string *file );
+
+void path_parse( char *file, PATHNAME *f );
+void path_parent( PATHNAME *f );
+
+#ifdef NT
+
+/** Returns newstr-allocated string with long equivivalent of 'short_name'.
+    If none exists -- i.e. 'short_path' is already long path, it's returned
+    unaltered. */
+char* short_path_to_long_path(char* short_path);
+
+#endif
+
+#endif

Added: boost-jam/boost-build/branches/upstream/current/jam_src/pathunix.c
===================================================================
--- boost-jam/boost-build/branches/upstream/current/jam_src/pathunix.c	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/jam_src/pathunix.c	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,397 @@
+/*
+ * Copyright 1993-2002 Christopher Seiwald and Perforce Software, Inc.
+ *
+ * This file is part of Jam - see jam.c for Copyright information.
+ */
+
+/*  This file is ALSO:
+ *  Copyright 2001-2004 David Abrahams.
+ *  Distributed under the Boost Software License, Version 1.0.
+ *  (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+ */
+
+# include "jam.h"
+# include "pathsys.h"
+# include "strings.h"
+# include "newstr.h"
+# include "filesys.h"
+
+# ifdef USE_PATHUNIX
+
+/*
+ * pathunix.c - manipulate file names on UNIX, NT, OS2, AmigaOS
+ *
+ * External routines:
+ *
+ *	path_parse() - split a file name into dir/base/suffix/member
+ *	path_build() - build a filename given dir/base/suffix/member
+ *	path_parent() - make a PATHNAME point to its parent dir
+ *
+ * File_parse() and path_build() just manipuate a string and a structure;
+ * they do not make system calls.
+ *
+ * 04/08/94 (seiwald) - Coherent/386 support added.
+ * 12/26/93 (seiwald) - handle dir/.suffix properly in path_build()
+ * 12/19/94 (mikem) - solaris string table insanity support
+ * 12/21/94 (wingerd) Use backslashes for pathnames - the NT way.
+ * 02/14/95 (seiwald) - parse and build /xxx properly
+ * 02/23/95 (wingerd) Compilers on NT can handle "/" in pathnames, so we
+ *                    should expect hdr searches to come up with strings
+ *                    like "thing/thing.h". So we need to test for "/" as
+ *                    well as "\" when parsing pathnames.
+ * 03/16/95 (seiwald) - fixed accursed typo on line 69.
+ * 05/03/96 (seiwald) - split from filent.c, fileunix.c
+ * 12/20/96 (seiwald) - when looking for the rightmost . in a file name,
+ *		      don't include the archive member name.
+ * 01/13/01 (seiwald) - turn on \ handling on UNIX, on by accident
+ */
+
+/*
+ * path_parse() - split a file name into dir/base/suffix/member
+ */
+
+void
+path_parse( 
+	char	*file,
+	PATHNAME *f )
+{
+	char *p, *q;
+	char *end;
+	
+	memset( (char *)f, 0, sizeof( *f ) );
+
+	/* Look for <grist> */
+
+	if( file[0] == '<' && ( p = strchr( file, '>' ) ) )
+	{
+	    f->f_grist.ptr = file;
+	    f->f_grist.len = p - file;
+	    file = p + 1;
+	}
+
+	/* Look for dir/ */
+
+	p = strrchr( file, '/' );
+
+# if PATH_DELIM == '\\'
+	/* On NT, look for dir\ as well */
+	{
+	    char *p1 = strrchr( file, '\\' );
+	    p = p1 > p ? p1 : p;
+	}
+# endif
+
+	if( p )
+	{
+	    f->f_dir.ptr = file;
+	    f->f_dir.len = p - file;
+	
+	    /* Special case for / - dirname is /, not "" */
+
+	    if( !f->f_dir.len )
+		f->f_dir.len = 1;
+
+# if PATH_DELIM == '\\'
+	    /* Special case for D:/ - dirname is D:/, not "D:" */
+
+	    if( f->f_dir.len == 2 && file[1] == ':' )
+		f->f_dir.len = 3;
+# endif
+
+	    file = p + 1;
+	}
+
+	end = file + strlen( file );
+
+	/* Look for (member) */
+
+	if( ( p = strchr( file, '(' ) ) && end[-1] == ')' )
+	{
+	    f->f_member.ptr = p + 1;
+	    f->f_member.len = end - p - 2;
+	    end = p;
+	} 
+
+	/* Look for .suffix */
+	/* This would be memrchr() */
+
+	p = 0;
+	q = file;
+
+	while( q = (char *)memchr( q, '.', end - q ) )
+	    p = q++;
+
+	if( p )
+	{
+	    f->f_suffix.ptr = p;
+	    f->f_suffix.len = end - p;
+	    end = p;
+	}
+
+	/* Leaves base */
+
+	f->f_base.ptr = file;
+	f->f_base.len = end - file;
+}
+
+/*
+ * path_delims - the string of legal path delimiters
+ */
+static char path_delims[] = {
+    PATH_DELIM,
+#  if PATH_DELIM == '\\'
+    '/',
+#  endif
+    0
+};
+
+/*
+ * is_path_delim() - true iff c is a path delimiter
+ */
+static int is_path_delim( char c )
+{
+    char* p = strchr( path_delims, c );
+    return p && *p;
+}
+
+/*
+ * as_path_delim() - convert c to a path delimiter if it isn't one
+ * already
+ */
+static char as_path_delim( char c )
+{
+    return is_path_delim( c ) ? c : PATH_DELIM;
+}
+
+/*
+ * path_build() - build a filename given dir/base/suffix/member
+ *
+ * To avoid changing slash direction on NT when reconstituting paths,
+ * instead of unconditionally appending PATH_DELIM we check the
+ * past-the-end character of the previous path element.  If it is in
+ * path_delims, we append that, and only append PATH_DELIM as a last
+ * resort.  This heuristic is based on the fact that PATHNAME objects
+ * are usually the result of calling path_parse, which leaves the
+ * original slashes in the past-the-end position. Correctness depends
+ * on the assumption that all strings are zero terminated, so a
+ * past-the-end character will always be available.
+ *
+ * As an attendant patch, we had to ensure that backslashes are used
+ * explicitly in timestamp.c
+ */
+
+void
+path_build(
+	PATHNAME *f,
+	string	*file,
+	int	binding )
+{
+    file_build1( f, file );
+    
+    /* Don't prepend root if it's . or directory is rooted */
+# if PATH_DELIM == '/'
+
+    if( f->f_root.len 
+        && !( f->f_root.len == 1 && f->f_root.ptr[0] == '.' )
+        && !( f->f_dir.len && f->f_dir.ptr[0] == '/' ) )
+
+# else /* unix */
+
+    if( f->f_root.len 
+        && !( f->f_root.len == 1 && f->f_root.ptr[0] == '.' )
+        && !( f->f_dir.len && f->f_dir.ptr[0] == '/' )
+        && !( f->f_dir.len && f->f_dir.ptr[0] == '\\' )
+        && !( f->f_dir.len && f->f_dir.ptr[1] == ':' ) )
+
+# endif /* unix */
+
+    {
+        string_append_range( file, f->f_root.ptr, f->f_root.ptr + f->f_root.len  );
+        /* If 'root' already ends with path delimeter, 
+           don't add yet another one. */
+        if( ! is_path_delim( f->f_root.ptr[f->f_root.len-1] ) )
+            string_push_back( file, as_path_delim( f->f_root.ptr[f->f_root.len] ) );
+    }
+
+    if( f->f_dir.len )
+    {
+        string_append_range( file, f->f_dir.ptr, f->f_dir.ptr + f->f_dir.len  );
+    }
+
+    /* UNIX: Put / between dir and file */
+    /* NT:   Put \ between dir and file */
+
+    if( f->f_dir.len && ( f->f_base.len || f->f_suffix.len ) )
+    {
+        /* UNIX: Special case for dir \ : don't add another \ */
+        /* NT:   Special case for dir / : don't add another / */
+
+# if PATH_DELIM == '\\'
+        if( !( f->f_dir.len == 3 && f->f_dir.ptr[1] == ':' ) )
+# endif
+            if( !( f->f_dir.len == 1 && is_path_delim( f->f_dir.ptr[0] ) ) )
+                string_push_back( file, as_path_delim( f->f_dir.ptr[f->f_dir.len] ) );
+    }
+
+    if( f->f_base.len )
+    {
+        string_append_range( file, f->f_base.ptr, f->f_base.ptr + f->f_base.len  );
+    }
+
+    if( f->f_suffix.len )
+    {
+        string_append_range( file, f->f_suffix.ptr, f->f_suffix.ptr + f->f_suffix.len  );
+    }
+
+    if( f->f_member.len )
+    {
+        string_push_back( file, '(' );
+        string_append_range( file, f->f_member.ptr, f->f_member.ptr + f->f_member.len  );
+        string_push_back( file, ')' );
+    }
+}
+
+/*
+ *	path_parent() - make a PATHNAME point to its parent dir
+ */
+
+void
+path_parent( PATHNAME *f )
+{
+	/* just set everything else to nothing */
+
+	f->f_base.ptr =
+	f->f_suffix.ptr =
+	f->f_member.ptr = "";
+
+	f->f_base.len = 
+	f->f_suffix.len = 
+	f->f_member.len = 0;
+}
+
+#ifdef NT
+#include <windows.h>
+#include <tchar.h>
+
+/* The definition of this in winnt.h is not ANSI-C compatible. */
+#undef INVALID_FILE_ATTRIBUTES
+#define INVALID_FILE_ATTRIBUTES ((DWORD)-1)
+
+
+DWORD ShortPathToLongPath(LPCTSTR lpszShortPath,LPTSTR lpszLongPath,DWORD
+                          cchBuffer)
+{
+    DWORD i=0;
+    TCHAR path[_MAX_PATH]={0};
+    TCHAR ret[_MAX_PATH]={0};
+    DWORD pos=0, prev_pos=0;
+    DWORD len=_tcslen(lpszShortPath);
+
+    /* Is the string valid? */
+    if (!lpszShortPath) {
+        SetLastError(ERROR_INVALID_PARAMETER);
+        return 0;  
+    }
+
+    /* Is the path valid? */
+    if (GetFileAttributes(lpszShortPath)==INVALID_FILE_ATTRIBUTES)
+        return 0;
+
+    /* Convert "/" to "\" */
+    for (i=0;i<len;++i) {
+        if (lpszShortPath[i]==_T('/')) 
+            path[i]=_T('\\');
+        else
+            path[i]=lpszShortPath[i];
+    }
+
+    /* UNC path? */
+    if (path[0]==_T('\\') && path[1]==_T('\\')) {
+        pos=2;
+        for (i=0;i<2;++i) {
+            while (path[pos]!=_T('\\') && path[pos]!=_T('\0'))
+                ++pos;
+            ++pos;
+        }
+        _tcsncpy(ret,path,pos-1);
+    } /* Drive letter? */
+    else if (path[1]==_T(':')) {
+        if (path[2]==_T('\\'))
+            pos=3;
+        if (len==3) {
+            if (cchBuffer>3)
+                _tcscpy(lpszLongPath,lpszShortPath);
+            return len;
+        }
+        _tcsncpy(ret,path,2);
+    }
+    
+    /* Expand the path for each subpath, and strip trailing backslashes */
+    for (prev_pos = pos-1;pos<=len;++pos) {
+        if (path[pos]==_T('\\') || (path[pos]==_T('\0') &&
+                                    path[pos-1]!=_T('\\'))) {
+            WIN32_FIND_DATA fd;
+            HANDLE hf=0;
+            TCHAR c=path[pos];
+            char* new_element;
+            path[pos]=_T('\0');
+
+            /* the path[prev_pos+1]... path[pos] range is the part of
+               path we're handling right now. We need to find long
+               name for that element and add it. */
+            new_element = path + prev_pos + 1;
+
+            /* First add separator, but only if there's something in result already. */
+            if (ret[0] != _T('\0'))
+            {
+                _tcscat(ret,_T("\\"));
+            }
+
+            /* If it's ".." element, we need to append it, not
+               the name in parent that FindFirstFile will return.
+               Same goes for "." */
+            
+            if (new_element[0] == _T('.') && new_element[1] == _T('\0') ||
+                new_element[0] == _T('.') && new_element[1] == _T('.') 
+                && new_element[2] == _T('\0'))
+            {
+                _tcscat(ret, new_element);
+            }
+            else
+            {
+                hf=FindFirstFile(path, &fd);
+                if (hf==INVALID_HANDLE_VALUE)
+                    return 0;
+
+                _tcscat(ret,fd.cFileName);
+                FindClose(hf);
+            }
+
+            path[pos]=c;
+
+            prev_pos = pos;
+        }
+    }
+ 
+    len=_tcslen(ret)+1;
+    if (cchBuffer>=len)
+        _tcscpy(lpszLongPath,ret);
+    
+    return len;
+}
+
+char* short_path_to_long_path(char* short_path)
+{  
+    char buffer2[_MAX_PATH];
+    int ret = ShortPathToLongPath(short_path, buffer2, _MAX_PATH);
+
+    if (ret)
+	return newstr(buffer2);
+    else
+      return newstr(short_path);
+}
+
+#endif
+
+
+# endif /* unix, NT, OS/2, AmigaOS */

Added: boost-jam/boost-build/branches/upstream/current/jam_src/pathvms.c
===================================================================
--- boost-jam/boost-build/branches/upstream/current/jam_src/pathvms.c	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/jam_src/pathvms.c	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,424 @@
+/*
+ * Copyright 1993-2002 Christopher Seiwald and Perforce Software, Inc.
+ *
+ * This file is part of Jam - see jam.c for Copyright information.
+ */
+
+/*  This file is ALSO:
+ *  Copyright 2001-2004 David Abrahams.
+ *  Distributed under the Boost Software License, Version 1.0.
+ *  (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+ */
+
+# include "jam.h"
+# include "pathsys.h"
+
+# ifdef OS_VMS
+
+# define DEBUG
+
+/*
+ * pathvms.c - manipulate file names on VMS
+ *
+ * External routines:
+ *
+ *	path_parse() - split a file name into dir/base/suffix/member
+ *	path_build() - build a filename given dir/base/suffix/member
+ *	path_parent() - make a PATHNAME point to its parent dir
+ *
+ * File_parse() and path_build() just manipuate a string and a structure;
+ * they do not make system calls.
+ *
+ * WARNING!  This file contains voodoo logic, as black magic is 
+ * necessary for wrangling with VMS file name.  Woe be to people
+ * who mess with this code.
+ *
+ * 02/09/95 (seiwald) - bungled R=[xxx] - was using directory length!
+ * 05/03/96 (seiwald) - split from filevms.c
+ */
+
+/*
+ * path_parse() - split a file name into dir/base/suffix/member
+ */
+
+void
+path_parse( 
+	char	*file,
+	PATHNAME *f )
+{
+	char *p, *q;
+	char *end;
+	
+	memset( (char *)f, 0, sizeof( *f ) );
+
+	/* Look for <grist> */
+
+	if( file[0] == '<' && ( p = strchr( file, '>' ) ) )
+	{
+	    f->f_grist.ptr = file;
+	    f->f_grist.len = p - file;
+	    file = p + 1;
+	}
+
+	/* Look for dev:[dir] or dev: */
+
+	if( ( p = strchr( file, ']' ) ) || ( p = strchr( file, ':' ) ) )
+	{
+	    f->f_dir.ptr = file;
+	    f->f_dir.len = p + 1 - file;
+	    file = p + 1;
+	}
+
+	end = file + strlen( file );
+
+	/* Look for (member) */
+
+	if( ( p = strchr( file, '(' ) ) && end[-1] == ')' )
+	{
+	    f->f_member.ptr = p + 1;
+	    f->f_member.len = end - p - 2;
+	    end = p;
+	} 
+
+	/* Look for .suffix */
+	/* This would be memrchr() */
+
+	p = 0;
+	q = file;
+
+	while( q = (char *)memchr( q, '.', end - q ) )
+	    p = q++;
+
+	if( p )
+	{
+	    f->f_suffix.ptr = p;
+	    f->f_suffix.len = end - p;
+	    end = p;
+	}
+
+	/* Leaves base */
+
+	f->f_base.ptr = file;
+	f->f_base.len = end - file;
+
+	/* Is this a directory without a file spec? */
+
+	f->parent = 0;
+}
+
+/*
+ *	dir		mods		result
+ *	---		---		------
+ * Rerooting:
+ *
+ *	(none)		:R=dev:		dev:		
+ *	devd:		:R=dev:		devd:
+ *	devd:[dir]	:R=dev:		devd:[dir]
+ *	[.dir]		:R=dev:		dev:[dir]	questionable
+ *	[dir]		:R=dev:		dev:[dir]
+ *
+ *	(none)		:R=[rdir]	[rdir]		questionable
+ *	devd:		:R=[rdir]	devd:
+ *	devd:[dir]	:R=[rdir]	devd:[dir]
+ *	[.dir]		:R=[rdir]	[rdir.dir]	questionable
+ *	[dir]		:R=[rdir]	[rdir]
+ *
+ *	(none)		:R=dev:[root]	dev:[root]
+ *	devd:		:R=dev:[root]	devd:
+ *	devd:[dir]	:R=dev:[root]	devd:[dir]
+ *	[.dir]		:R=dev:[root]	dev:[root.dir]
+ *	[dir]		:R=dev:[root]	[dir]
+ *
+ * Climbing to parent:
+ *
+ */
+
+# define DIR_EMPTY	0	/* empty string */
+# define DIR_DEV	1	/* dev: */
+# define DIR_DEVDIR	2	/* dev:[dir] */
+# define DIR_DOTDIR	3	/* [.dir] */
+# define DIR_DASHDIR	4	/* [-] or [-.dir] */
+# define DIR_ABSDIR	5	/* [dir] */
+# define DIR_ROOT	6	/* [000000] or dev:[000000] */
+
+# define G_DIR		0	/* take just dir */
+# define G_ROOT		1	/* take just root */
+# define G_VAD		2	/* root's dev: + [abs] */
+# define G_DRD		3	/* root's dev:[dir] + [.rel] */
+# define G_VRD		4	/* root's dev: + [.rel] made [abs] */
+# define G_DDD		5	/* root's dev:[dir] + . + [dir] */
+
+static int grid[7][7] = {
+
+/* root/dir	EMPTY	DEV	DEVDIR	DOTDIR	DASH,	ABSDIR	ROOT */
+/* EMPTY */	G_DIR,	G_DIR,	G_DIR,	G_DIR,	G_DIR,	G_DIR,	G_DIR,
+/* DEV */	G_ROOT,	G_DIR,	G_DIR,	G_VRD,	G_VAD,	G_VAD,	G_VAD,
+/* DEVDIR */	G_ROOT,	G_DIR,	G_DIR,	G_DRD,	G_VAD,	G_VAD,	G_VAD,
+/* DOTDIR */	G_ROOT,	G_DIR,	G_DIR,	G_DRD,	G_DIR,	G_DIR,	G_DIR,
+/* DASHDIR */	G_ROOT,	G_DIR,	G_DIR,	G_DRD,	G_DDD,	G_DIR,	G_DIR,
+/* ABSDIR */	G_ROOT,	G_DIR,	G_DIR,	G_DRD,	G_DIR,	G_DIR,	G_DIR,
+/* ROOT */	G_ROOT,	G_DIR,	G_DIR,	G_VRD,	G_DIR,	G_DIR,	G_DIR,
+
+} ;
+
+struct dirinf {
+	int	flags;
+
+	struct {
+		char	*ptr;
+		int	len;
+	} dev, dir;
+} ;
+
+static char *
+strnchr( 
+	char	*buf,
+	int	c,
+	int	len )
+{
+	while( len-- )
+	    if( *buf && *buf++ == c )
+		return buf - 1;
+
+	return 0;
+}
+
+static void
+dir_flags( 
+	char	*buf,
+	int	len,
+	struct dirinf *i )
+{
+	char *p;
+
+	if( !buf || !len )
+	{
+	    i->flags = DIR_EMPTY;
+	    i->dev.ptr =
+	    i->dir.ptr = 0;
+	    i->dev.len =
+	    i->dir.len = 0;
+	}
+	else if( p = strnchr( buf, ':', len ) )
+	{
+	    i->dev.ptr = buf;
+	    i->dev.len = p + 1 - buf;
+	    i->dir.ptr = buf + i->dev.len;
+	    i->dir.len = len - i->dev.len;
+	    i->flags = i->dir.len && *i->dir.ptr == '[' ? DIR_DEVDIR : DIR_DEV;
+	}
+	else
+	{
+	    i->dev.ptr = buf;
+	    i->dev.len = 0;
+	    i->dir.ptr = buf;
+	    i->dir.len = len;
+
+	    if( *buf == '[' && buf[1] == ']' )
+		i->flags = DIR_EMPTY;
+	    else if( *buf == '[' && buf[1] == '.' )
+		i->flags = DIR_DOTDIR;
+	    else if( *buf == '[' && buf[1] == '-' )
+		i->flags = DIR_DASHDIR;
+	    else
+		i->flags = DIR_ABSDIR;
+	}
+
+	/* But if its rooted in any way */
+
+	if( i->dir.len == 8 && !strncmp( i->dir.ptr, "[000000]", 8 ) )
+	    i->flags = DIR_ROOT;
+}
+
+/*
+ * path_build() - build a filename given dir/base/suffix/member
+ */
+
+void
+path_build(
+	PATHNAME *f,
+	string	*file,
+	int	binding )
+{
+    struct dirinf root, dir;
+    int g;
+
+    file_build1( f, file );
+        
+    /* Get info on root and dir for combining. */
+
+    dir_flags( f->f_root.ptr, f->f_root.len, &root );
+    dir_flags( f->f_dir.ptr, f->f_dir.len, &dir );
+
+    /* Combine */
+
+    switch( g = grid[ root.flags ][ dir.flags ] )
+    {
+    case G_DIR:	
+        /* take dir */
+        string_append_range( file, f->f_dir.ptr, f->f_dir.ptr + f->f_dir.len  );
+        break;
+
+    case G_ROOT:	
+        /* take root */
+        string_append_range( file, f->f_root.ptr, f->f_root.ptr + f->f_root.len  );
+        break;
+
+    case G_VAD:	
+        /* root's dev + abs directory */
+        string_append_range( file, root.dev.ptr, root.dev.ptr + root.dev.len  );
+        string_append_range( file, dir.dir.ptr, dir.dir.ptr + dir.dir.len  );
+        break;
+		
+    case G_DRD:	
+    case G_DDD:
+        /* root's dev:[dir] + rel directory */
+        string_append_range( file, f->f_root.ptr, f->f_root.ptr + f->f_root.len  );
+
+        /* sanity checks: root ends with ] */
+
+        if( file->value[file->size - 1] == ']' )
+            string_pop_back( file );
+
+        /* Add . if separating two -'s */
+
+        if( g == G_DDD )
+            string_push_back( file, '.' );
+
+        /* skip [ of dir */
+        string_append_range( file, dir.dir.ptr + 1, dir.dir.ptr + 1 + dir.dir.len - 1  );
+        break;
+
+    case G_VRD:	
+        /* root's dev + rel directory made abs */
+        string_append_range( file, root.dev.ptr, root.dev.ptr + root.dev.len  );
+        string_push_back( file, '[' );
+        /* skip [. of rel dir */
+        string_append_range( file, dir.dir.ptr + 2, dir.dir.ptr + 2 + dir.dir.len - 2  );
+        break;
+    }
+
+# ifdef DEBUG
+    if( DEBUG_SEARCH && ( root.flags || dir.flags ) )
+    {
+        printf( "%d x %d = %d (%s)\n", root.flags, dir.flags,
+                grid[ root.flags ][ dir.flags ], file->value );
+    }
+# endif 
+
+    /* 
+     * Now do the special :P modifier when no file was present.
+     *	(none)		(none)
+     *	[dir1.dir2]	[dir1]
+     *	[dir]		[000000]
+     *	[.dir]		(none)
+     *	[]		[]
+     */
+
+    if( file->value[file->size - 1] == ']' && f->parent )
+    {
+        char* p = file->value + file->size;
+        while( p-- > file->value )
+        {
+            if( *p == '.' )
+            {
+                /* If we've truncated everything and left with '[',
+                   return empty string. */
+                if (p == file->value + 1)
+                    string_truncate( file, 0 );
+                else {
+                    string_truncate( file, p - file->value );
+                    string_push_back( file, ']' );
+                }
+                break;
+            }
+            else if( *p == '-' )
+            {
+                /* handle .- or - */
+                if( p > file->value && p[-1] == '.' )
+                    --p;
+                
+                *p++ = ']';
+                break;
+            }
+            else if( *p == '[' )
+            {
+                if( p[1] == ']' )
+                {
+                    /* CONSIDER: I don't see any use of this code. We immediately
+                       break, and 'p' is a local variable. */
+                    p += 2;
+                }
+                else
+                {
+                    string_truncate( file, p - file->value );
+                    string_append( file, "[000000]" );
+                }
+                break;
+            }
+        }
+    }
+
+    /* Now copy the file pieces. */
+
+    if( f->f_base.len )
+    {
+        string_append_range( file, f->f_base.ptr, f->f_base.ptr + f->f_base.len  );
+    }
+
+    /* If there is no suffix, we append a "." onto all generated */
+    /* names.  This keeps VMS from appending its own (wrong) idea */
+    /* of what the suffix should be. */
+
+    if( f->f_suffix.len )
+    {
+        string_append_range( file, f->f_suffix.ptr, f->f_suffix.ptr + f->f_suffix.len  );
+    }
+    else if( binding && f->f_base.len )
+    {
+        string_push_back( file, '.' );
+    }
+
+    if( f->f_member.len )
+    {
+        string_push_back( file, '(' );
+        string_append_range( file, f->f_member.ptr, f->f_member.ptr + f->f_member.len  );
+        string_push_back( file, ')' );
+    }
+
+# ifdef DEBUG
+    if( DEBUG_SEARCH )
+        printf("built %.*s + %.*s / %.*s suf %.*s mem %.*s -> %s\n", 
+               f->f_root.len, f->f_root.ptr,
+               f->f_dir.len, f->f_dir.ptr,
+               f->f_base.len, f->f_base.ptr,
+               f->f_suffix.len, f->f_suffix.ptr,
+               f->f_member.len, f->f_member.ptr,
+               file->value );
+# endif
+}
+
+/*
+ *	path_parent() - make a PATHNAME point to its parent dir
+ */
+
+void
+path_parent( PATHNAME *f )
+{
+	if( f->f_base.len )
+	{
+	    f->f_base.ptr =
+	    f->f_suffix.ptr =
+	    f->f_member.ptr = "";
+
+	    f->f_base.len =
+	    f->f_suffix.len =
+	    f->f_member.len = 0;
+	}
+	else
+	{
+	    f->parent = 1;
+	}
+}
+
+# endif /* VMS */

Added: boost-jam/boost-build/branches/upstream/current/jam_src/pwd.c
===================================================================
--- boost-jam/boost-build/branches/upstream/current/jam_src/pwd.c	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/jam_src/pwd.c	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,44 @@
+/* Copyright Vladimir Prus 2002. Distributed under the Boost */
+/* Software License, Version 1.0. (See accompanying */
+/* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */
+
+#include "jam.h"
+#include "lists.h"
+#include "newstr.h"
+#include "pathsys.h"
+
+#include <limits.h>
+
+/* MinGW on windows declares PATH_MAX in limits.h */
+#if defined(NT) && ! defined(__GNUC__)
+#include <direct.h>
+#define PATH_MAX _MAX_PATH
+#else
+#include <limits.h>
+#include <unistd.h>
+#if defined(__COMO__)
+     #include <linux/limits.h>
+#endif
+#endif
+
+
+
+LIST*
+pwd(void)
+{
+    char buffer[PATH_MAX];
+    if (getcwd(buffer, sizeof(buffer)) == NULL)
+    {
+        perror("can not get current directory");
+        return L0;
+    }
+    else
+    {
+#ifdef NT
+        return list_new(L0, short_path_to_long_path(buffer));
+#else
+        return list_new(L0, newstr(buffer));
+#endif
+    }
+}
+

Added: boost-jam/boost-build/branches/upstream/current/jam_src/pwd.h
===================================================================
--- boost-jam/boost-build/branches/upstream/current/jam_src/pwd.h	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/jam_src/pwd.h	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,10 @@
+/* Copyright Vladimir Prus 2002. Distributed under the Boost */
+/* Software License, Version 1.0. (See accompanying */
+/* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */
+
+#ifndef PWD_H
+#define PWD_H
+
+LIST* pwd(void);
+
+#endif

Added: boost-jam/boost-build/branches/upstream/current/jam_src/regexp.c
===================================================================
--- boost-jam/boost-build/branches/upstream/current/jam_src/regexp.c	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/jam_src/regexp.c	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,1317 @@
+/*
+ * regcomp and regexec -- regsub and regerror are elsewhere
+ *
+ *	Copyright (c) 1986 by University of Toronto.
+ *	Written by Henry Spencer.  Not derived from licensed software.
+ *
+ *	Permission is granted to anyone to use this software for any
+ *	purpose on any computer system, and to redistribute it freely,
+ *	subject to the following restrictions:
+ *
+ *	1. The author is not responsible for the consequences of use of
+ *		this software, no matter how awful, even if they arise
+ *		from defects in it.
+ *
+ *	2. The origin of this software must not be misrepresented, either
+ *		by explicit claim or by omission.
+ *
+ *	3. Altered versions must be plainly marked as such, and must not
+ *		be misrepresented as being the original software.
+ *** THIS IS AN ALTERED VERSION.  It was altered by John Gilmore,
+ *** hoptoad!gnu, on 27 Dec 1986, to add \n as an alternative to |
+ *** to assist in implementing egrep.
+ *** THIS IS AN ALTERED VERSION.  It was altered by John Gilmore,
+ *** hoptoad!gnu, on 27 Dec 1986, to add \< and \> for word-matching
+ *** as in BSD grep and ex.
+ *** THIS IS AN ALTERED VERSION.  It was altered by John Gilmore,
+ *** hoptoad!gnu, on 28 Dec 1986, to optimize characters quoted with \.
+ *** THIS IS AN ALTERED VERSION.  It was altered by James A. Woods,
+ *** ames!jaw, on 19 June 1987, to quash a regcomp() redundancy.
+ *** THIS IS AN ALTERED VERSION.  It was altered by Christopher Seiwald
+ *** seiwald at vix.com, on 28 August 1993, for use in jam.  Regmagic.h
+ *** was moved into regexp.h, and the include of regexp.h now uses "'s
+ *** to avoid conflicting with the system regexp.h.  Const, bless its
+ *** soul, was removed so it can compile everywhere.  The declaration
+ *** of strchr() was in conflict on AIX, so it was removed (as it is
+ *** happily defined in string.h).
+ *** THIS IS AN ALTERED VERSION.  It was altered by Christopher Seiwald
+ *** seiwald at perforce.com, on 20 January 2000, to use function prototypes.
+ *
+ * Beware that some of this code is subtly aware of the way operator
+ * precedence is structured in regular expressions.  Serious changes in
+ * regular-expression syntax might require a total rethink.
+ */
+#include "regexp.h"
+#include <stdio.h>
+#include <ctype.h>
+#ifndef ultrix
+#include <stdlib.h>
+#endif
+#include <string.h>
+
+/*
+ * The "internal use only" fields in regexp.h are present to pass info from
+ * compile to execute that permits the execute phase to run lots faster on
+ * simple cases.  They are:
+ *
+ * regstart	char that must begin a match; '\0' if none obvious
+ * reganch	is the match anchored (at beginning-of-line only)?
+ * regmust	string (pointer into program) that match must include, or NULL
+ * regmlen	length of regmust string
+ *
+ * Regstart and reganch permit very fast decisions on suitable starting points
+ * for a match, cutting down the work a lot.  Regmust permits fast rejection
+ * of lines that cannot possibly match.  The regmust tests are costly enough
+ * that regcomp() supplies a regmust only if the r.e. contains something
+ * potentially expensive (at present, the only such thing detected is * or +
+ * at the start of the r.e., which can involve a lot of backup).  Regmlen is
+ * supplied because the test in regexec() needs it and regcomp() is computing
+ * it anyway.
+ */
+
+/*
+ * Structure for regexp "program".  This is essentially a linear encoding
+ * of a nondeterministic finite-state machine (aka syntax charts or
+ * "railroad normal form" in parsing technology).  Each node is an opcode
+ * plus a "next" pointer, possibly plus an operand.  "Next" pointers of
+ * all nodes except BRANCH implement concatenation; a "next" pointer with
+ * a BRANCH on both ends of it is connecting two alternatives.  (Here we
+ * have one of the subtle syntax dependencies:  an individual BRANCH (as
+ * opposed to a collection of them) is never concatenated with anything
+ * because of operator precedence.)  The operand of some types of node is
+ * a literal string; for others, it is a node leading into a sub-FSM.  In
+ * particular, the operand of a BRANCH node is the first node of the branch.
+ * (NB this is *not* a tree structure:  the tail of the branch connects
+ * to the thing following the set of BRANCHes.)  The opcodes are:
+ */
+
+/* definition	number	opnd?	meaning */
+#define	END	0	/* no	End of program. */
+#define	BOL	1	/* no	Match "" at beginning of line. */
+#define	EOL	2	/* no	Match "" at end of line. */
+#define	ANY	3	/* no	Match any one character. */
+#define	ANYOF	4	/* str	Match any character in this string. */
+#define	ANYBUT	5	/* str	Match any character not in this string. */
+#define	BRANCH	6	/* node	Match this alternative, or the next... */
+#define	BACK	7	/* no	Match "", "next" ptr points backward. */
+#define	EXACTLY	8	/* str	Match this string. */
+#define	NOTHING	9	/* no	Match empty string. */
+#define	STAR	10	/* node	Match this (simple) thing 0 or more times. */
+#define	PLUS	11	/* node	Match this (simple) thing 1 or more times. */
+#define	WORDA	12	/* no	Match "" at wordchar, where prev is nonword */
+#define	WORDZ	13	/* no	Match "" at nonwordchar, where prev is word */
+#define	OPEN	20	/* no	Mark this point in input as start of #n. */
+			/*	OPEN+1 is number 1, etc. */
+#define	CLOSE	30	/* no	Analogous to OPEN. */
+
+/*
+ * Opcode notes:
+ *
+ * BRANCH	The set of branches constituting a single choice are hooked
+ *		together with their "next" pointers, since precedence prevents
+ *		anything being concatenated to any individual branch.  The
+ *		"next" pointer of the last BRANCH in a choice points to the
+ *		thing following the whole choice.  This is also where the
+ *		final "next" pointer of each individual branch points; each
+ *		branch starts with the operand node of a BRANCH node.
+ *
+ * BACK		Normal "next" pointers all implicitly point forward; BACK
+ *		exists to make loop structures possible.
+ *
+ * STAR,PLUS	'?', and complex '*' and '+', are implemented as circular
+ *		BRANCH structures using BACK.  Simple cases (one character
+ *		per match) are implemented with STAR and PLUS for speed
+ *		and to minimize recursive plunges.
+ *
+ * OPEN,CLOSE	...are numbered at compile time.
+ */
+
+/*
+ * A node is one char of opcode followed by two chars of "next" pointer.
+ * "Next" pointers are stored as two 8-bit pieces, high order first.  The
+ * value is a positive offset from the opcode of the node containing it.
+ * An operand, if any, simply follows the node.  (Note that much of the
+ * code generation knows about this implicit relationship.)
+ *
+ * Using two bytes for the "next" pointer is vast overkill for most things,
+ * but allows patterns to get big without disasters.
+ */
+#define	OP(p)	(*(p))
+#define	NEXT(p)	(((*((p)+1)&0377)<<8) + (*((p)+2)&0377))
+#define	OPERAND(p)	((p) + 3)
+
+/*
+ * See regmagic.h for one further detail of program structure.
+ */
+
+
+/*
+ * Utility definitions.
+ */
+#ifndef CHARBITS
+#define	UCHARAT(p)	((int)*(unsigned char *)(p))
+#else
+#define	UCHARAT(p)	((int)*(p)&CHARBITS)
+#endif
+
+#define	FAIL(m)	{ regerror(m); return(NULL); }
+#define	ISMULT(c)	((c) == '*' || (c) == '+' || (c) == '?')
+
+/*
+ * Flags to be passed up and down.
+ */
+#define	HASWIDTH	01	/* Known never to match null string. */
+#define	SIMPLE		02	/* Simple enough to be STAR/PLUS operand. */
+#define	SPSTART		04	/* Starts with * or +. */
+#define	WORST		0	/* Worst case. */
+
+/*
+ * Global work variables for regcomp().
+ */
+static char *regparse;		/* Input-scan pointer. */
+static int regnpar;		/* () count. */
+static char regdummy;
+static char *regcode;		/* Code-emit pointer; &regdummy = don't. */
+static long regsize;		/* Code size. */
+
+/*
+ * Forward declarations for regcomp()'s friends.
+ */
+#ifndef STATIC
+#define	STATIC	static
+#endif
+STATIC char *reg( int paren, int *flagp );
+STATIC char *regbranch( int *flagp );
+STATIC char *regpiece( int *flagp );
+STATIC char *regatom( int *flagp );
+STATIC char *regnode( int op );
+STATIC char *regnext( register char *p );
+STATIC void regc( int b );
+STATIC void reginsert( char op, char *opnd );
+STATIC void regtail( char *p, char *val );
+STATIC void regoptail( char *p, char *val );
+#ifdef STRCSPN
+STATIC int strcspn();
+#endif
+
+/*
+ - regcomp - compile a regular expression into internal code
+ *
+ * We can't allocate space until we know how big the compiled form will be,
+ * but we can't compile it (and thus know how big it is) until we've got a
+ * place to put the code.  So we cheat:  we compile it twice, once with code
+ * generation turned off and size counting turned on, and once "for real".
+ * This also means that we don't allocate space until we are sure that the
+ * thing really will compile successfully, and we never have to move the
+ * code and thus invalidate pointers into it.  (Note that it has to be in
+ * one piece because free() must be able to free it all.)
+ *
+ * Beware that the optimization-preparation code in here knows about some
+ * of the structure of the compiled regexp.
+ */
+regexp *
+regcomp( char *exp )
+{
+	register regexp *r;
+	register char *scan;
+	register char *longest;
+	register unsigned len;
+	int flags;
+
+	if (exp == NULL)
+		FAIL("NULL argument");
+
+	/* First pass: determine size, legality. */
+#ifdef notdef
+	if (exp[0] == '.' && exp[1] == '*') exp += 2;  /* aid grep */
+#endif
+	regparse = (char *)exp;
+	regnpar = 1;
+	regsize = 0L;
+	regcode = &regdummy;
+	regc(MAGIC);
+	if (reg(0, &flags) == NULL)
+		return(NULL);
+
+	/* Small enough for pointer-storage convention? */
+	if (regsize >= 32767L)		/* Probably could be 65535L. */
+		FAIL("regexp too big");
+
+	/* Allocate space. */
+	r = (regexp *)malloc(sizeof(regexp) + (unsigned)regsize);
+	if (r == NULL)
+		FAIL("out of space");
+
+	/* Second pass: emit code. */
+	regparse = (char *)exp;
+	regnpar = 1;
+	regcode = r->program;
+	regc(MAGIC);
+	if (reg(0, &flags) == NULL)
+		return(NULL);
+
+	/* Dig out information for optimizations. */
+	r->regstart = '\0';	/* Worst-case defaults. */
+	r->reganch = 0;
+	r->regmust = NULL;
+	r->regmlen = 0;
+	scan = r->program+1;			/* First BRANCH. */
+	if (OP(regnext(scan)) == END) {		/* Only one top-level choice. */
+		scan = OPERAND(scan);
+
+		/* Starting-point info. */
+		if (OP(scan) == EXACTLY)
+			r->regstart = *OPERAND(scan);
+		else if (OP(scan) == BOL)
+			r->reganch++;
+
+		/*
+		 * If there's something expensive in the r.e., find the
+		 * longest literal string that must appear and make it the
+		 * regmust.  Resolve ties in favor of later strings, since
+		 * the regstart check works with the beginning of the r.e.
+		 * and avoiding duplication strengthens checking.  Not a
+		 * strong reason, but sufficient in the absence of others.
+		 */
+		if (flags&SPSTART) {
+			longest = NULL;
+			len = 0;
+			for (; scan != NULL; scan = regnext(scan))
+				if (OP(scan) == EXACTLY && strlen(OPERAND(scan)) >= len) {
+					longest = OPERAND(scan);
+					len = strlen(OPERAND(scan));
+				}
+			r->regmust = longest;
+			r->regmlen = len;
+		}
+	}
+
+	return(r);
+}
+
+/*
+ - reg - regular expression, i.e. main body or parenthesized thing
+ *
+ * Caller must absorb opening parenthesis.
+ *
+ * Combining parenthesis handling with the base level of regular expression
+ * is a trifle forced, but the need to tie the tails of the branches to what
+ * follows makes it hard to avoid.
+ */
+static char *
+reg(
+	int paren,			/* Parenthesized? */
+	int *flagp )
+{
+	register char *ret;
+	register char *br;
+	register char *ender;
+	register int parno;
+	int flags;
+
+	*flagp = HASWIDTH;	/* Tentatively. */
+
+	/* Make an OPEN node, if parenthesized. */
+	if (paren) {
+		if (regnpar >= NSUBEXP)
+			FAIL("too many ()");
+		parno = regnpar;
+		regnpar++;
+		ret = regnode(OPEN+parno);
+	} else
+		ret = NULL;
+
+	/* Pick up the branches, linking them together. */
+	br = regbranch(&flags);
+	if (br == NULL)
+		return(NULL);
+	if (ret != NULL)
+		regtail(ret, br);	/* OPEN -> first. */
+	else
+		ret = br;
+	if (!(flags&HASWIDTH))
+		*flagp &= ~HASWIDTH;
+	*flagp |= flags&SPSTART;
+	while (*regparse == '|' || *regparse == '\n') {
+		regparse++;
+		br = regbranch(&flags);
+		if (br == NULL)
+			return(NULL);
+		regtail(ret, br);	/* BRANCH -> BRANCH. */
+		if (!(flags&HASWIDTH))
+			*flagp &= ~HASWIDTH;
+		*flagp |= flags&SPSTART;
+	}
+
+	/* Make a closing node, and hook it on the end. */
+	ender = regnode((paren) ? CLOSE+parno : END);	
+	regtail(ret, ender);
+
+	/* Hook the tails of the branches to the closing node. */
+	for (br = ret; br != NULL; br = regnext(br))
+		regoptail(br, ender);
+
+	/* Check for proper termination. */
+	if (paren && *regparse++ != ')') {
+		FAIL("unmatched ()");
+	} else if (!paren && *regparse != '\0') {
+		if (*regparse == ')') {
+			FAIL("unmatched ()");
+		} else
+			FAIL("junk on end");	/* "Can't happen". */
+		/* NOTREACHED */
+	}
+
+	return(ret);
+}
+
+/*
+ - regbranch - one alternative of an | operator
+ *
+ * Implements the concatenation operator.
+ */
+static char *
+regbranch( int *flagp )
+{
+	register char *ret;
+	register char *chain;
+	register char *latest;
+	int flags;
+
+	*flagp = WORST;		/* Tentatively. */
+
+	ret = regnode(BRANCH);
+	chain = NULL;
+	while (*regparse != '\0' && *regparse != ')' &&
+	       *regparse != '\n' && *regparse != '|') {
+		latest = regpiece(&flags);
+		if (latest == NULL)
+			return(NULL);
+		*flagp |= flags&HASWIDTH;
+		if (chain == NULL)	/* First piece. */
+			*flagp |= flags&SPSTART;
+		else
+			regtail(chain, latest);
+		chain = latest;
+	}
+	if (chain == NULL)	/* Loop ran zero times. */
+		(void) regnode(NOTHING);
+
+	return(ret);
+}
+
+/*
+ - regpiece - something followed by possible [*+?]
+ *
+ * Note that the branching code sequences used for ? and the general cases
+ * of * and + are somewhat optimized:  they use the same NOTHING node as
+ * both the endmarker for their branch list and the body of the last branch.
+ * It might seem that this node could be dispensed with entirely, but the
+ * endmarker role is not redundant.
+ */
+static char *
+regpiece( int *flagp )
+{
+	register char *ret;
+	register char op;
+	register char *next;
+	int flags;
+
+	ret = regatom(&flags);
+	if (ret == NULL)
+		return(NULL);
+
+	op = *regparse;
+	if (!ISMULT(op)) {
+		*flagp = flags;
+		return(ret);
+	}
+
+	if (!(flags&HASWIDTH) && op != '?')
+		FAIL("*+ operand could be empty");
+	*flagp = (op != '+') ? (WORST|SPSTART) : (WORST|HASWIDTH);
+
+	if (op == '*' && (flags&SIMPLE))
+		reginsert(STAR, ret);
+	else if (op == '*') {
+		/* Emit x* as (x&|), where & means "self". */
+		reginsert(BRANCH, ret);			/* Either x */
+		regoptail(ret, regnode(BACK));		/* and loop */
+		regoptail(ret, ret);			/* back */
+		regtail(ret, regnode(BRANCH));		/* or */
+		regtail(ret, regnode(NOTHING));		/* null. */
+	} else if (op == '+' && (flags&SIMPLE))
+		reginsert(PLUS, ret);
+	else if (op == '+') {
+		/* Emit x+ as x(&|), where & means "self". */
+		next = regnode(BRANCH);			/* Either */
+		regtail(ret, next);
+		regtail(regnode(BACK), ret);		/* loop back */
+		regtail(next, regnode(BRANCH));		/* or */
+		regtail(ret, regnode(NOTHING));		/* null. */
+	} else if (op == '?') {
+		/* Emit x? as (x|) */
+		reginsert(BRANCH, ret);			/* Either x */
+		regtail(ret, regnode(BRANCH));		/* or */
+		next = regnode(NOTHING);		/* null. */
+		regtail(ret, next);
+		regoptail(ret, next);
+	}
+	regparse++;
+	if (ISMULT(*regparse))
+		FAIL("nested *?+");
+
+	return(ret);
+}
+
+/*
+ - regatom - the lowest level
+ *
+ * Optimization:  gobbles an entire sequence of ordinary characters so that
+ * it can turn them into a single node, which is smaller to store and
+ * faster to run.  Backslashed characters are exceptions, each becoming a
+ * separate node; the code is simpler that way and it's not worth fixing.
+ */
+static char *
+regatom( int *flagp )
+{
+	register char *ret;
+	int flags;
+
+	*flagp = WORST;		/* Tentatively. */
+
+	switch (*regparse++) {
+	/* FIXME: these chars only have meaning at beg/end of pat? */
+	case '^':
+		ret = regnode(BOL);
+		break;
+	case '$':
+		ret = regnode(EOL);
+		break;
+	case '.':
+		ret = regnode(ANY);
+		*flagp |= HASWIDTH|SIMPLE;
+		break;
+	case '[': {
+			register int classr;
+			register int classend;
+
+			if (*regparse == '^') {	/* Complement of range. */
+				ret = regnode(ANYBUT);
+				regparse++;
+			} else
+				ret = regnode(ANYOF);
+			if (*regparse == ']' || *regparse == '-')
+				regc(*regparse++);
+			while (*regparse != '\0' && *regparse != ']') {
+				if (*regparse == '-') {
+					regparse++;
+					if (*regparse == ']' || *regparse == '\0')
+						regc('-');
+					else {
+						classr = UCHARAT(regparse-2)+1;
+						classend = UCHARAT(regparse);
+						if (classr > classend+1)
+							FAIL("invalid [] range");
+						for (; classr <= classend; classr++)
+							regc(classr);
+						regparse++;
+					}
+				} else
+					regc(*regparse++);
+			}
+			regc('\0');
+			if (*regparse != ']')
+				FAIL("unmatched []");
+			regparse++;
+			*flagp |= HASWIDTH|SIMPLE;
+		}
+		break;
+	case '(':
+		ret = reg(1, &flags);
+		if (ret == NULL)
+			return(NULL);
+		*flagp |= flags&(HASWIDTH|SPSTART);
+		break;
+	case '\0':
+	case '|':
+	case '\n':
+	case ')':
+		FAIL("internal urp");	/* Supposed to be caught earlier. */
+		break;
+	case '?':
+	case '+':
+	case '*':
+		FAIL("?+* follows nothing");
+		break;
+	case '\\':
+		switch (*regparse++) {
+		case '\0':
+			FAIL("trailing \\");
+			break;
+		case '<':
+			ret = regnode(WORDA);
+			break;
+		case '>':
+			ret = regnode(WORDZ);
+			break;
+		/* FIXME: Someday handle \1, \2, ... */
+		default:
+			/* Handle general quoted chars in exact-match routine */
+			goto de_fault;
+		}
+		break;
+	de_fault:
+	default:
+		/*
+		 * Encode a string of characters to be matched exactly.
+		 *
+		 * This is a bit tricky due to quoted chars and due to
+		 * '*', '+', and '?' taking the SINGLE char previous
+		 * as their operand.
+		 *
+		 * On entry, the char at regparse[-1] is going to go
+		 * into the string, no matter what it is.  (It could be
+		 * following a \ if we are entered from the '\' case.)
+		 * 
+		 * Basic idea is to pick up a good char in  ch  and
+		 * examine the next char.  If it's *+? then we twiddle.
+		 * If it's \ then we frozzle.  If it's other magic char
+		 * we push  ch  and terminate the string.  If none of the
+		 * above, we push  ch  on the string and go around again.
+		 *
+		 *  regprev  is used to remember where "the current char"
+		 * starts in the string, if due to a *+? we need to back
+		 * up and put the current char in a separate, 1-char, string.
+		 * When  regprev  is NULL,  ch  is the only char in the
+		 * string; this is used in *+? handling, and in setting
+		 * flags |= SIMPLE at the end.
+		 */
+		{
+			char *regprev;
+			register char ch;
+
+			regparse--;			/* Look at cur char */
+			ret = regnode(EXACTLY);
+			for ( regprev = 0 ; ; ) {
+				ch = *regparse++;	/* Get current char */
+				switch (*regparse) {	/* look at next one */
+
+				default:
+					regc(ch);	/* Add cur to string */
+					break;
+
+				case '.': case '[': case '(':
+				case ')': case '|': case '\n':
+				case '$': case '^':
+				case '\0':
+				/* FIXME, $ and ^ should not always be magic */
+				magic:
+					regc(ch);	/* dump cur char */
+					goto done;	/* and we are done */
+
+				case '?': case '+': case '*':
+					if (!regprev) 	/* If just ch in str, */
+						goto magic;	/* use it */
+					/* End mult-char string one early */
+					regparse = regprev; /* Back up parse */
+					goto done;
+
+				case '\\':
+					regc(ch);	/* Cur char OK */
+					switch (regparse[1]){ /* Look after \ */
+					case '\0':
+					case '<':
+					case '>':
+					/* FIXME: Someday handle \1, \2, ... */
+						goto done; /* Not quoted */
+					default:
+						/* Backup point is \, scan							 * point is after it. */
+						regprev = regparse;
+						regparse++; 
+						continue;	/* NOT break; */
+					}
+				}
+				regprev = regparse;	/* Set backup point */
+			}
+		done:
+			regc('\0');
+			*flagp |= HASWIDTH;
+			if (!regprev)		/* One char? */
+				*flagp |= SIMPLE;
+		}
+		break;
+	}
+
+	return(ret);
+}
+
+/*
+ - regnode - emit a node
+ */
+static char *			/* Location. */
+regnode( int op )
+{
+	register char *ret;
+	register char *ptr;
+
+	ret = regcode;
+	if (ret == &regdummy) {
+		regsize += 3;
+		return(ret);
+	}
+
+	ptr = ret;
+	*ptr++ = op;
+	*ptr++ = '\0';		/* Null "next" pointer. */
+	*ptr++ = '\0';
+	regcode = ptr;
+
+	return(ret);
+}
+
+/*
+ - regc - emit (if appropriate) a byte of code
+ */
+static void
+regc( int b )
+{
+	if (regcode != &regdummy)
+		*regcode++ = b;
+	else
+		regsize++;
+}
+
+/*
+ - reginsert - insert an operator in front of already-emitted operand
+ *
+ * Means relocating the operand.
+ */
+static void
+reginsert(
+	char op,
+	char *opnd )
+{
+	register char *src;
+	register char *dst;
+	register char *place;
+
+	if (regcode == &regdummy) {
+		regsize += 3;
+		return;
+	}
+
+	src = regcode;
+	regcode += 3;
+	dst = regcode;
+	while (src > opnd)
+		*--dst = *--src;
+
+	place = opnd;		/* Op node, where operand used to be. */
+	*place++ = op;
+	*place++ = '\0';
+	*place++ = '\0';
+}
+
+/*
+ - regtail - set the next-pointer at the end of a node chain
+ */
+static void
+regtail(
+	char *p,
+	char *val )
+{
+	register char *scan;
+	register char *temp;
+	register int offset;
+
+	if (p == &regdummy)
+		return;
+
+	/* Find last node. */
+	scan = p;
+	for (;;) {
+		temp = regnext(scan);
+		if (temp == NULL)
+			break;
+		scan = temp;
+	}
+
+	if (OP(scan) == BACK)
+		offset = scan - val;
+	else
+		offset = val - scan;
+	*(scan+1) = (offset>>8)&0377;
+	*(scan+2) = offset&0377;
+}
+
+/*
+ - regoptail - regtail on operand of first argument; nop if operandless
+ */
+
+static void
+regoptail(
+	char *p,
+	char *val )
+{
+	/* "Operandless" and "op != BRANCH" are synonymous in practice. */
+	if (p == NULL || p == &regdummy || OP(p) != BRANCH)
+		return;
+	regtail(OPERAND(p), val);
+}
+
+/*
+ * regexec and friends
+ */
+
+/*
+ * Global work variables for regexec().
+ */
+static char *reginput;		/* String-input pointer. */
+static char *regbol;		/* Beginning of input, for ^ check. */
+static char **regstartp;	/* Pointer to startp array. */
+static char **regendp;		/* Ditto for endp. */
+
+/*
+ * Forwards.
+ */
+STATIC int regtry( regexp *prog, char *string );
+STATIC int regmatch( char *prog );
+STATIC int regrepeat( char *p );
+
+#ifdef DEBUG
+int regnarrate = 0;
+void regdump();
+STATIC char *regprop();
+#endif
+
+/*
+ - regexec - match a regexp against a string
+ */
+int
+regexec(
+	register regexp *prog,
+	register char *string )
+{
+	register char *s;
+
+	/* Be paranoid... */
+	if (prog == NULL || string == NULL) {
+		regerror("NULL parameter");
+		return(0);
+	}
+
+	/* Check validity of program. */
+	if (UCHARAT(prog->program) != MAGIC) {
+		regerror("corrupted program");
+		return(0);
+	}
+
+	/* If there is a "must appear" string, look for it. */
+	if (prog->regmust != NULL) {
+		s = (char *)string;
+		while ((s = strchr(s, prog->regmust[0])) != NULL) {
+			if (strncmp(s, prog->regmust, prog->regmlen) == 0)
+				break;	/* Found it. */
+			s++;
+		}
+		if (s == NULL)	/* Not present. */
+			return(0);
+	}
+
+	/* Mark beginning of line for ^ . */
+	regbol = (char *)string;
+
+	/* Simplest case:  anchored match need be tried only once. */
+	if (prog->reganch)
+		return(regtry(prog, string));
+
+	/* Messy cases:  unanchored match. */
+	s = (char *)string;
+	if (prog->regstart != '\0')
+		/* We know what char it must start with. */
+		while ((s = strchr(s, prog->regstart)) != NULL) {
+			if (regtry(prog, s))
+				return(1);
+			s++;
+		}
+	else
+		/* We don't -- general case. */
+		do {
+			if (regtry(prog, s))
+				return(1);
+		} while (*s++ != '\0');
+
+	/* Failure. */
+	return(0);
+}
+
+/*
+ - regtry - try match at specific point
+ */
+static int			/* 0 failure, 1 success */
+regtry(
+	regexp *prog,
+	char *string )
+{
+	register int i;
+	register char **sp;
+	register char **ep;
+
+	reginput = string;
+	regstartp = prog->startp;
+	regendp = prog->endp;
+
+	sp = prog->startp;
+	ep = prog->endp;
+	for (i = NSUBEXP; i > 0; i--) {
+		*sp++ = NULL;
+		*ep++ = NULL;
+	}
+	if (regmatch(prog->program + 1)) {
+		prog->startp[0] = string;
+		prog->endp[0] = reginput;
+		return(1);
+	} else
+		return(0);
+}
+
+/*
+ - regmatch - main matching routine
+ *
+ * Conceptually the strategy is simple:  check to see whether the current
+ * node matches, call self recursively to see whether the rest matches,
+ * and then act accordingly.  In practice we make some effort to avoid
+ * recursion, in particular by going through "ordinary" nodes (that don't
+ * need to know whether the rest of the match failed) by a loop instead of
+ * by recursion.
+ */
+static int			/* 0 failure, 1 success */
+regmatch( char *prog )
+{
+	register char *scan;	/* Current node. */
+	char *next;		/* Next node. */
+
+	scan = prog;
+#ifdef DEBUG
+	if (scan != NULL && regnarrate)
+		fprintf(stderr, "%s(\n", regprop(scan));
+#endif
+	while (scan != NULL) {
+#ifdef DEBUG
+		if (regnarrate)
+			fprintf(stderr, "%s...\n", regprop(scan));
+#endif
+		next = regnext(scan);
+
+		switch (OP(scan)) {
+		case BOL:
+			if (reginput != regbol)
+				return(0);
+			break;
+		case EOL:
+			if (*reginput != '\0')
+				return(0);
+			break;
+		case WORDA:
+			/* Must be looking at a letter, digit, or _ */
+			if ((!isalnum(*reginput)) && *reginput != '_')
+				return(0);
+			/* Prev must be BOL or nonword */
+			if (reginput > regbol &&
+			    (isalnum(reginput[-1]) || reginput[-1] == '_'))
+				return(0);
+			break;
+		case WORDZ:
+			/* Must be looking at non letter, digit, or _ */
+			if (isalnum(*reginput) || *reginput == '_')
+				return(0);
+			/* We don't care what the previous char was */
+			break;
+		case ANY:
+			if (*reginput == '\0')
+				return(0);
+			reginput++;
+			break;
+		case EXACTLY: {
+				register int len;
+				register char *opnd;
+
+				opnd = OPERAND(scan);
+				/* Inline the first character, for speed. */
+				if (*opnd != *reginput)
+					return(0);
+				len = strlen(opnd);
+				if (len > 1 && strncmp(opnd, reginput, len) != 0)
+					return(0);
+				reginput += len;
+			}
+			break;
+		case ANYOF:
+ 			if (*reginput == '\0' || strchr(OPERAND(scan), *reginput) == NULL)
+				return(0);
+			reginput++;
+			break;
+		case ANYBUT:
+ 			if (*reginput == '\0' || strchr(OPERAND(scan), *reginput) != NULL)
+				return(0);
+			reginput++;
+			break;
+		case NOTHING:
+			break;
+		case BACK:
+			break;
+		case OPEN+1:
+		case OPEN+2:
+		case OPEN+3:
+		case OPEN+4:
+		case OPEN+5:
+		case OPEN+6:
+		case OPEN+7:
+		case OPEN+8:
+		case OPEN+9: {
+				register int no;
+				register char *save;
+
+				no = OP(scan) - OPEN;
+				save = reginput;
+
+				if (regmatch(next)) {
+					/*
+					 * Don't set startp if some later
+					 * invocation of the same parentheses
+					 * already has.
+					 */
+					if (regstartp[no] == NULL)
+						regstartp[no] = save;
+					return(1);
+				} else
+					return(0);
+			}
+			break;
+		case CLOSE+1:
+		case CLOSE+2:
+		case CLOSE+3:
+		case CLOSE+4:
+		case CLOSE+5:
+		case CLOSE+6:
+		case CLOSE+7:
+		case CLOSE+8:
+		case CLOSE+9: {
+				register int no;
+				register char *save;
+
+				no = OP(scan) - CLOSE;
+				save = reginput;
+
+				if (regmatch(next)) {
+					/*
+					 * Don't set endp if some later
+					 * invocation of the same parentheses
+					 * already has.
+					 */
+					if (regendp[no] == NULL)
+						regendp[no] = save;
+					return(1);
+				} else
+					return(0);
+			}
+			break;
+		case BRANCH: {
+				register char *save;
+
+				if (OP(next) != BRANCH)		/* No choice. */
+					next = OPERAND(scan);	/* Avoid recursion. */
+				else {
+					do {
+						save = reginput;
+						if (regmatch(OPERAND(scan)))
+							return(1);
+						reginput = save;
+						scan = regnext(scan);
+					} while (scan != NULL && OP(scan) == BRANCH);
+					return(0);
+					/* NOTREACHED */
+				}
+			}
+			break;
+		case STAR:
+		case PLUS: {
+				register char nextch;
+				register int no;
+				register char *save;
+				register int min;
+
+				/*
+				 * Lookahead to avoid useless match attempts
+				 * when we know what character comes next.
+				 */
+				nextch = '\0';
+				if (OP(next) == EXACTLY)
+					nextch = *OPERAND(next);
+				min = (OP(scan) == STAR) ? 0 : 1;
+				save = reginput;
+				no = regrepeat(OPERAND(scan));
+				while (no >= min) {
+					/* If it could work, try it. */
+					if (nextch == '\0' || *reginput == nextch)
+						if (regmatch(next))
+							return(1);
+					/* Couldn't or didn't -- back up. */
+					no--;
+					reginput = save + no;
+				}
+				return(0);
+			}
+			break;
+		case END:
+			return(1);	/* Success! */
+			break;
+		default:
+			regerror("memory corruption");
+			return(0);
+			break;
+		}
+
+		scan = next;
+	}
+
+	/*
+	 * We get here only if there's trouble -- normally "case END" is
+	 * the terminating point.
+	 */
+	regerror("corrupted pointers");
+	return(0);
+}
+
+/*
+ - regrepeat - repeatedly match something simple, report how many
+ */
+static int
+regrepeat( char *p )
+{
+	register int count = 0;
+	register char *scan;
+	register char *opnd;
+
+	scan = reginput;
+	opnd = OPERAND(p);
+	switch (OP(p)) {
+	case ANY:
+		count = strlen(scan);
+		scan += count;
+		break;
+	case EXACTLY:
+		while (*opnd == *scan) {
+			count++;
+			scan++;
+		}
+		break;
+	case ANYOF:
+		while (*scan != '\0' && strchr(opnd, *scan) != NULL) {
+			count++;
+			scan++;
+		}
+		break;
+	case ANYBUT:
+		while (*scan != '\0' && strchr(opnd, *scan) == NULL) {
+			count++;
+			scan++;
+		}
+		break;
+	default:		/* Oh dear.  Called inappropriately. */
+		regerror("internal foulup");
+		count = 0;	/* Best compromise. */
+		break;
+	}
+	reginput = scan;
+
+	return(count);
+}
+
+/*
+ - regnext - dig the "next" pointer out of a node
+ */
+static char *
+regnext( register char *p )
+{
+	register int offset;
+
+	if (p == &regdummy)
+		return(NULL);
+
+	offset = NEXT(p);
+	if (offset == 0)
+		return(NULL);
+
+	if (OP(p) == BACK)
+		return(p-offset);
+	else
+		return(p+offset);
+}
+
+#ifdef DEBUG
+
+STATIC char *regprop();
+
+/*
+ - regdump - dump a regexp onto stdout in vaguely comprehensible form
+ */
+void
+regdump( regexp *r )
+{
+	register char *s;
+	register char op = EXACTLY;	/* Arbitrary non-END op. */
+	register char *next;
+
+
+	s = r->program + 1;
+	while (op != END) {	/* While that wasn't END last time... */
+		op = OP(s);
+		printf("%2d%s", s-r->program, regprop(s));	/* Where, what. */
+		next = regnext(s);
+		if (next == NULL)		/* Next ptr. */
+			printf("(0)");
+		else 
+			printf("(%d)", (s-r->program)+(next-s));
+		s += 3;
+		if (op == ANYOF || op == ANYBUT || op == EXACTLY) {
+			/* Literal string, where present. */
+			while (*s != '\0') {
+				putchar(*s);
+				s++;
+			}
+			s++;
+		}
+		putchar('\n');
+	}
+
+	/* Header fields of interest. */
+	if (r->regstart != '\0')
+		printf("start `%c' ", r->regstart);
+	if (r->reganch)
+		printf("anchored ");
+	if (r->regmust != NULL)
+		printf("must have \"%s\"", r->regmust);
+	printf("\n");
+}
+
+/*
+ - regprop - printable representation of opcode
+ */
+static char *
+regprop( char *op )
+{
+	register char *p;
+	static char buf[50];
+
+	(void) strcpy(buf, ":");
+
+	switch (OP(op)) {
+	case BOL:
+		p = "BOL";
+		break;
+	case EOL:
+		p = "EOL";
+		break;
+	case ANY:
+		p = "ANY";
+		break;
+	case ANYOF:
+		p = "ANYOF";
+		break;
+	case ANYBUT:
+		p = "ANYBUT";
+		break;
+	case BRANCH:
+		p = "BRANCH";
+		break;
+	case EXACTLY:
+		p = "EXACTLY";
+		break;
+	case NOTHING:
+		p = "NOTHING";
+		break;
+	case BACK:
+		p = "BACK";
+		break;
+	case END:
+		p = "END";
+		break;
+	case OPEN+1:
+	case OPEN+2:
+	case OPEN+3:
+	case OPEN+4:
+	case OPEN+5:
+	case OPEN+6:
+	case OPEN+7:
+	case OPEN+8:
+	case OPEN+9:
+		sprintf(buf+strlen(buf), "OPEN%d", OP(op)-OPEN);
+		p = NULL;
+		break;
+	case CLOSE+1:
+	case CLOSE+2:
+	case CLOSE+3:
+	case CLOSE+4:
+	case CLOSE+5:
+	case CLOSE+6:
+	case CLOSE+7:
+	case CLOSE+8:
+	case CLOSE+9:
+		sprintf(buf+strlen(buf), "CLOSE%d", OP(op)-CLOSE);
+		p = NULL;
+		break;
+	case STAR:
+		p = "STAR";
+		break;
+	case PLUS:
+		p = "PLUS";
+		break;
+	case WORDA:
+		p = "WORDA";
+		break;
+	case WORDZ:
+		p = "WORDZ";
+		break;
+	default:
+		regerror("corrupted opcode");
+		break;
+	}
+	if (p != NULL)
+		(void) strcat(buf, p);
+	return(buf);
+}
+#endif
+
+/*
+ * The following is provided for those people who do not have strcspn() in
+ * their C libraries.  They should get off their butts and do something
+ * about it; at least one public-domain implementation of those (highly
+ * useful) string routines has been published on Usenet.
+ */
+#ifdef STRCSPN
+/*
+ * strcspn - find length of initial segment of s1 consisting entirely
+ * of characters not from s2
+ */
+
+static int
+strcspn(
+	char *s1,
+	char *s2 )
+{
+	register char *scan1;
+	register char *scan2;
+	register int count;
+
+	count = 0;
+	for (scan1 = s1; *scan1 != '\0'; scan1++) {
+		for (scan2 = s2; *scan2 != '\0';)	/* ++ moved down. */
+			if (*scan1 == *scan2++)
+				return(count);
+		count++;
+	}
+	return(count);
+}
+#endif

Added: boost-jam/boost-build/branches/upstream/current/jam_src/regexp.h
===================================================================
--- boost-jam/boost-build/branches/upstream/current/jam_src/regexp.h	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/jam_src/regexp.h	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,32 @@
+/*
+ * Definitions etc. for regexp(3) routines.
+ *
+ * Caveat:  this is V8 regexp(3) [actually, a reimplementation thereof],
+ * not the System V one.
+ */
+#ifndef REGEXP_DWA20011023_H
+# define REGEXP_DWA20011023_H
+
+#define NSUBEXP  10
+typedef struct regexp {
+	char *startp[NSUBEXP];
+	char *endp[NSUBEXP];
+	char regstart;		/* Internal use only. */
+	char reganch;		/* Internal use only. */
+	char *regmust;		/* Internal use only. */
+	int regmlen;		/* Internal use only. */
+	char program[1];	/* Unwarranted chumminess with compiler. */
+} regexp;
+
+regexp *regcomp( char *exp );
+int regexec( regexp *prog, char *string );
+void regerror( char *s );
+
+/*
+ * The first byte of the regexp internal "program" is actually this magic
+ * number; the start node begins in the second byte.
+ */
+#define	MAGIC	0234
+
+#endif
+

Added: boost-jam/boost-build/branches/upstream/current/jam_src/rules.c
===================================================================
--- boost-jam/boost-build/branches/upstream/current/jam_src/rules.c	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/jam_src/rules.c	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,782 @@
+/*
+ * Copyright 1993, 1995 Christopher Seiwald.
+ *
+ * This file is part of Jam - see jam.c for Copyright information.
+ */
+
+# include "jam.h"
+# include "lists.h"
+# include "parse.h"
+# include "variable.h"
+# include "rules.h"
+# include "newstr.h"
+# include "hash.h"
+# include "modules.h"
+# include "search.h"
+# include "lists.h"
+# include "pathsys.h"
+# include "timestamp.h"
+
+/*  This file is ALSO:
+ *  Copyright 2001-2004 David Abrahams.
+ *  Distributed under the Boost Software License, Version 1.0.
+ *  (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+ */
+
+/*
+ * rules.c - access to RULEs, TARGETs, and ACTIONs
+ *
+ * External routines:
+ *
+ *    bindrule() - return pointer to RULE, creating it if necessary
+ *    bindtarget() - return pointer to TARGET, creating it if necessary
+ *    touchtarget() - mark a target to simulate being new
+ *    targetlist() - turn list of target names into a TARGET chain
+ *    targetentry() - add a TARGET to a chain of TARGETS
+ *    actionlist() - append to an ACTION chain
+ *    addsettings() - add a deferred "set" command to a target
+#ifndef OPT_FIX_TARGET_VARIABLES_EXT
+ *    usesettings() - set all target specific variables
+#endif
+ *    pushsettings() - set all target specific variables
+ *    popsettings() - reset target specific variables to their pre-push values
+ *    freesettings() - delete a settings list
+ *    donerules() - free RULE and TARGET tables
+ *
+ * 04/12/94 (seiwald) - actionlist() now just appends a single action.
+ * 08/23/94 (seiwald) - Support for '+=' (append to variable)
+ */
+
+static void set_rule_actions( RULE* rule, rule_actions* actions );
+static void set_rule_body( RULE* rule, argument_list* args, PARSE* procedure );
+static struct hash *targethash = 0;
+
+typedef struct _located_target LOCATED_TARGET ;
+
+struct _located_target {
+    char* file_name;
+    TARGET* target;
+};
+static struct hash *located_targets = 0;
+
+
+
+
+/*
+ * enter_rule() - return pointer to RULE, creating it if necessary in
+ * target_module.
+ */
+static RULE *
+enter_rule( char *rulename, module_t *target_module )
+{
+    RULE rule, *r = &rule;
+
+    r->name = rulename;
+
+    if ( hashenter( demand_rules( target_module ), (HASHDATA **)&r ) )
+    {
+        r->name = newstr( rulename );	/* never freed */
+        r->procedure = (PARSE *)0;
+        r->module = 0;
+        r->actions = 0;
+        r->arguments = 0;
+        r->exported = 0;
+        r->module = target_module;
+    }
+    return r;
+}
+
+/*
+ * define_rule() - return pointer to RULE, creating it if necessary in
+ * target_module. Prepare it to accept a body or action originating in
+ * src_module.
+ */
+static RULE *
+define_rule( module_t *src_module, char *rulename, module_t *target_module )
+{
+    RULE *r = enter_rule( rulename, target_module );
+
+    if ( r->module != src_module ) /* if the rule was imported from elsewhere, clear it now */
+    {
+        set_rule_body( r, 0, 0 ); 
+        set_rule_actions( r, 0 );
+        r->module = src_module; /* r will be executed in the source module */
+    }
+
+    return r;
+}
+
+void
+rule_free( RULE* r )
+{
+    freestr( r->name );
+    r->name = "";
+    parse_free( r->procedure );
+    r->procedure = 0;
+	if ( r->arguments )
+	    args_free( r->arguments );
+    r->arguments = 0;
+    if ( r->actions )
+		actions_free( r->actions );
+    r->actions = 0;
+}
+
+/*
+ * bindtarget() - return pointer to TARGET, creating it if necessary
+ */
+
+TARGET *
+bindtarget( const char *targetname )
+{
+	TARGET target, *t = &target;
+
+	if( !targethash )
+	    targethash = hashinit( sizeof( TARGET ), "targets" );
+
+    /* Perforce added const everywhere. No time to merge that change. */
+	t->name = (char*)targetname;
+
+	if( hashenter( targethash, (HASHDATA **)&t ) )
+	{
+	    memset( (char *)t, '\0', sizeof( *t ) );
+	    t->name = newstr( (char*)targetname );	/* never freed */
+	    t->boundname = t->name;		/* default for T_FLAG_NOTFILE */
+	}
+
+	return t;
+}
+
+
+static void bind_explicitly_located_target(void* xtarget, void* data)
+{
+    TARGET* t = (TARGET*)xtarget;
+    if (! (t->flags & T_FLAG_NOTFILE) )
+    {
+        /* Check if there's a setting for LOCATE */
+        SETTINGS* s = t->settings;
+        for(; s ; s = s->next)
+        {            
+            if (strcmp(s->symbol, "LOCATE") == 0) 
+            {
+                pushsettings(t->settings);
+                /* We're binding a target with explicit LOCATE. So
+                   third argument is of now use: nothing will be returned
+                   through it. */
+                t->boundname = search( t->name, &t->time, 0 );
+                popsettings(t->settings);
+                break;
+            }
+        }
+    }
+}
+
+void bind_explicitly_located_targets()
+{
+    if (targethash)
+        hashenumerate(targethash, bind_explicitly_located_target, (void*)0);
+}
+
+/* TODO: this is probably not a good idea to use functions in other modules like
+  that. */
+void call_bind_rule(char* target, char* boundname);
+
+TARGET* search_for_target ( char * name, LIST* search_path )
+{
+    PATHNAME f[1];
+    string buf[1];
+    LOCATED_TARGET lt, *lta = &lt;
+    time_t time;
+    int found = 0;
+    TARGET* result;
+
+    string_new( buf );
+
+	path_parse( name, f );
+
+    f->f_grist.ptr = 0;
+    f->f_grist.len = 0;
+
+    while( search_path )
+    {
+        f->f_root.ptr = search_path->string;
+        f->f_root.len = strlen( search_path->string );
+
+        string_truncate( buf, 0 );
+        path_build( f, buf, 1 );
+
+        lt.file_name = buf->value ;
+
+        if (! located_targets )
+            located_targets = hashinit( sizeof(LOCATED_TARGET),
+                                        "located targets" );
+
+
+        if ( hashcheck( located_targets, (HASHDATA **)&lta ) )
+        {
+            return lta->target;
+        }
+
+        timestamp( buf->value, &time );
+        if (time)
+        {
+            found = 1;
+            break;
+        }
+
+        search_path = list_next( search_path );
+    }
+
+    if ( ! found )
+    {
+        f->f_root.ptr = 0;
+        f->f_root.len = 0;
+
+        string_truncate( buf, 0 );
+        path_build( f, buf, 1 );
+
+        timestamp( buf->value, &time );        
+    }
+
+    result = bindtarget( name );
+    result->boundname = newstr( buf->value );
+    result->time = time;
+    result->binding = time ? T_BIND_EXISTS : T_BIND_MISSING;
+
+    call_bind_rule( result->name, result->boundname );
+    
+    string_free( buf );
+
+    return result;
+
+}
+
+/*
+ * copytarget() - make a new target with the old target's name
+ *
+ * Not entered into hash table -- for internal nodes.
+ */
+
+TARGET *
+copytarget( const TARGET *ot )
+{
+	TARGET *t;
+
+	t = (TARGET *)malloc( sizeof( *t ) );
+	memset( (char *)t, '\0', sizeof( *t ) );
+	t->name = copystr( ot->name );
+	t->boundname = t->name;
+
+	t->flags |= T_FLAG_NOTFILE | T_FLAG_INTERNAL;
+
+	return t;
+}
+
+/*
+ * touchtarget() - mark a target to simulate being new
+ */
+
+void
+touchtarget( char *t )
+{
+	bindtarget( t )->flags |= T_FLAG_TOUCHED;
+}
+
+/*
+ * targetlist() - turn list of target names into a TARGET chain
+ *
+ * Inputs:
+ *	chain	existing TARGETS to append to
+ *	targets	list of target names
+ */
+
+TARGETS *
+targetlist( 
+	TARGETS	*chain,
+	LIST 	*targets )
+{
+	for( ; targets; targets = list_next( targets ) )
+	    chain = targetentry( chain, bindtarget( targets->string ) );
+
+	return chain;
+}
+
+/*
+ * targetentry() - add a TARGET to a chain of TARGETS
+ *
+ * Inputs:
+ *	chain	exisitng TARGETS to append to
+ *	target	new target to append
+ */
+
+TARGETS *
+targetentry( 
+	TARGETS	*chain,
+	TARGET	*target )
+{
+	TARGETS *c;
+
+	c = (TARGETS *)malloc( sizeof( TARGETS ) );
+	c->target = target;
+
+	if( !chain ) chain = c;
+	else chain->tail->next = c;
+	chain->tail = c;
+	c->next = 0;
+
+	return chain;
+}
+
+/*
+ * targetchain() - append two TARGET chains
+ *
+ * Inputs:
+ *	chain	exisitng TARGETS to append to
+ *	target	new target to append
+ */
+
+TARGETS *
+targetchain( 
+	TARGETS	*chain,
+	TARGETS	*targets )
+{
+	TARGETS *c;
+
+	if( !targets )
+	    return chain;
+	else if( !chain )
+	    return targets;
+
+	chain->tail->next = targets;
+	chain->tail = targets->tail;
+
+	return chain;
+}
+
+/*
+ * actionlist() - append to an ACTION chain
+ */
+
+ACTIONS *
+actionlist(
+	ACTIONS	*chain,
+	ACTION	*action )
+{
+	ACTIONS *actions = (ACTIONS *)malloc( sizeof( ACTIONS ) );
+
+	actions->action = action;
+
+	if( !chain ) chain = actions;
+	else chain->tail->next = actions;
+	chain->tail = actions;
+	actions->next = 0;
+
+	return chain;
+}
+
+static SETTINGS* settings_freelist;
+
+/*
+ * addsettings() - add a deferred "set" command to a target
+ *
+ * Adds a variable setting (varname=list) onto a chain of settings
+ * for a particular target.  Replaces the previous previous value,
+ * if any, unless 'append' says to append the new list onto the old.
+ * Returns the head of the chain of settings.
+ */
+
+SETTINGS *
+addsettings(
+	SETTINGS *head,
+	int	append,
+	char	*symbol,
+	LIST	*value )
+{
+	SETTINGS *v;
+	
+	/* Look for previous setting */
+
+	for( v = head; v; v = v->next )
+	    if( !strcmp( v->symbol, symbol ) )
+		break;
+
+	/* If not previously set, alloc a new. */
+	/* If appending, do so. */
+	/* Else free old and set new. */
+
+	if( !v )
+	{
+        v = settings_freelist;
+        
+        if ( v )
+            settings_freelist = v->next;
+        else
+            v = (SETTINGS *)malloc( sizeof( *v ) );
+        
+	    v->symbol = newstr( symbol );
+	    v->value = value;
+	    v->next = head;
+	    head = v;
+	}
+	else if( append )
+	{
+	    v->value = list_append( v->value, value );
+	}
+	else
+	{
+	    list_free( v->value );
+	    v->value = value;
+	} 
+
+	/* Return (new) head of list. */
+
+	return head;
+}
+
+/*
+ * pushsettings() - set all target specific variables
+ */
+
+void
+pushsettings( SETTINGS *v )
+{
+	for( ; v; v = v->next )
+	    v->value = var_swap( v->symbol, v->value );
+}
+
+/*
+ * popsettings() - reset target specific variables to their pre-push values
+ */
+
+void
+popsettings( SETTINGS *v )
+{
+	pushsettings( v );	/* just swap again */
+}
+
+/*
+ * copysettings() - duplicate a settings list, returning the new copy
+ */
+SETTINGS*
+copysettings( SETTINGS *head )
+{
+    SETTINGS *copy = 0, *v;
+
+    for (v = head; v; v = v->next)
+	copy = addsettings(copy, 0, v->symbol, list_copy(0, v->value));
+
+    return copy;
+}
+
+/*
+ *    freetargets() - delete a targets list
+ */
+void freetargets( TARGETS *chain )
+{
+    while( chain )
+    {
+        TARGETS* n = chain->next;
+        free( chain );
+        chain = n;
+    }
+}
+
+/*
+ *    freeactions() - delete an action list
+ */
+void freeactions( ACTIONS *chain )
+{
+    while( chain )
+    {
+        ACTIONS* n = chain->next;
+        free( chain );
+        chain = n;
+    }
+}
+
+
+/*
+ *    freesettings() - delete a settings list
+ */
+
+void
+freesettings( SETTINGS *v )
+{
+	while( v )
+	{
+	    SETTINGS *n = v->next;
+
+	    freestr( v->symbol );
+	    list_free( v->value );
+        v->next = settings_freelist;
+        settings_freelist = v;
+
+	    v = n;
+	}
+}
+
+static void freetarget( void *xt, void *data )
+{
+    TARGET* t = (TARGET *)xt;
+    if ( t->settings )
+        freesettings( t->settings );
+    if ( t->depends )
+        freetargets( t->depends );
+    if ( t->includes )
+        freetarget( t->includes, (void*)0);
+    if ( t->actions )
+        freeactions( t->actions );
+}
+
+/*
+ * donerules() - free TARGET tables
+ */
+
+void
+donerules()
+{
+     hashenumerate( targethash, freetarget, 0 );
+	hashdone( targethash );
+    while ( settings_freelist )
+    {
+        SETTINGS* n = settings_freelist->next;
+        free( settings_freelist );
+        settings_freelist = n;
+    }
+}
+
+/*
+ * args_new() - make a new reference-counted argument list
+ */
+argument_list* args_new()
+{
+    argument_list* r = (argument_list*)malloc( sizeof(argument_list) );
+    r->reference_count = 0;
+    lol_init(r->data);
+    return r;
+}
+
+/*
+ * args_refer() - add a new reference to the given argument list
+ */
+void args_refer( argument_list* a )
+{
+    ++a->reference_count;
+}
+
+/*
+ * args_free() - release a reference to the given argument list
+ */
+void args_free( argument_list* a )
+{
+    if (--a->reference_count <= 0)
+    {
+        lol_free(a->data);
+        free(a);
+    }
+}
+
+/*
+ * actions_refer() - add a new reference to the given actions
+ */
+void actions_refer(rule_actions* a)
+{
+    ++a->reference_count;
+}
+
+/*
+ * actions_free() - release a reference to the given actions
+ */
+void actions_free(rule_actions* a)
+{
+    if (--a->reference_count <= 0)
+    {
+        freestr(a->command);
+        list_free(a->bindlist);
+        free(a);
+    }
+}
+
+/*
+ * set_rule_body() - set the argument list and procedure of the given rule
+ */
+static void set_rule_body( RULE* rule, argument_list* args, PARSE* procedure )
+{
+    if ( args )
+        args_refer( args );
+    if ( rule->arguments )
+        args_free( rule->arguments );
+    rule->arguments = args;
+    
+    if ( procedure )
+        parse_refer( procedure );
+    if ( rule->procedure )
+        parse_free( rule->procedure );
+    rule->procedure = procedure;
+}
+
+/*
+ * global_name() - given a rule, return the name for a corresponding rule in the global module
+ */
+static char* global_rule_name( RULE* r )
+{
+    if ( r->module == root_module() )
+    {
+        return r->name;
+    }
+    else
+    {
+        char name[4096] = "";
+        strncat(name, r->module->name, sizeof(name) - 1);
+        strncat(name, r->name, sizeof(name) - 1 );
+        return newstr(name);
+    }
+}
+
+/*
+ * global_rule() - given a rule, produce the corresponding entry in the global module
+ */
+static RULE* global_rule( RULE* r )
+{
+    if ( r->module == root_module() )
+    {
+        return r;
+    }
+    else
+    {
+        char* name = global_rule_name( r );
+        RULE* result = define_rule( r->module, name, root_module() );
+        freestr(name);
+        return result;
+    }
+}
+
+/*
+ * new_rule_body() - make a new rule named rulename in the given
+ * module, with the given argument list and procedure. If exported is
+ * true, the rule is exported to the global module as
+ * modulename.rulename.
+ */
+RULE* new_rule_body( module_t* m, char* rulename, argument_list* args, PARSE* procedure, int exported )
+{
+    RULE* local = define_rule( m, rulename, m );
+    local->exported = exported;
+    set_rule_body( local, args, procedure );
+    
+    /* Mark the procedure with the global rule name, regardless of
+     * whether the rule is exported. That gives us something
+     * reasonably identifiable that we can use, e.g. in profiling
+     * output. Only do this once, since this could be called multiple
+     * times with the same procedure.
+     */
+    if ( procedure->rulename == 0 )
+        procedure->rulename = global_rule_name( local );
+
+    return local;
+}
+
+static void set_rule_actions( RULE* rule, rule_actions* actions )
+{
+    if ( actions )
+        actions_refer( actions );
+    if ( rule->actions )
+        actions_free( rule->actions );
+    rule->actions = actions;
+    
+}
+
+static rule_actions* actions_new( char* command, LIST* bindlist, int flags )
+{
+    rule_actions* result = (rule_actions*)malloc(sizeof(rule_actions));
+    result->command = copystr( command );
+    result->bindlist = bindlist;
+    result->flags = flags;
+    result->reference_count = 0;
+    return result;
+}
+
+RULE* new_rule_actions( module_t* m, char* rulename, char* command, LIST* bindlist, int flags )
+{
+    RULE* local = define_rule( m, rulename, m );
+    RULE* global = global_rule( local );
+    set_rule_actions( local, actions_new( command, bindlist, flags ) );
+    set_rule_actions( global, local->actions );
+    return local;
+}
+
+/* Looks for a rule in the specified module, and returns it, if found.
+   First checks if the rule is present in the module's rule table.
+   Second, if name of the rule is in the form name1.name2 and name1 is in 
+   the list of imported modules, look in module 'name1' for rule 'name2'.
+*/
+RULE *lookup_rule( char *rulename, module_t *m, int local_only )
+{
+    RULE rule, *r = &rule, *result = 0;
+    module_t* original_module = m;
+    r->name = rulename;
+
+    if (m->class_module)
+        m = m->class_module;
+
+    if (m->rules && hashcheck( m->rules, (HASHDATA **)&r ) )
+        result = r;
+    else if (!local_only && m->imported_modules) {
+        /* Try splitting the name into module and rule. */
+        char *p = strchr(r->name, '.') ;
+        if (p) {
+            *p = '\0';
+            /* Now, r->name keeps the module name, and p+1 keeps the rule name. */
+            if (hashcheck( m->imported_modules, (HASHDATA **)&r))
+            {
+                result = lookup_rule(p+1, bindmodule(rulename), 1);
+            }
+            *p = '.';
+        }        
+    }
+
+    if (result)
+    {
+        if (local_only && !result->exported)
+            result = 0;
+        else
+        {
+            /* Lookup started in class module. We've found a rule in class module,
+               which is marked for execution in that module, or in some instances.
+               Mark it for execution in the instance where we've started lookup.
+            */
+            int execute_in_class = (result->module == m);
+            int execute_in_some_instance = 
+            (result->module->class_module && result->module->class_module == m);
+            if (original_module != m && (execute_in_class || execute_in_some_instance))
+                result->module = original_module;            
+        }
+    }
+
+    return result;
+        
+}
+
+
+RULE *bindrule( char *rulename, module_t* m)
+{
+    RULE *result;
+
+    result = lookup_rule(rulename, m, 0);
+    if (!result)
+        result = lookup_rule(rulename, root_module(), 0);
+    /* We've only one caller, 'evaluate_rule', which will complain about 
+       calling underfined rule. We could issue the error
+       here, but we don't have necessary information, such as frame.
+    */
+    if (!result)
+        result = enter_rule( rulename, root_module() );
+
+    return result;
+}
+
+RULE* import_rule( RULE* source, module_t* m, char* name )
+{
+    RULE* dest = define_rule( source->module, name, m );
+    set_rule_body( dest, source->arguments, source->procedure );
+    set_rule_actions( dest, source->actions );
+    return dest;
+}

Added: boost-jam/boost-build/branches/upstream/current/jam_src/rules.h
===================================================================
--- boost-jam/boost-build/branches/upstream/current/jam_src/rules.h	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/jam_src/rules.h	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,255 @@
+/*
+ * Copyright 1993, 1995 Christopher Seiwald.
+ *
+ * This file is part of Jam - see jam.c for Copyright information.
+ */
+
+/*  This file is ALSO:
+ *  Copyright 2001-2004 David Abrahams.
+ *  Distributed under the Boost Software License, Version 1.0.
+ *  (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+ */
+
+#ifndef RULES_DWA_20011020_H
+# define RULES_DWA_20011020_H
+
+# include "modules.h"
+# include "jam.h"
+# include "parse.h"
+
+/*
+ * rules.h -  targets, rules, and related information
+ *
+ * This file describes the structures holding the targets, rules, and
+ * related information accumulated by interpreting the statements
+ * of the jam files.
+ *
+ * The following are defined:
+ *
+ *	RULE - a generic jam rule, the product of RULE and ACTIONS 
+ *	ACTIONS - a chain of ACTIONs 
+ *	ACTION - a RULE instance with targets and sources 
+ *	SETTINGS - variables to set when executing a TARGET's ACTIONS 
+ *	TARGETS - a chain of TARGETs 
+ *	TARGET - a file or "thing" that can be built 
+ *
+ * 04/11/94 (seiwald) - Combined deps & headers into deps[2] in TARGET.
+ * 04/12/94 (seiwald) - actionlist() now just appends a single action.
+ * 06/01/94 (seiwald) - new 'actions existing' does existing sources
+ * 12/20/94 (seiwald) - NOTIME renamed NOTFILE.
+ * 01/19/95 (seiwald) - split DONTKNOW into CANTFIND/CANTMAKE.
+ * 02/02/95 (seiwald) - new LEAVES modifier on targets.
+ * 02/14/95 (seiwald) - new NOUPDATE modifier on targets.
+ */
+
+typedef struct _rule RULE;
+typedef struct _target TARGET;
+typedef struct _targets TARGETS;
+typedef struct _action ACTION;
+typedef struct _actions ACTIONS;
+typedef struct _settings SETTINGS ;
+
+/* RULE - a generic jam rule, the product of RULE and ACTIONS */
+
+/* A rule's argument list */
+struct argument_list
+{
+    int reference_count;
+    LOL data[1];
+};
+
+/* The build actions corresponding to a rule */
+struct rule_actions
+{
+    int reference_count;
+    char* command;       /* command string from ACTIONS */
+    LIST* bindlist;
+    int flags;          /* modifiers on ACTIONS */
+
+# define    RULE_NEWSRCS    0x01    /* $(>) is updated sources only */
+# define    RULE_TOGETHER   0x02    /* combine actions on single target */
+# define    RULE_IGNORE 0x04    /* ignore return status of executes */
+# define    RULE_QUIETLY    0x08    /* don't mention it unless verbose */
+# define    RULE_PIECEMEAL  0x10    /* split exec so each $(>) is small */
+# define    RULE_EXISTING   0x20    /* $(>) is pre-exisitng sources only */
+};
+
+typedef struct rule_actions rule_actions;
+typedef struct argument_list argument_list;
+
+struct _rule {
+    char    *name;
+    PARSE   *procedure;        /* parse tree from RULE */
+    argument_list* arguments;  /* argument checking info, or NULL for unchecked */
+    rule_actions* actions;     /* build actions, or NULL for no actions */
+    module_t  *module;           /* module in which this rule is executed */
+    int     exported;          /* nonzero if this rule is supposed to
+                                * appear in the global module and be
+                                * automatically imported into other modules
+                                */
+};
+
+/* ACTIONS - a chain of ACTIONs */
+
+struct _actions {
+	ACTIONS	*next;
+	ACTIONS	*tail;			/* valid only for head */
+	ACTION	*action;
+} ;
+
+/* ACTION - a RULE instance with targets and sources */
+
+struct _action {
+	RULE	*rule;
+	TARGETS	*targets;
+	TARGETS	*sources;		/* aka $(>) */
+	char	running;		/* has been started */
+	char	status;			/* see TARGET status */
+} ;
+
+/* SETTINGS - variables to set when executing a TARGET's ACTIONS */
+
+struct _settings {
+	SETTINGS *next;
+	char	*symbol;		/* symbol name for var_set() */
+	LIST	*value;			/* symbol value for var_set() */
+} ;
+
+/* TARGETS - a chain of TARGETs */
+
+struct _targets {
+	TARGETS	*next;
+	TARGETS	*tail;			/* valid only for head */
+	TARGET	*target;
+} ;
+
+/* TARGET - a file or "thing" that can be built */
+
+struct _target {
+	char	*name;
+	char	*boundname;		/* if search() relocates target */
+	ACTIONS	*actions;		/* rules to execute, if any */
+	SETTINGS *settings;		/* variables to define */
+
+	short flags;    		/* status info */
+
+# define 	T_FLAG_TEMP 	0x0001	/* TEMPORARY applied */
+# define 	T_FLAG_NOCARE 	0x0002	/* NOCARE applied */
+# define 	T_FLAG_NOTFILE 	0x0004	/* NOTFILE applied */
+# define	T_FLAG_TOUCHED	0x0008	/* ALWAYS applied or -t target */
+# define	T_FLAG_LEAVES	0x0010	/* LEAVES applied */
+# define	T_FLAG_NOUPDATE	0x0020	/* NOUPDATE applied */
+# define	T_FLAG_VISITED  0x0040    /* CWM: Used in debugging */
+
+/* this flag was added to support a new builtin rule named "RMBAD" */
+/* it is used to force removal of outdated targets whose dependencies
+ * fail to build  */
+    
+# define        T_FLAG_RMOLD    0x0080    /* RMBAD applied */
+
+/* this flag was added to support a new builting rule named "FAIL_EXPECTED" */
+/* it is used to indicate that the result of running a given action should  */
+/* be inverted (i.e. ok <=> fail). This is useful to launch certain test    */
+/* runs from a Jamfile..                                                    */
+/*                                                                          */
+# define        T_FLAG_FAIL_EXPECTED  0x0100  /* FAIL_EXPECTED applied */
+
+# define T_FLAG_INTERNAL 0x0200    /* internal INCLUDES node */
+
+
+
+#ifdef OPT_SEMAPHORE
+# define 	T_MAKE_SEMAPHORE 5 /* Special target type for semaphores */
+#endif
+
+
+	char	binding;		/* how target relates to real file */
+
+# define 	T_BIND_UNBOUND	0	/* a disembodied name */
+# define 	T_BIND_MISSING	1	/* couldn't find real file */
+#ifdef OPT_SEMAPHORE
+	TARGET  *semaphore;		/* used in serialization */
+#endif
+# define 	T_BIND_PARENTS	2	/* using parent's timestamp */
+# define 	T_BIND_EXISTS	3	/* real file, timestamp valid */
+
+	TARGETS		*depends;	/* dependencies */
+	TARGET		*includes;	/* includes */
+    TARGET        *original_target; /* original_target->includes = this */
+    char rescanned;
+
+	time_t	time;			/* update time */
+	time_t	leaf;			/* update time of leaf sources */
+
+	char	fate;			/* make0()'s diagnosis */
+
+# define 	T_FATE_INIT	0	/* nothing done to target */
+# define 	T_FATE_MAKING	1	/* make0(target) on stack */
+
+# define 	T_FATE_STABLE	2	/* target didn't need updating */
+# define	T_FATE_NEWER	3	/* target newer than parent */
+
+# define	T_FATE_SPOIL	4	/* >= SPOIL rebuilds parents */
+# define 	T_FATE_ISTMP	4	/* unneeded temp target oddly present */
+
+# define	T_FATE_BUILD	5	/* >= BUILD rebuilds target */
+# define	T_FATE_TOUCHED	5	/* manually touched with -t */
+# define	T_FATE_MISSING	6	/* is missing, needs updating */
+# define	T_FATE_NEEDTMP	7	/* missing temp that must be rebuild */
+# define 	T_FATE_OUTDATED	8	/* is out of date, needs updating */
+# define 	T_FATE_UPDATE	9	/* deps updated, needs updating */
+
+# define 	T_FATE_BROKEN	10	/* >= BROKEN ruins parents */
+# define 	T_FATE_CANTFIND	10	/* no rules to make missing target */
+# define 	T_FATE_CANTMAKE	11	/* can't find dependents */
+
+	char	progress;		/* tracks make1() progress */
+
+# define	T_MAKE_INIT	0	/* make1(target) not yet called */
+# define	T_MAKE_ONSTACK	1	/* make1(target) on stack */
+# define	T_MAKE_ACTIVE	2	/* make1(target) in make1b() */
+# define	T_MAKE_RUNNING	3	/* make1(target) running commands */
+# define	T_MAKE_DONE	4	/* make1(target) done */
+
+	char	status;			/* execcmd() result */
+
+	int	asynccnt;		/* child deps outstanding */
+	TARGETS	*parents;		/* used by make1() for completion */
+	char	*cmds;			/* type-punned command list */
+
+    char* failed;
+} ;
+
+RULE 	*bindrule( char *rulename, module_t* );
+
+RULE*   import_rule( RULE* source, module_t* m, char* name );
+RULE*   new_rule_body( module_t* m, char* rulename, argument_list* args, PARSE* procedure, int exprt );
+RULE*   new_rule_actions( module_t* m, char* rulename, char* command, LIST* bindlist, int flags );
+TARGET  *bindtarget( const char *targetname );
+TARGET *copytarget( const TARGET *t );
+void bind_explicitly_located_targets();
+TARGET* search_for_target( char * name, LIST* search_path );
+void 	touchtarget( char *t );
+TARGETS *targetlist( TARGETS *chain, LIST  *targets );
+TARGETS *targetentry( TARGETS *chain, TARGET *target );
+TARGETS *targetchain( TARGETS *chain, TARGETS *targets );
+void freetargets( TARGETS *chain );
+ACTIONS *actionlist( ACTIONS *chain, ACTION *action );
+void freeactions( ACTIONS *chain );
+SETTINGS *addsettings( SETTINGS *head, int append, char *symbol, LIST *value );
+void 	pushsettings( SETTINGS *v );
+void 	popsettings( SETTINGS *v );
+SETTINGS *copysettings( SETTINGS *v );
+void 	freesettings( SETTINGS *v );
+void    rule_free( RULE *r );
+void	donerules();
+
+argument_list* args_new();
+void    args_refer( argument_list* );
+void    args_free( argument_list* );
+
+void actions_refer(rule_actions*);
+void actions_free(rule_actions*);
+
+#endif
+

Added: boost-jam/boost-build/branches/upstream/current/jam_src/scan.c
===================================================================
--- boost-jam/boost-build/branches/upstream/current/jam_src/scan.c	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/jam_src/scan.c	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,424 @@
+/*
+ * Copyright 1993-2002 Christopher Seiwald and Perforce Software, Inc.
+ *
+ * This file is part of Jam - see jam.c for Copyright information.
+ */
+
+# include "jam.h"
+# include "lists.h"
+# include "parse.h"
+# include "scan.h"
+# include "jamgram.h"
+# include "jambase.h"
+# include "newstr.h"
+
+/*
+ * scan.c - the jam yacc scanner
+ *
+ * 12/26/93 (seiwald) - bump buf in yylex to 10240 - yuk.
+ * 09/16/94 (seiwald) - check for overflows, unmatched {}'s, etc.
+ *			Also handle tokens abutting EOF by remembering
+ *			to return EOF now matter how many times yylex()
+ *			reinvokes yyline().
+ * 02/11/95 (seiwald) - honor only punctuation keywords if SCAN_PUNCT.
+ * 07/27/95 (seiwald) - Include jamgram.h after scan.h, so that YYSTYPE is
+ *			defined before Linux's yacc tries to redefine it.
+ */
+
+struct keyword {
+	char *word;
+	int type;
+} keywords[] = {
+# include "jamgramtab.h"
+	{ 0, 0 }
+} ;
+
+struct include {
+	struct include *next;	/* next serial include file */
+	char 	*string;	/* pointer into current line */
+	char	**strings;	/* for yyfparse() -- text to parse */
+	FILE 	*file;		/* for yyfparse() -- file being read */
+	char 	*fname;		/* for yyfparse() -- file name */
+	int 	line;		/* line counter for error messages */
+	char 	buf[ 512 ];	/* for yyfparse() -- line buffer */
+} ;
+
+static struct include *incp = 0; /* current file; head of chain */
+
+static int scanmode = SCAN_NORMAL;
+static int anyerrors = 0;
+static char *symdump( YYSTYPE *s );
+
+# define BIGGEST_TOKEN 10240	/* no single token can be larger */
+
+/* 
+ * Set parser mode: normal, string, or keyword
+ */
+
+void
+yymode( int n )
+{
+	scanmode = n;
+}
+
+void
+yyerror( char *s )
+{
+	if( incp )
+	    printf( "%s:%d: ", incp->fname, incp->line );
+
+	printf( "%s at %s\n", s, symdump( &yylval ) );
+
+	++anyerrors;
+}
+
+int
+yyanyerrors()
+{
+	return anyerrors != 0;
+}
+
+void
+yyfparse( char *s )
+{
+	struct include *i = (struct include *)malloc( sizeof( *i ) );
+
+	/* Push this onto the incp chain. */
+
+	i->string = "";
+	i->strings = 0;
+	i->file = 0;
+	i->fname = copystr( s );
+	i->line = 0;
+	i->next = incp;
+	incp = i;
+
+	/* If the filename is "+", it means use the internal jambase. */
+
+	if( !strcmp( s, "+" ) )
+	    i->strings = jambase;
+}
+
+/*
+ * yyline() - read new line and return first character
+ *
+ * Fabricates a continuous stream of characters across include files,
+ * returning EOF at the bitter end.
+ */
+
+int
+yyline()
+{
+	struct include *i = incp;
+
+	if( !incp )
+	    return EOF;
+
+	/* Once we start reading from the input stream, we reset the */
+	/* include insertion point so that the next include file becomes */
+	/* the head of the list. */
+
+	/* If there is more data in this line, return it. */
+
+	if( *i->string )
+	    return *i->string++;
+
+	/* If we're reading from an internal string list, go to the */
+	/* next string. */
+
+	if( i->strings )
+	{
+	    if( !*i->strings )
+		goto next;
+
+	    i->line++;
+	    i->string = *(i->strings++);
+	    return *i->string++;
+	}
+
+	/* If necessary, open the file */
+
+	if( !i->file )
+	{
+	    FILE *f = stdin;
+
+	    if( strcmp( i->fname, "-" ) && !( f = fopen( i->fname, "r" ) ) )
+		perror( i->fname );
+
+	    i->file = f;
+	}
+
+	/* If there's another line in this file, start it. */
+
+	if( i->file && fgets( i->buf, sizeof( i->buf ), i->file ) )
+	{
+	    i->line++;
+	    i->string = i->buf;
+	    return *i->string++;
+	}
+
+    next:
+	/* This include is done.  */
+	/* Free it up and return EOF so yyparse() returns to parse_file(). */
+
+	incp = i->next;
+
+	/* Close file, free name */
+
+	if( i->file && i->file != stdin )
+	    fclose( i->file );
+	freestr( i->fname );
+	free( (char *)i );
+
+	return EOF;
+}
+
+/*
+ * yylex() - set yylval to current token; return its type
+ *
+ * Macros to move things along:
+ *
+ *	yychar() - return and advance character; invalid after EOF
+ *	yyprev() - back up one character; invalid before yychar()
+ *
+ * yychar() returns a continuous stream of characters, until it hits
+ * the EOF of the current include file.
+ */
+
+# define yychar() ( *incp->string ? *incp->string++ : yyline() )
+# define yyprev() ( incp->string-- )
+
+int
+yylex()
+{
+	int c;
+	char buf[BIGGEST_TOKEN];
+	char *b = buf;
+
+	if( !incp )
+	    goto eof;
+
+	/* Get first character (whitespace or of token) */
+
+	c = yychar();
+
+	if( scanmode == SCAN_STRING )
+	{
+	    /* If scanning for a string (action's {}'s), look for the */
+	    /* closing brace.  We handle matching braces, if they match! */
+
+	    int nest = 1;
+
+	    while( c != EOF && b < buf + sizeof( buf ) )
+	    {
+		    if( c == '{' )
+			nest++;
+
+		    if( c == '}' && !--nest )
+			break;
+
+		    *b++ = c;
+
+		    c = yychar();
+
+                    /* turn trailing "\r\n" sequences into plain "\n"
+                     * for Cygwin
+                     */
+                    if (c == '\n' && b[-1] == '\r')
+                        --b;
+	    }
+
+	    /* We ate the ending brace -- regurgitate it. */
+
+	    if( c != EOF )
+		yyprev();
+
+	    /* Check obvious errors. */
+
+	    if( b == buf + sizeof( buf ) )
+	    {
+		yyerror( "action block too big" );
+		goto eof;
+	    }
+
+	    if( nest )
+	    {
+		yyerror( "unmatched {} in action block" );
+		goto eof;
+	    }
+
+	    *b = 0;
+	    yylval.type = STRING;
+	    yylval.string = newstr( buf );
+        yylval.file = incp->fname;
+        yylval.line = incp->line;
+        
+	}
+	else
+	{
+	    char *b = buf;
+	    struct keyword *k;
+	    int inquote = 0;
+	    int notkeyword;
+		
+	    /* Eat white space */
+
+	    for( ;; )
+	    {
+            /* Skip past white space */
+
+            while( c != EOF && isspace( c ) )
+                c = yychar();
+
+            /* Not a comment?  Swallow up comment line. */
+
+            if( c != '#' )
+                break;
+            while( ( c = yychar() ) != EOF && c != '\n' )
+                ;
+	    }
+
+	    /* c now points to the first character of a token. */
+
+	    if( c == EOF )
+		goto eof;
+
+        yylval.file = incp->fname;
+        yylval.line = incp->line;
+        
+	    /* While scanning the word, disqualify it for (expensive) */
+	    /* keyword lookup when we can: $anything, "anything", \anything */
+
+	    notkeyword = c == '$';
+
+	    /* look for white space to delimit word */
+	    /* "'s get stripped but preserve white space */
+	    /* \ protects next character */
+
+	    while( 
+		c != EOF &&
+		b < buf + sizeof( buf ) &&
+		( inquote || !isspace( c ) ) )
+	    {
+		if( c == '"' )
+		{
+		    /* begin or end " */
+		    inquote = !inquote;
+		    notkeyword = 1;
+		}
+		else if( c != '\\' )
+		{
+		    /* normal char */
+		    *b++ = c;
+		}
+		else if( ( c = yychar()) != EOF )
+	    {
+		    /* \c */
+		    *b++ = c;
+		    notkeyword = 1;
+		}
+		else
+		{
+		    /* \EOF */
+		    break;
+		}
+
+		c = yychar();
+	    }
+
+	    /* Check obvious errors. */
+
+	    if( b == buf + sizeof( buf ) )
+	    {
+		yyerror( "string too big" );
+		goto eof;
+	    }
+
+	    if( inquote )
+	    {
+		yyerror( "unmatched \" in string" );
+		goto eof;
+	    }
+
+	    /* We looked ahead a character - back up. */
+
+	    if( c != EOF )
+		yyprev();
+
+	    /* scan token table */
+	    /* don't scan if it's obviously not a keyword or if its */
+	    /* an alphabetic when were looking for punctuation */
+
+	    *b = 0;
+	    yylval.type = ARG;
+
+	    if( !notkeyword && !( isalpha( *buf ) && scanmode == SCAN_PUNCT ) )
+	    {
+		for( k = keywords; k->word; k++ )
+		    if( *buf == *k->word && !strcmp( k->word, buf ) )
+		{
+		    yylval.type = k->type;
+		    yylval.string = k->word;	/* used by symdump */
+		    break;
+		}
+	    }
+
+	    if( yylval.type == ARG )
+		yylval.string = newstr( buf );
+	}
+
+	if( DEBUG_SCAN )
+		printf( "scan %s\n", symdump( &yylval ) );
+
+	return yylval.type;
+
+eof:
+    yylval.file = "end-of-input"; /* just in case */
+    yylval.line = 0;
+        
+	yylval.type = EOF;
+	return yylval.type;
+}
+
+static char *
+symdump( YYSTYPE *s )
+{
+	static char buf[ BIGGEST_TOKEN + 20 ];
+
+	switch( s->type )
+	{
+	case EOF:
+		sprintf( buf, "EOF" );
+		break;
+	case 0:
+		sprintf( buf, "unknown symbol %s", s->string );
+		break;
+	case ARG:
+		sprintf( buf, "argument %s", s->string );
+		break;
+	case STRING:
+		sprintf( buf, "string \"%s\"", s->string );
+		break;
+	default:
+		sprintf( buf, "keyword %s", s->string );
+		break;
+	}
+	return buf;
+}
+
+/*  Get information about the current file and line, for those epsilon
+ *  transitions that produce a parse
+ */
+void yyinput_stream( char** name, int* line )
+{
+    if (incp)
+    {
+        *name = incp->fname;
+        *line = incp->line;
+    }
+    else
+    {
+        *name = "(builtin)";
+        *line = -1;
+    }
+}

Added: boost-jam/boost-build/branches/upstream/current/jam_src/scan.h
===================================================================
--- boost-jam/boost-build/branches/upstream/current/jam_src/scan.h	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/jam_src/scan.h	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,55 @@
+/*
+ * Copyright 1993, 1995 Christopher Seiwald.
+ *
+ * This file is part of Jam - see jam.c for Copyright information.
+ */
+
+/*
+ * scan.h - the jam yacc scanner
+ *
+ * External functions:
+ *
+ *	yyerror( char *s ) - print a parsing error message
+ *	yyfparse( char *s ) - scan include file s
+ *	yylex() - parse the next token, returning its type
+ *	yymode() - adjust lexicon of scanner
+ *	yyparse() - declaration for yacc parser
+ *	yyanyerrors() - indicate if any parsing errors occured
+ *
+ * The yymode() function is for the parser to adjust the lexicon of the
+ * scanner.  Aside from normal keyword scanning, there is a mode to
+ * handle action strings (look only for the closing }) and a mode to 
+ * ignore most keywords when looking for a punctuation keyword.  This 
+ * allows non-punctuation keywords to be used in lists without quoting.
+ */
+
+/*
+ * YYSTYPE - value of a lexical token
+ */
+
+# define YYSTYPE YYSYMBOL
+
+typedef struct _YYSTYPE {
+    int     type;
+    char    *string;
+    PARSE   *parse;
+    LIST    *list;
+    int     number;
+    char    *file;
+    int     line;
+} YYSTYPE;
+
+extern YYSTYPE yylval;
+
+void yymode( int n );
+void yyerror( char *s );
+int yyanyerrors();
+void yyfparse( char *s );
+int yyline();
+int yylex();
+int yyparse();
+void yyinput_stream( char** name, int* line );
+
+# define SCAN_NORMAL	0	/* normal parsing */
+# define SCAN_STRING	1	/* look only for matching } */
+# define SCAN_PUNCT	2	/* only punctuation keywords */

Added: boost-jam/boost-build/branches/upstream/current/jam_src/search.c
===================================================================
--- boost-jam/boost-build/branches/upstream/current/jam_src/search.c	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/jam_src/search.c	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,208 @@
+/*
+ * Copyright 1993-2002 Christopher Seiwald and Perforce Software, Inc.
+ *
+ * This file is part of Jam - see jam.c for Copyright information.
+ */
+
+/*  This file is ALSO:
+ *  Copyright 2001-2004 David Abrahams.
+ *  Distributed under the Boost Software License, Version 1.0.
+ *  (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+ */
+
+# include "jam.h"
+# include "lists.h"
+# include "search.h"
+# include "timestamp.h"
+# include "pathsys.h"
+# include "variable.h"
+# include "newstr.h"
+# include "compile.h"
+# include "strings.h"
+# include "hash.h"
+# include <string.h>
+
+typedef struct _binding {
+    char* binding;
+    char* target;
+} BINDING;
+
+static struct hash *explicit_bindings = 0;
+
+void call_bind_rule(
+    char* target_,
+    char* boundname_ )
+{
+    LIST* bind_rule = var_get( "BINDRULE" );
+    if( bind_rule )
+    {
+        /* No guarantee that target is an allocated string, so be on the
+         * safe side */
+        char* target = copystr( target_ );
+        
+        /* Likewise, don't rely on implementation details of newstr.c: allocate
+         * a copy of boundname */
+        char* boundname = copystr( boundname_ );
+        if( boundname && target )
+        {
+            /* Prepare the argument list */
+            FRAME frame[1];
+            frame_init( frame );
+                    
+            /* First argument is the target name */
+            lol_add( frame->args, list_new( L0, target ) );
+                    
+            lol_add( frame->args, list_new( L0, boundname ) );
+            if( lol_get( frame->args, 1 ) )
+                evaluate_rule( bind_rule->string, frame );
+            
+            /* Clean up */
+            frame_free( frame );
+        }
+        else
+        {
+            if( boundname )
+                freestr( boundname );
+            if( target )
+                freestr( target );
+        }
+    }
+}
+
+/*
+ * search.c - find a target along $(SEARCH) or $(LOCATE) 
+ * First, check if LOCATE is set. If so, use it to determine
+ * the location of target and return, regardless of whether anything
+ * exists on that location.
+ *
+ * Second, examine all directories in SEARCH. If there's file already
+ * or there's another target with the same name which was placed
+ * to this location via LOCATE setting, stop and return the location. 
+ * In case of previous target, return it's name via the third argument.
+ *
+ * This bevahiour allow to handle dependency on generated files. If
+ * caller does not expect that target is generated, 0 can be passed as
+ * the third argument.
+ */
+
+char *
+search( 
+    char *target,
+    time_t *time,
+    char **another_target
+)
+{
+	PATHNAME f[1];
+    LIST    *varlist;
+    string    buf[1];
+    int     found = 0;
+    /* Will be set to 1 if target location is specified via LOCATE. */
+    int     explicitly_located = 0;
+    char    *boundname = 0;
+
+    if( another_target )
+        *another_target = 0;
+
+    if (! explicit_bindings )
+        explicit_bindings = hashinit( sizeof(BINDING), 
+                                     "explicitly specified locations");
+
+    string_new( buf );
+    /* Parse the filename */
+
+	path_parse( target, f );
+
+    f->f_grist.ptr = 0;
+    f->f_grist.len = 0;
+
+    if( varlist = var_get( "LOCATE" ) )
+      {
+        f->f_root.ptr = varlist->string;
+        f->f_root.len = strlen( varlist->string );
+
+	    path_build( f, buf, 1 );
+
+        if( DEBUG_SEARCH )
+            printf( "locate %s: %s\n", target, buf->value );
+
+        explicitly_located = 1;
+
+        timestamp( buf->value, time );
+        found = 1;
+    }
+    else if( varlist = var_get( "SEARCH" ) )
+    {
+        while( varlist )
+        {
+            BINDING b, *ba = &b;
+
+            f->f_root.ptr = varlist->string;
+            f->f_root.len = strlen( varlist->string );
+
+            string_truncate( buf, 0 );
+            path_build( f, buf, 1 );
+
+            if( DEBUG_SEARCH )
+                printf( "search %s: %s\n", target, buf->value );
+
+            timestamp( buf->value, time );
+
+            b.binding = buf->value;
+            
+            if( hashcheck( explicit_bindings, (HASHDATA**)&ba ) )
+            {
+                if( DEBUG_SEARCH )
+                    printf(" search %s: found explicitly located target %s\n", 
+                           target, ba->target);
+                if( another_target )
+                    *another_target = ba->target;
+                found = 1;
+                break;                
+            }
+            else if( *time )
+            {
+                found = 1;
+                break;
+            }
+
+            varlist = list_next( varlist );
+        }
+    }
+
+    if (!found)
+    {
+        /* Look for the obvious */
+        /* This is a questionable move.  Should we look in the */
+        /* obvious place if SEARCH is set? */
+
+        f->f_root.ptr = 0;
+        f->f_root.len = 0;
+
+        string_truncate( buf, 0 );
+        path_build( f, buf, 1 );
+
+        if( DEBUG_SEARCH )
+            printf( "search %s: %s\n", target, buf->value );
+
+        timestamp( buf->value, time );
+    }
+
+    boundname = newstr( buf->value );
+    string_free( buf );
+
+    if (explicitly_located)
+    {
+        BINDING b, *ba = &b;
+        b.binding = boundname;
+        b.target = target;
+        /* CONSIDER: we probably should issue a warning is another file
+           is explicitly bound to the same location. This might break
+           compatibility, though. */
+        hashenter(explicit_bindings, (HASHDATA**)&ba);
+    }
+        
+    /* prepare a call to BINDRULE if the variable is set */
+    call_bind_rule( target, boundname );
+
+    return boundname;
+}

Added: boost-jam/boost-build/branches/upstream/current/jam_src/search.h
===================================================================
--- boost-jam/boost-build/branches/upstream/current/jam_src/search.h	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/jam_src/search.h	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,11 @@
+/*
+ * Copyright 1993, 1995 Christopher Seiwald.
+ *
+ * This file is part of Jam - see jam.c for Copyright information.
+ */
+
+/*
+ * search.h - find a target along $(SEARCH) or $(LOCATE) 
+ */
+
+char *search( char *target, time_t *time, char **another_target );

Added: boost-jam/boost-build/branches/upstream/current/jam_src/strings.c
===================================================================
--- boost-jam/boost-build/branches/upstream/current/jam_src/strings.c	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/jam_src/strings.c	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,191 @@
+/* Copyright David Abrahams 2004. Distributed under the Boost */
+/* Software License, Version 1.0. (See accompanying */
+/* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */
+
+#include "strings.h"
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include <stdio.h>
+
+
+#ifndef NDEBUG
+# define JAM_STRING_MAGIC ((char)0xcf)
+# define JAM_STRING_MAGIC_SIZE 4
+static void assert_invariants( string* self )
+{
+    int i;
+    
+    assert( self->size < self->capacity );
+    assert( ( self->capacity <= sizeof(self->opt) ) == ( self->value == self->opt ) );
+    assert( strlen( self->value ) == self->size );
+
+    for (i = 0; i < 4; ++i)
+    {
+        assert( self->magic[i] == JAM_STRING_MAGIC );
+        assert( self->value[self->capacity + i] == JAM_STRING_MAGIC );
+    }
+}
+#else
+# define JAM_STRING_MAGIC_SIZE 0
+# define assert_invariants(x) do {} while (0)
+#endif
+
+void string_new( string* s )
+{
+    s->value = s->opt;
+    s->size = 0;
+    s->capacity = sizeof(s->opt);
+    s->opt[0] = 0;
+#ifndef NDEBUG
+    memset(s->magic, JAM_STRING_MAGIC, sizeof(s->magic));
+#endif
+    assert_invariants( s );
+}
+
+void string_free( string* s )
+{
+    assert_invariants( s );
+    if ( s->value != s->opt )
+        free( s->value );
+}
+
+static void string_reserve_internal( string* self, size_t capacity )
+{
+    if ( self->value == self->opt )
+    {
+        self->value = (char*)malloc( capacity + JAM_STRING_MAGIC_SIZE );
+        self->value[0] = 0;
+        strncat( self->value, self->opt, sizeof(self->opt) );
+        assert( strlen( self->value ) <= self->capacity ); /* This is a regression test */
+    }
+    else
+    {
+        self->value = (char*)realloc( self->value, capacity + JAM_STRING_MAGIC_SIZE );
+    }
+#ifndef NDEBUG
+    memcpy( self->value + capacity, self->magic, JAM_STRING_MAGIC_SIZE );
+#endif
+    self->capacity = capacity;
+}
+
+void string_reserve( string* self, size_t capacity )
+{
+    assert_invariants( self );
+    if ( capacity <= self->capacity )
+        return;
+    string_reserve_internal( self, capacity );
+    assert_invariants( self );
+}
+
+static void extend_full( string* self, char* start, char *finish )
+{
+    size_t new_size = self->capacity + ( finish - start );
+    size_t new_capacity = self->capacity;
+    size_t old_size = self->capacity;
+    while ( new_capacity < new_size + 1)
+        new_capacity <<= 1;
+    string_reserve_internal( self, new_capacity );
+    memcpy( self->value + old_size, start, new_size - old_size );
+    self->value[new_size] = 0;
+    self->size = new_size;
+}
+
+void string_append( string* self, char* rhs )
+{
+    char* p = self->value + self->size;
+    char* end = self->value + self->capacity;
+    assert_invariants( self );
+    
+    while ( *rhs && p != end)
+        *p++ = *rhs++;
+    
+    if ( p != end )
+    {
+        *p = 0;
+        self->size = p - self->value;
+    }
+    else
+    {
+        extend_full( self, rhs, rhs + strlen(rhs) );
+    }
+    assert_invariants( self );
+}
+
+void string_append_range( string* self, char* start, char* finish )
+{
+    char* p = self->value + self->size;
+    char* end = self->value + self->capacity;
+    assert_invariants( self );
+    
+    while ( p != end && start != finish )
+        *p++ = *start++;
+    
+    if ( p != end )
+    {
+        *p = 0;
+        self->size = p - self->value;
+    }
+    else
+    {
+        extend_full( self, start, finish );
+    }
+    assert_invariants( self );
+}
+
+void string_copy( string* s, char* rhs )
+{
+    string_new( s );
+    string_append( s, rhs );
+}
+
+void string_truncate( string* self, size_t n )
+{
+    assert_invariants( self );
+    assert( n <= self->capacity );
+    self->value[self->size = n] = 0;
+    assert_invariants( self );
+}
+
+void string_pop_back( string* self )
+{
+    string_truncate( self, self->size - 1 );
+}
+
+void string_push_back( string* self, char x )
+{
+    string_append_range( self, &x, &x + 1 );
+}
+
+char string_back( string* self )
+{
+    assert_invariants( self );
+    return self->value[self->size - 1];
+}
+
+#ifndef NDEBUG
+void string_unit_test()
+{
+    string s[1];
+    int i;
+    char buffer[sizeof(s->opt) * 2 + 2];
+    int limit = sizeof(buffer) > 254 ? 254 : sizeof(buffer);
+
+    string_new(s);
+    
+    for (i = 0; i < limit; ++i)
+    {
+        string_push_back( s, (char)(i + 1) );
+    };
+
+    for (i = 0; i < limit; ++i)
+    {
+        assert( i < s->size );
+        assert( s->value[i] == (char)(i + 1));
+    }
+
+    string_free(s);
+    
+}
+#endif
+

Added: boost-jam/boost-build/branches/upstream/current/jam_src/strings.h
===================================================================
--- boost-jam/boost-build/branches/upstream/current/jam_src/strings.h	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/jam_src/strings.h	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,34 @@
+#ifndef STRINGS_DWA20011024_H
+# define STRINGS_DWA20011024_H
+
+/* Copyright David Abrahams 2004. Distributed under the Boost */
+/* Software License, Version 1.0. (See accompanying */
+/* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */
+
+# include <stddef.h>
+
+typedef struct string
+{
+    char* value;
+    unsigned long size;
+    unsigned long capacity;
+    char opt[32];
+#ifndef NDEBUG
+    char magic[4];
+#endif
+} string;
+
+void string_new( string* );
+void string_copy( string*, char* );
+void string_free( string* );
+void string_append( string*, char* );
+void string_append_range( string*, char*, char* );
+void string_push_back( string* s, char x );
+void string_reserve( string*, size_t );
+void string_truncate( string*, size_t );
+void string_pop_back( string* );
+char string_back( string* );
+void string_unit_test();
+
+#endif
+

Added: boost-jam/boost-build/branches/upstream/current/jam_src/subst.c
===================================================================
--- boost-jam/boost-build/branches/upstream/current/jam_src/subst.c	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/jam_src/subst.c	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,94 @@
+#include <stddef.h>
+#include "jam.h"
+#include "regexp.h"
+#include "hash.h"
+
+#include "newstr.h"
+#include "lists.h"
+#include "parse.h"
+#include "compile.h"
+#include "frames.h"
+
+struct regex_entry
+{
+    const char* pattern;
+    regexp* regex;
+};
+typedef struct regex_entry regex_entry;
+
+static struct hash* regex_hash;
+
+regexp* regex_compile( const char* pattern )
+{
+    regex_entry entry, *e = &entry;
+    entry.pattern = pattern;
+    
+    if ( !regex_hash )
+        regex_hash = hashinit(sizeof(regex_entry), "regex");
+        
+    if ( hashenter( regex_hash, (HASHDATA **)&e ) )
+        e->regex = regcomp( (char*)pattern );
+    
+    return e->regex;
+}
+
+LIST*
+builtin_subst(
+    PARSE    *parse,
+    FRAME      *frame )
+{        
+  LIST* result = L0;
+  LIST* arg1 = lol_get( frame->args, 0 );
+
+  if ( arg1 && list_next(arg1) && list_next(list_next(arg1)) )
+  {    
+  
+      const char* source = arg1->string;
+      const char* pattern = list_next(arg1)->string;
+      regexp* repat = regex_compile( pattern );
+
+      if ( regexec( repat, (char*)source) )
+      {
+          LIST* subst = list_next(arg1);
+          
+          while ((subst = list_next(subst)) != L0)
+          {
+# define BUFLEN 4096
+              char buf[BUFLEN + 1];
+              const char* in = subst->string;
+              char* out = buf;
+
+              for ( in = subst->string; *in && out < buf + BUFLEN; ++in )
+              {
+                  if ( *in == '\\' || *in == '$' )
+                  {
+                      ++in;
+                      if ( *in == 0 )
+                      {
+                          break;
+                      }
+                      else if ( *in >= '0' && *in <= '9' )
+                      {
+                          unsigned n = *in - '0';
+                          const size_t srclen = repat->endp[n] - repat->startp[n];
+                          const size_t remaining = buf + BUFLEN - out;
+                          const size_t len = srclen < remaining ? srclen : remaining;
+                          memcpy( out, repat->startp[n], len );
+                          out += len;
+                          continue;
+                      }
+                      /* fall through and copy the next character */
+                  }
+                  *out++ = *in;
+              }
+              *out = 0;
+
+              result = list_new( result, newstr( buf ) );
+#undef BUFLEN
+          }
+      }
+  }
+  
+  return result;
+}
+

Added: boost-jam/boost-build/branches/upstream/current/jam_src/timestamp.c
===================================================================
--- boost-jam/boost-build/branches/upstream/current/jam_src/timestamp.c	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/jam_src/timestamp.c	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,227 @@
+/*
+ * Copyright 1993-2002 Christopher Seiwald and Perforce Software, Inc.
+ *
+ * This file is part of Jam - see jam.c for Copyright information.
+ */
+
+/*  This file is ALSO:
+ *  Copyright 2001-2004 David Abrahams.
+ *  Distributed under the Boost Software License, Version 1.0.
+ *  (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+ */
+
+# include "jam.h"
+# include "hash.h"
+# include "filesys.h"
+# include "pathsys.h"
+# include "timestamp.h"
+# include "newstr.h"
+# include "strings.h"
+
+/*
+ * timestamp.c - get the timestamp of a file or archive member
+ *
+ * 09/22/00 (seiwald) - downshift names on OS2, too
+ */
+
+/*
+ * BINDING - all known files
+ */
+
+typedef struct _binding BINDING;
+
+struct _binding {
+	char	*name;
+	short	flags;
+
+# define BIND_SCANNED	0x01	/* if directory or arch, has been scanned */
+
+	short	progress;
+
+# define BIND_INIT	0	/* never seen */
+# define BIND_NOENTRY	1	/* timestamp requested but file never found */
+# define BIND_SPOTTED	2	/* file found but not timed yet */
+# define BIND_MISSING	3	/* file found but can't get timestamp */
+# define BIND_FOUND	4	/* file found and time stamped */
+
+	time_t	time;		/* update time - 0 if not exist */
+} ;
+
+static struct hash *bindhash = 0;
+static void time_enter( void *, char *, int , time_t  );
+
+static char *time_progress[] =
+{
+	"INIT",
+	"NOENTRY",
+	"SPOTTED",
+	"MISSING",
+	"FOUND"
+} ;
+
+
+/*
+ * timestamp() - return timestamp on a file, if present
+ */
+
+void
+timestamp( 
+	char	*target,
+	time_t	*time )
+{
+	PATHNAME f1, f2;
+	BINDING	binding, *b = &binding;
+	string buf[1];
+
+# ifdef DOWNSHIFT_PATHS
+        string path; 
+	char *p;
+
+        string_copy( &path, target );
+        p = path.value;
+
+	do
+    {
+        *p = tolower( *p );
+#  ifdef NT
+        /* On NT, we must use backslashes or the file won't be found. */
+        if (*p == '/')
+            *p = PATH_DELIM;
+#  endif 
+    }
+	while( *p++ );
+
+	target = path.value;
+# endif
+        string_new( buf );
+
+	if( !bindhash )
+	    bindhash = hashinit( sizeof( BINDING ), "bindings" );
+
+	/* Quick path - is it there? */
+
+	b->name = target;
+	b->time = b->flags = 0;
+	b->progress = BIND_INIT;
+
+	if( hashenter( bindhash, (HASHDATA **)&b ) )
+	    b->name = newstr( target );		/* never freed */
+
+	if( b->progress != BIND_INIT )
+	    goto afterscanning;
+
+	b->progress = BIND_NOENTRY;
+
+	/* Not found - have to scan for it */
+
+	path_parse( target, &f1 );
+
+	/* Scan directory if not already done so */
+
+	{
+	    BINDING binding, *b = &binding;
+
+	    f2 = f1;
+	    f2.f_grist.len = 0;
+	    path_parent( &f2 );
+	    path_build( &f2, buf, 0 );
+
+	    b->name = buf->value;
+	    b->time = b->flags = 0;
+	    b->progress = BIND_INIT;
+
+	    if( hashenter( bindhash, (HASHDATA **)&b ) )
+		b->name = newstr( buf->value );	/* never freed */
+
+	    if( !( b->flags & BIND_SCANNED ) )
+	    {
+		file_dirscan( buf->value, time_enter, bindhash );
+		b->flags |= BIND_SCANNED;
+	    }
+	}
+
+	/* Scan archive if not already done so */
+
+	if( f1.f_member.len )
+	{
+	    BINDING binding, *b = &binding;
+
+	    f2 = f1;
+	    f2.f_grist.len = 0;
+	    f2.f_member.len = 0;
+            string_truncate( buf, 0 );
+	    path_build( &f2, buf, 0 );
+
+	    b->name = buf->value;
+	    b->time = b->flags = 0;
+	    b->progress = BIND_INIT;
+
+	    if( hashenter( bindhash, (HASHDATA **)&b ) )
+		b->name = newstr( buf->value );	/* never freed */
+
+	    if( !( b->flags & BIND_SCANNED ) )
+	    {
+		file_archscan( buf->value, time_enter, bindhash );
+		b->flags |= BIND_SCANNED;
+	    }
+	}
+
+    afterscanning:
+
+	if( b->progress == BIND_SPOTTED )
+	{
+	    if( file_time( b->name, &b->time ) < 0 )
+		b->progress = BIND_MISSING;
+	    else
+		b->progress = BIND_FOUND;
+	}
+
+	*time = b->progress == BIND_FOUND ? b->time : 0;
+        string_free( buf );
+# ifdef DOWNSHIFT_PATHS
+        string_free( &path );
+#endif
+}
+
+static void
+time_enter( 
+	void	*closure,
+	char	*target,
+	int	found,
+	time_t	time )
+{
+	BINDING	binding, *b = &binding;
+	struct hash *bindhash = (struct hash *)closure;
+
+# ifdef DOWNSHIFT_PATHS
+	char path[ MAXJPATH ];
+	char *p = path;
+
+	do *p++ = tolower( *target );
+	while( *target++ );
+
+	target = path;
+# endif
+
+	b->name = target;
+	b->flags = 0;
+
+	if( hashenter( bindhash, (HASHDATA **)&b ) )
+	    b->name = newstr( target );		/* never freed */
+
+	b->time = time;
+	b->progress = found ? BIND_FOUND : BIND_SPOTTED;
+
+	if( DEBUG_BINDSCAN )
+	    printf( "time ( %s ) : %s\n", target, time_progress[b->progress] );
+}
+
+/*
+ * donestamps() - free timestamp tables
+ */
+
+void
+donestamps()
+{
+	hashdone( bindhash );
+}

Added: boost-jam/boost-build/branches/upstream/current/jam_src/timestamp.h
===================================================================
--- boost-jam/boost-build/branches/upstream/current/jam_src/timestamp.h	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/jam_src/timestamp.h	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,12 @@
+/*
+ * Copyright 1993, 1995 Christopher Seiwald.
+ *
+ * This file is part of Jam - see jam.c for Copyright information.
+ */
+
+/*
+ * timestamp.h - get the timestamp of a file or archive member
+ */
+
+void timestamp( char *target, time_t *time );
+void donestamps();

Added: boost-jam/boost-build/branches/upstream/current/jam_src/variable.c
===================================================================
--- boost-jam/boost-build/branches/upstream/current/jam_src/variable.c	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/jam_src/variable.c	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,386 @@
+/*
+ * Copyright 1993, 2000 Christopher Seiwald.
+ *
+ * This file is part of Jam - see jam.c for Copyright information.
+ */
+
+/*  This file is ALSO:
+ *  Copyright 2001-2004 David Abrahams.
+ *  Distributed under the Boost Software License, Version 1.0.
+ *  (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+ */
+
+# include "jam.h"
+# include "lists.h"
+# include "parse.h"
+# include "variable.h"
+# include "expand.h"
+# include "hash.h"
+# include "filesys.h"
+# include "newstr.h"
+# include "strings.h"
+# include <stdlib.h>
+
+/*
+ * variable.c - handle jam multi-element variables
+ *
+ * External routines:
+ *
+ *	var_defines() - load a bunch of variable=value settings
+ *	var_string() - expand a string with variables in it
+ *	var_get() - get value of a user defined symbol
+ *	var_set() - set a variable in jam's user defined symbol table
+ *	var_swap() - swap a variable's value with the given one
+ *	var_done() - free variable tables
+ *
+ * Internal routines:
+ *
+ *	var_enter() - make new var symbol table entry, returning var ptr
+ *	var_dump() - dump a variable to stdout
+ *
+ * 04/13/94 (seiwald) - added shorthand L0 for null list pointer
+ * 08/23/94 (seiwald) - Support for '+=' (append to variable)
+ * 01/22/95 (seiwald) - split environment variables at blanks or :'s
+ * 05/10/95 (seiwald) - split path variables at SPLITPATH (not :)
+ * 09/11/00 (seiwald) - defunct var_list() removed
+ */
+
+static struct hash *varhash = 0;
+
+/*
+ * VARIABLE - a user defined multi-value variable
+ */
+
+typedef struct _variable VARIABLE ;
+
+struct _variable {
+	char	*symbol;
+	LIST	*value;
+} ;
+
+static VARIABLE *var_enter( char *symbol );
+static void var_dump( char *symbol, LIST *value, char *what );
+
+
+
+/*
+ * var_hash_swap() - swap all variable settings with those passed
+ *
+ * Used to implement separate settings spaces for modules
+ */
+void var_hash_swap( struct hash** new_vars )
+{
+    struct hash* old = varhash;
+    varhash = *new_vars;
+    *new_vars = old;
+}
+
+/*
+ * var_defines() - load a bunch of variable=value settings
+ *
+ * If variable name ends in PATH, split value at :'s.  
+ * Otherwise, split at blanks.
+ */
+
+void
+var_defines( char **e )
+{
+    string buf[1];
+
+    string_new( buf );
+
+	for( ; *e; e++ )
+	{
+	    char *val;
+
+	    /* Just say "no": windows defines this in the env, */
+	    /* but we don't want it to override our notion of OS. */
+
+	    if( !strcmp( *e, "OS=Windows_NT" ) )
+		continue;
+
+# ifdef OS_MAC
+	    /* On the mac (MPW), the var=val is actually var\0val */
+	    /* Think different. */
+	
+	    if( ( val = strchr( *e, '=' ) ) || ( val = *e + strlen( *e ) ) )
+# else
+	    if( val = strchr( *e, '=' ) )
+# endif
+	    {
+		LIST *l = L0;
+		char *pp, *p;
+# ifdef OS_MAC
+		char split = ',';
+# else
+		char split = ' ';
+# endif
+                size_t len = strlen(val + 1);
+                if ( val[1] == '"' && val[len] == '"')
+                {
+                    string_append_range( buf, val + 2, val + len );
+                    l = list_new( l, newstr( buf->value ) );
+                    string_truncate( buf, 0 );
+                }
+                else
+                {
+                    /* Split *PATH at :'s, not spaces */
+
+                    if( val - 4 >= *e )
+                    {
+                        if( !strncmp( val - 4, "PATH", 4 ) ||
+                            !strncmp( val - 4, "Path", 4 ) ||
+                            !strncmp( val - 4, "path", 4 ) )
+			    split = SPLITPATH;
+                    }
+
+                    /* Do the split */
+
+                    for( pp = val + 1; p = strchr( pp, split ); pp = p + 1 )
+                    {
+                        string_append_range( buf, pp, p );
+                        l = list_new( l, newstr( buf->value ) );
+                        string_truncate( buf, 0 );
+                    }
+
+                    l = list_new( l, newstr( pp ) );
+                }
+
+		/* Get name */
+                string_append_range( buf, *e, val );
+		var_set( buf->value, l, VAR_SET );
+                string_truncate( buf, 0 );
+	    }
+	}
+        string_free( buf );
+}
+
+/*
+ * var_string() - expand a string with variables in it
+ *
+ * Copies in to out; doesn't modify targets & sources.
+ */
+
+int
+var_string(
+	char	*in,
+	char	*out,
+	int	outsize,
+	LOL	*lol )
+{
+	char 	*out0 = out;
+	char	*oute = out + outsize - 1;
+
+	while( *in )
+	{
+	    char	*lastword;
+	    int		dollar = 0;
+
+	    /* Copy white space */
+
+	    while( isspace( *in ) )
+	    {
+		if( out >= oute )
+		    return -1;
+
+		*out++ = *in++;
+	    }
+
+	    lastword = out;
+
+	    /* Copy non-white space, watching for variables */
+
+	    while( *in && !isspace( *in ) )
+	    {
+	        if( out >= oute )
+		    return -1;
+
+		if( in[0] == '$' && in[1] == '(' )
+		    dollar++;
+
+		*out++ = *in++;
+	    }
+
+        /* Add zero to 'out' so that 'lastword' is correctly zero-terminated. */
+        if (out >= oute)
+            return -1;
+        /* Don't increment, intentionally. */
+        *out= '\0';
+           
+	    /* If a variable encountered, expand it and and embed the */
+	    /* space-separated members of the list in the output. */
+
+	    if( dollar )
+	    {
+		LIST	*l;
+
+		l = var_expand( L0, lastword, out, lol, 0 );
+
+		out = lastword;
+
+		for( ; l; l = list_next( l ) )
+		{
+		    int so = strlen( l->string );
+
+		    if( out + so >= oute )
+			return -1;
+
+		    strcpy( out, l->string );
+		    out += so;
+		    *out++ = ' ';
+		}
+
+		list_free( l );
+	    }
+	}
+
+	if( out >= oute )
+	    return -1;
+
+	*out++ = '\0';
+
+	return out - out0;
+}
+
+/*
+ * var_get() - get value of a user defined symbol
+ *
+ * Returns NULL if symbol unset.
+ */
+
+LIST *
+var_get( char *symbol )
+{
+	VARIABLE var, *v = &var;
+
+	v->symbol = symbol;
+
+	if( varhash && hashcheck( varhash, (HASHDATA **)&v ) )
+	{
+	    if( DEBUG_VARGET )
+		var_dump( v->symbol, v->value, "get" );
+	    return v->value;
+	}
+    
+	return 0;
+}
+
+/*
+ * var_set() - set a variable in jam's user defined symbol table
+ *
+ * 'flag' controls the relationship between new and old values of
+ * the variable: SET replaces the old with the new; APPEND appends
+ * the new to the old; DEFAULT only uses the new if the variable
+ * was previously unset.
+ *
+ * Copies symbol.  Takes ownership of value.
+ */
+
+void
+var_set(
+	char	*symbol,
+	LIST	*value,
+	int	flag )
+{
+	VARIABLE *v = var_enter( symbol );
+
+	if( DEBUG_VARSET )
+	    var_dump( symbol, value, "set" );
+        
+	switch( flag )
+	{
+	case VAR_SET:
+	    /* Replace value */
+	    list_free( v->value );
+	    v->value = value;
+	    break;
+
+	case VAR_APPEND:
+	    /* Append value */
+	    v->value = list_append( v->value, value );
+	    break;
+
+	case VAR_DEFAULT:
+	    /* Set only if unset */
+	    if( !v->value )
+		v->value = value;
+	    else
+		list_free( value );
+	    break;
+	}
+}
+
+/*
+ * var_swap() - swap a variable's value with the given one
+ */
+
+LIST *
+var_swap(
+	char	*symbol,
+	LIST	*value )
+{
+	VARIABLE *v = var_enter( symbol );
+	LIST 	 *oldvalue = v->value;
+
+	if( DEBUG_VARSET )
+	    var_dump( symbol, value, "set" );
+
+	v->value = value;
+
+	return oldvalue;
+}
+
+
+
+/*
+ * var_enter() - make new var symbol table entry, returning var ptr
+ */
+
+static VARIABLE *
+var_enter( char	*symbol )
+{
+	VARIABLE var, *v = &var;
+
+	if( !varhash )
+	    varhash = hashinit( sizeof( VARIABLE ), "variables" );
+
+	v->symbol = symbol;
+	v->value = 0;
+
+	if( hashenter( varhash, (HASHDATA **)&v ) )
+	    v->symbol = newstr( symbol );	/* never freed */
+
+	return v;
+}
+
+/*
+ * var_dump() - dump a variable to stdout
+ */
+
+static void
+var_dump(
+	char	*symbol,
+	LIST	*value,
+	char	*what )
+{
+	printf( "%s %s = ", what, symbol );
+	list_print( value );
+	printf( "\n" );
+}
+
+/*
+ * var_done() - free variable tables
+ */
+static void delete_var_( void* xvar, void* data )
+{
+    VARIABLE *v = (VARIABLE*)xvar;
+    freestr( v->symbol );
+    list_free( v-> value );
+}
+
+void
+var_done()
+{
+    hashenumerate( varhash, delete_var_, (void*)0 );
+	hashdone( varhash );
+}

Added: boost-jam/boost-build/branches/upstream/current/jam_src/variable.h
===================================================================
--- boost-jam/boost-build/branches/upstream/current/jam_src/variable.h	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/jam_src/variable.h	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,28 @@
+/*
+ * Copyright 1993, 2000 Christopher Seiwald.
+ *
+ * This file is part of Jam - see jam.c for Copyright information.
+ */
+
+/*
+ * variable.h - handle jam multi-element variables
+ */
+
+struct hash;
+
+void 	var_defines( char **e );
+int 	var_string( char *in, char *out, int outsize, LOL *lol );
+LIST * 	var_get( char *symbol );
+void 	var_set( char *symbol, LIST *value, int flag );
+LIST * 	var_swap( char *symbol, LIST *value );
+void 	var_done();
+void    var_hash_swap( struct hash** );
+
+/*
+ * Defines for var_set().
+ */
+
+# define VAR_SET	0	/* override previous value */
+# define VAR_APPEND	1	/* append to previous value */
+# define VAR_DEFAULT	2	/* set only if no previous value */
+

Added: boost-jam/boost-build/branches/upstream/current/jam_src/w32_getreg.c
===================================================================
--- boost-jam/boost-build/branches/upstream/current/jam_src/w32_getreg.c	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/jam_src/w32_getreg.c	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,123 @@
+/* Copyright Paul Lin 2003. Distributed under the Boost */
+/* Software License, Version 1.0. (See accompanying */
+/* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */
+
+# include "jam.h"
+# include "lists.h"
+# include "newstr.h"
+# include "parse.h"
+# include "frames.h"
+# include "strings.h"
+
+# define WIN32_LEAN_AND_MEAN
+# include <windows.h>
+
+# define  MAX_REGISTRY_DATA_LENGTH  4096
+
+typedef struct
+{
+    LPCSTR  name;
+    HKEY    value;
+} KeyMap;
+
+static const KeyMap dlRootKeys[] = {
+    { "HKLM", HKEY_LOCAL_MACHINE },
+    { "HKCU", HKEY_CURRENT_USER },
+    { "HKCR", HKEY_CLASSES_ROOT },
+    { "HKEY_LOCAL_MACHINE", HKEY_LOCAL_MACHINE },
+    { "HKEY_CURRENT_USER", HKEY_CURRENT_USER },
+    { "HKEY_CLASSES_ROOT", HKEY_CLASSES_ROOT },
+    { 0, 0 }
+};
+
+LIST*
+builtin_system_registry(
+    PARSE    *parse,
+    FRAME    *frame )
+{
+    char const* path = lol_get(frame->args, 0)->string;
+    LIST* result = L0;
+    HKEY key;
+    
+    {
+        const KeyMap *p;
+        
+        for (p = dlRootKeys; p->name; ++p)
+        {
+            int n = strlen(p->name);
+            if (!strncmp(path,p->name,n))
+            {
+                if (path[n] == '\\' || path[n] == 0)
+                {
+                    path += n + 1;
+                    break;
+                }
+            }
+        }
+        
+        key = p->value;
+    }
+
+    if (
+        key != 0
+        && ERROR_SUCCESS == RegOpenKeyEx(key, path, 0, KEY_QUERY_VALUE, &key) 
+    )
+    {
+        DWORD  type, len;
+        BYTE   data[MAX_REGISTRY_DATA_LENGTH];
+        LIST const* const field = lol_get(frame->args, 1);
+        
+        if ( ERROR_SUCCESS ==
+             RegQueryValueEx(key, field ? field->string : 0, 0, &type, data, &len) )
+        {
+            switch (type)
+            {
+                
+             case REG_EXPAND_SZ:
+                 {
+                     long len;
+                     string expanded[1];
+                     string_new(expanded);
+
+                     while (
+                         (len = ExpandEnvironmentStrings(
+                             (LPCSTR)data, expanded->value, expanded->capacity))
+                         > expanded->capacity
+                     )
+                         string_reserve(expanded, len);
+
+                     expanded->size = len - 1;
+
+                     result = list_new( result, newstr(expanded->value) );
+                     string_free( expanded );
+                 }
+                 break;
+            
+             case REG_MULTI_SZ:
+                 {
+                     char* s;
+
+                     for (s = (char*)data; *s; s += strlen(s) + 1)
+                         result = list_new( result, newstr(s) );
+
+                 }
+                 break;
+             
+             case REG_DWORD:
+                 {
+                     char buf[100];
+                     sprintf( buf, "%u", *(PDWORD)data );
+                     result = list_new( result, newstr(buf) );
+                 }
+                 break;
+
+             case REG_SZ:
+                 result = list_new( result, newstr((char*)data) );
+                 break;
+            }
+        }
+        RegCloseKey(key);
+    }
+    return  result;
+}
+

Added: boost-jam/boost-build/branches/upstream/current/jam_src/yyacc.c
===================================================================
--- boost-jam/boost-build/branches/upstream/current/jam_src/yyacc.c	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/jam_src/yyacc.c	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,268 @@
+/* Copyright 2002 Rene Rivera.
+** Distributed under the Boost Software License, Version 1.0.
+** (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+*/
+
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+#include <stdlib.h>
+
+/*
+# yyacc - yacc wrapper
+#
+# Allows tokens to be written as `literal` and then automatically 
+# substituted with #defined tokens.
+#
+# Usage:
+#    yyacc file.y filetab.h file.yy 
+#
+# inputs:
+#    file.yy        yacc grammar with ` literals
+#
+# outputs:
+#    file.y        yacc grammar
+#    filetab.h    array of string <-> token mappings
+#
+# 3-13-93
+#    Documented and p moved in sed command (for some reason,
+#    s/x/y/p doesn't work).
+# 10-12-93
+#    Take basename as second argument.
+# 12-31-96
+#    reversed order of args to be compatible with GenFile rule
+# 11-20-2002
+#    Reimplemented as a C program for portability. (Rene Rivera)
+*/
+
+void print_usage();
+char * copy_string(char * s, int l);
+char * tokenize_string(char * s);
+int cmp_literal(const void * a, const void * b);
+
+typedef struct
+{
+    char * string;
+    char * token;
+} literal;
+
+int main(int argc, char ** argv)
+{
+    int result = 0;
+    if (argc != 4)
+    {
+        print_usage();
+        result = 1;
+    }
+    else
+    {
+        FILE * token_output_f = 0;
+        FILE * grammar_output_f = 0;
+        FILE * grammar_source_f = 0;
+        
+        grammar_source_f = fopen(argv[3],"r");
+        if (grammar_source_f == 0) { result = 1; }
+        if (result == 0)
+        {
+            literal literals[1024];
+            int t = 0;
+            char l[2048];
+            while (1)
+            {
+                if (fgets(l,2048,grammar_source_f) != 0)
+                {
+                    char * c = l;
+                    while (1)
+                    {
+                        char * c1 = strchr(c,'`');
+                        if (c1 != 0)
+                        {
+                            char * c2 = strchr(c1+1,'`');
+                            if (c2 != 0)
+                            {
+                                literals[t].string = copy_string(c1+1,c2-c1-1);
+                                literals[t].token = tokenize_string(literals[t].string);
+                                t += 1;
+                                c = c2+1;
+                            }
+                            else
+                                break;
+                        }
+                        else
+                            break;
+                    }
+                }
+                else
+                {
+                    break;
+                }
+            }
+            literals[t].string = 0;
+            literals[t].token = 0;
+            qsort(literals,t,sizeof(literal),cmp_literal);
+            {
+                int p = 1;
+                int i = 1;
+                while (literals[i].string != 0)
+                {
+                    if (strcmp(literals[p-1].string,literals[i].string) != 0)
+                    {
+                        literals[p] = literals[i];
+                        p += 1;
+                    }
+                    i += 1;
+                }
+                literals[p].string = 0;
+                literals[p].token = 0;
+                t = p;
+            }
+            token_output_f = fopen(argv[2],"w");
+            if (token_output_f != 0)
+            {
+                int i = 0;
+                while (literals[i].string != 0)
+                {
+                    fprintf(token_output_f,"    { \"%s\", %s },\n",literals[i].string,literals[i].token);
+                    i += 1;
+                }
+                fclose(token_output_f);
+            }
+            else
+                result = 1;
+            if (result == 0)
+            {
+                grammar_output_f = fopen(argv[1],"w");
+                if (grammar_output_f != 0)
+                {
+                    int i = 0;
+                    while (literals[i].string != 0)
+                    {
+                        fprintf(grammar_output_f,"%%token %s\n",literals[i].token);
+                        i += 1;
+                    }
+                    rewind(grammar_source_f);
+                    while (1)
+                    {
+                        if (fgets(l,2048,grammar_source_f) != 0)
+                        {
+                            char * c = l;
+                            while (1)
+                            {
+                                char * c1 = strchr(c,'`');
+                                if (c1 != 0)
+                                {
+                                    char * c2 = strchr(c1+1,'`');
+                                    if (c2 != 0)
+                                    {
+                                        literal key;
+                                        literal * replacement = 0;
+                                        key.string = copy_string(c1+1,c2-c1-1);
+                                        key.token = 0;
+                                        replacement = (literal*)bsearch(
+                                            &key,literals,t,sizeof(literal),cmp_literal);
+                                        *c1 = 0;
+                                        fprintf(grammar_output_f,"%s%s",c,replacement->token);
+                                        c = c2+1;
+                                    }
+                                    else
+                                    {
+                                        fprintf(grammar_output_f,"%s",c);
+                                        break;
+                                    }
+                                }
+                                else
+                                {
+                                    fprintf(grammar_output_f,"%s",c);
+                                    break;
+                                }
+                            }
+                        }
+                        else
+                        {
+                            break;
+                        }
+                    }
+                    fclose(grammar_output_f);
+                }
+                else
+                    result = 1;
+            }
+        }
+        if (result != 0)
+        {
+            perror("yyacc");
+        }
+    }
+    return result;
+}
+
+static char * usage[] = {
+    "yyacc <grammar output.y> <token table output.h> <grammar source.yy>",
+    0 };
+
+void print_usage()
+{
+    char ** u;
+    for (u = usage; *u != 0; ++u)
+    {
+        fputs(*u,stderr); putc('\n',stderr);
+    }
+}
+
+char * copy_string(char * s, int l)
+{
+    char * result = (char*)malloc(l+1);
+    strncpy(result,s,l);
+    result[l] = 0;
+    return result;
+}
+
+char * tokenize_string(char * s)
+{
+    char * result;
+    char * literal = s;
+    int l;
+    int c;
+    
+    if (strcmp(s,":") == 0) literal = "_colon";
+    else if (strcmp(s,"!") == 0) literal = "_bang";
+    else if (strcmp(s,"!=") == 0) literal = "_bang_equals";
+    else if (strcmp(s,"&&") == 0) literal = "_amperamper";
+    else if (strcmp(s,"&") == 0) literal = "_amper";
+    else if (strcmp(s,"+") == 0) literal = "_plus";
+    else if (strcmp(s,"+=") == 0) literal = "_plus_equals";
+    else if (strcmp(s,"||") == 0) literal = "_barbar";
+    else if (strcmp(s,"|") == 0) literal = "_bar";
+    else if (strcmp(s,";") == 0) literal = "_semic";
+    else if (strcmp(s,"-") == 0) literal = "_minus";
+    else if (strcmp(s,"<") == 0) literal = "_langle";
+    else if (strcmp(s,"<=") == 0) literal = "_langle_equals";
+    else if (strcmp(s,">") == 0) literal = "_rangle";
+    else if (strcmp(s,">=") == 0) literal = "_rangle_equals";
+    else if (strcmp(s,".") == 0) literal = "_period";
+    else if (strcmp(s,"?") == 0) literal = "_question";
+    else if (strcmp(s,"?=") == 0) literal = "_question_equals";
+    else if (strcmp(s,"=") == 0) literal = "_equals";
+    else if (strcmp(s,",") == 0) literal = "_comma";
+    else if (strcmp(s,"[") == 0) literal = "_lbracket";
+    else if (strcmp(s,"]") == 0) literal = "_rbracket";
+    else if (strcmp(s,"{") == 0) literal = "_lbrace";
+    else if (strcmp(s,"}") == 0) literal = "_rbrace";
+    else if (strcmp(s,"(") == 0) literal = "_lparen";
+    else if (strcmp(s,")") == 0) literal = "_rparen";
+    l = strlen(literal)+2;
+    result = (char*)malloc(l+1);
+    for (c = 0; literal[c] != 0; ++c)
+    {
+        result[c] = toupper(literal[c]);
+    }
+    result[l-2] = '_';
+    result[l-1] = 't';
+    result[l] = 0;
+    return result;
+}
+
+int cmp_literal(const void * a, const void * b)
+{
+    return strcmp(((const literal *)a)->string,((const literal *)b)->string);
+}

Added: boost-jam/boost-build/branches/upstream/current/kernel/boost-build.jam
===================================================================
--- boost-jam/boost-build/branches/upstream/current/kernel/boost-build.jam	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/kernel/boost-build.jam	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,6 @@
+# Copyright David Abrahams 2003. Permission to copy, use,
+# modify, sell and distribute this software is granted provided this
+# copyright notice appears in all copies. This software is provided
+# "as is" without express or implied warranty, and with no claim as
+# to its suitability for any purpose.
+boost-build . ;
\ No newline at end of file


Property changes on: boost-jam/boost-build/branches/upstream/current/kernel/boost-build.jam
___________________________________________________________________
Name: svn:executable
   + 

Added: boost-jam/boost-build/branches/upstream/current/kernel/bootstrap.jam
===================================================================
--- boost-jam/boost-build/branches/upstream/current/kernel/bootstrap.jam	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/kernel/bootstrap.jam	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,121 @@
+# (C) Copyright David Abrahams, 2001.
+# (C) Copyright Rene Rivera, 2003.
+#
+# See accompanying license for terms and conditions of use.
+#
+
+# First of all, check the jam version
+
+if $(JAM_VERSION:J="") < 030109
+{
+    ECHO "error: Boost.Jam version 3.1.9 or later required" ;
+    EXIT ;
+} 
+
+# Bootstrap the module system. Then bring the import rule into the global module.
+#
+SEARCH on <module@>modules.jam = $(.bootstrap-file:D) ;
+module modules { include <module@>modules.jam ; }
+IMPORT modules : import : : import ;
+
+{
+    # Add module subdirectories to the BOOST_BUILD_PATH, which allows
+    # us to make an incremental refactoring step by moving modules to
+    # the appropriate subdirectories, thereby achieving some physical
+    # separation of different layers without changing all of our code
+    # to specify subdirectories in import statements or use an extra
+    # level of qualification on imported names.
+    
+    local subdirs = 
+      kernel        # only the most-intrinsic modules: modules, errors
+      util          # low-level substrate: string/number handling, etc.
+      build         # essential elements of the build system architecture
+      tools         # toolsets for handling specific build jobs and targets.
+      
+      new           # until we get everything sorted out, there is
+                    # still some code here
+      
+      .             # build-system.jam lives here
+      
+      ;
+    local whereami = [ NORMALIZE_PATH $(.bootstrap-file:DT) ] ;
+    BOOST_BUILD_PATH += $(whereami:D)/$(subdirs) ;
+}
+
+# Reload the modules, to clean up things. The modules module can tolerate
+# being included twice.
+#
+import modules ;
+
+# Check command-line args as soon as possible.  For each option try
+# to load module named after option. Is that succeeds, invoke 'process'
+# rule in the module. The rule may return "true" to indicate that the
+# regular built process should not be attempted.
+#
+# Options take the general form of: --<name>[=<value>] [<value>]
+#
+local dont-build ;
+local args = $(ARGV) ;
+while $(args)
+{
+    local arg = [ MATCH ^--(.*) : $(args[1]) ] ;
+    while $(args[2-]) && ! $(arg)
+    {
+        args = $(args[2-]) ;
+        arg = [ MATCH ^--(.*) : $(args[1]) ] ;
+    }
+    args = $(args[2-]) ;
+    
+    if $(arg)
+    {
+        local split = [ MATCH ^(([^-=]+)[^=]*)(=?)(.*)$ : $(arg) ] ;
+        local full-name = $(split[1]) ;
+        local prefix = $(split[2]) ;
+        local values ;
+        
+        if $(split[3])
+        {
+            values = $(split[4]) ;
+        }
+        if $(args) && ! [ MATCH ^(--).* : $(args[1]) ]
+        {
+            values += $(args[1]) ;
+            args = $(args[2-]) ;
+        }
+        
+        # look in options subdirectories of BOOST_BUILD_PATH for modules
+        # matching the full option name and then its prefix.
+        local plugin-dir = options ;
+        local option-files = [ 
+            GLOB $(plugin-dir:D=$(BOOST_BUILD_PATH)) : $(full-name).jam $(prefix).jam 
+            ] ;
+        
+        if $(option-files)
+        {
+            # load the file into a module named for the option
+            local f = $(option-files[1]) ;
+            local module-name = --$(f:D=:S=) ;
+            modules.load $(module-name) : $(f:D=) : $(f:D) ;
+            
+            # if there's a process rule, call it with the full option name
+            # and its value (if any).  If there was no "=" in the option,
+            # the value will be empty.
+            if process in [ RULENAMES $(module-name) ]
+            {
+                dont-build += 
+                  [ modules.call-in $(module-name) : process --$(full-name) : $(values) ] ;
+            }
+        }
+    }
+}
+
+if ! $(dont-build)
+{   
+    # Allow users to override the build system file from the
+    # command-line (mostly for testing)
+    local build-system = [ MATCH --build-system=(.*) : $(ARGV) ] ;
+    build-system ?= build-system ;
+
+    # Use last element in case of multiple command-line options
+    import $(build-system[-1]) ;
+}


Property changes on: boost-jam/boost-build/branches/upstream/current/kernel/bootstrap.jam
___________________________________________________________________
Name: svn:executable
   + 

Added: boost-jam/boost-build/branches/upstream/current/kernel/class.jam
===================================================================
--- boost-jam/boost-build/branches/upstream/current/kernel/class.jam	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/kernel/class.jam	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,430 @@
+#  (C) Copyright David Abrahams 2002. Permission to copy, use, modify, sell and
+#  distribute this software is granted provided this copyright notice appears in
+#  all copies. This software is provided "as is" without express or implied
+#  warranty, and with no claim as to its suitability for any purpose.
+
+# Polymorphic class system built on top of core Jam facilities.
+#
+# Classes are defined by 'class' keywords::
+#
+#     class myclass ( arg1 )          
+#     {
+#         rule __init__ ( )          # constructor
+#         {
+#             self.attribute = $(arg1) ;
+#         }
+#
+#         rule method1 ( )           # method
+#         {
+#             return [ method2 ] ;
+#         }
+#
+#         rule method2 ( )           # method
+#         {
+#             return $(self.attribute) ;
+#         }
+#     }
+#
+# The __init__ rule is the constructor, and sets member variables.
+#
+# New instances are created by invoking [ new <class> <args...> ]::
+#
+#     local x = [ new myclass foo ] ;        # x is a new myclass object
+#     assert.result foo : [ $(x).method1 ] ; # $(x).method1 returns "foo"
+#
+# Derived class are created by mentioning base classes in the declaration::
+#
+#     class derived : myclass 
+#     {
+#          rule __init__ ( arg )
+#          {
+#              myclass.__init__ $(arg) ;  # call base __init__
+#
+#          }
+#
+#          rule method2 ( )           # method override
+#          {
+#              return $(self.attribute)XXX ;
+#          }
+#     }
+#
+# All methods operate virtually, replacing behavior in the base
+# classes. For example::
+#
+#     local y = [ new derived foo ] ;           # y is a new derived object
+#     assert.result fooXXX : [ $(y).method1 ] ; # $(y).method1 returns "foo"
+#
+# Each class instance is its own core Jam module. All instance
+# attributes and methods are accessible without additional
+# qualification from within the class instance. All rules imported in
+# class declaration, or visible in base classses are also visible.
+# Base methods are available in qualified form: base-name.method-name.
+# By convention, attribute names are prefixed with "self.".
+
+import numbers ;
+import errors : * ;
+import set ;
+import modules ;
+import assert ;
+
+classes = ;
+
+
+rule xinit ( instance : class )
+{
+    module $(instance)
+    {
+        __class__ = $(2) ;
+        __name__ = $(1) ;
+    }    
+}
+
+
+rule new ( class args * : * )
+{
+    .next-instance.$(class) ?= 1 ;
+    local id = object($(class))@$(.next-instance.$(class)) ;
+    
+    xinit $(id) : $(class) ;    
+       
+    INSTANCE $(id) : class@$(class) ;
+    IMPORT_MODULE $(id) : ;
+    $(id).__init__ $(args) : $(2) : $(3) : $(4) : $(5) : $(6) : $(7) : $(8) : $(9) ;
+          
+    # bump the next unique object name
+    .next-instance.$(class) = [ numbers.increment $(.next-instance.$(class)) ] ;
+    
+    # Return the name of the new instance.
+    return $(id) ;
+}
+
+
+rule bases ( class )
+{
+    #if ! ( $(class) in $(classes) )
+    #{
+    #    error class $(class) not defined ;
+    #}
+    
+    module class@$(class)
+    {
+        return $(__bases__) ;
+    }
+}
+
+rule is-derived ( class : bases + )
+{
+    #local all = $(class) $(bases) ;
+    #if ! ( $(all) in $(classes) )
+    #{
+    #    error class(es) [ set.difference $(class) $(bases) : $(classes) ] not defined ;
+    #}
+    
+    local stack = $(class) ;
+    local visited found ;
+    while ( ! $(found) ) && $(stack)
+    {
+        local top = $(stack[1]) ;
+        stack = $(stack[2-]) ;
+        if ! ( $(top) in $(visited) )
+        {
+            visited += $(top) ;
+            stack += [ bases $(top) ] ;
+            
+            if $(bases) in $(visited)
+            {
+                found = true ;
+            }
+        }
+    }
+    return $(found) ;
+}
+
+# Returns true if the 'value' is a class instance.
+rule is-instance ( value # The value to check 
+     )
+{
+    return [ MATCH "^(object\\()[^@]+\\)@.*" : $(value) ] ;        
+}
+
+# Check if the given value is of the given type.
+#
+rule is-a (
+    instance # The value to check.
+    : type # The type to test for.
+    )
+{
+    if [ is-instance $(instance) ]
+    {
+        return [ class.is-derived [ modules.peek $(instance) : __class__ ] : $(type) ] ;
+    }
+}
+
+local rule typecheck ( x )
+{
+    local class-name = [ MATCH "^\\[(.*)\\]$" : [ BACKTRACE 1 ] ] ;
+    if ! [ is-a $(x) : $(class-name) ]
+    {
+        return "Expected an instance of "$(class-name)" but got \""$(x)"\" for argument" ;
+    }
+}
+
+local rule __test__ ( )
+{
+    import "class" : * ;
+    import assert ;
+    import errors : * ;
+
+    # This will be the construction function for a class called
+    # 'myclass'
+    class myclass 
+    {
+        import assert : nonempty-variable ;        
+        
+        rule __init__ ( x_ * : y_ * )
+        {            
+            # set some instance variables
+            x = $(x_) ;
+            y = $(y_) ;
+            foo += 10 ;
+        }
+        
+        rule set-x ( newx * )
+        {
+            x = $(newx) ;
+        }
+
+        rule get-x ( )
+        {
+            return $(x) ;
+        }
+
+        rule set-y ( newy * )
+        {
+            y = $(newy) ;
+        }
+
+        rule get-y ( )
+        {
+            return $(y) ;
+        }
+
+        rule f ( )
+        {
+            return [ g $(x) ] ;
+        }
+
+        rule g ( args * )
+        {
+            if $(x) in $(y)
+            {
+                return $(x) ;
+            }
+            else if $(y) in $(x)
+            {
+                return $(y) ;
+            }
+            else
+            {
+                return ;
+            }
+        }
+
+        rule get-class ( )
+        {
+            return $(__class__) ;
+        }
+        
+        rule get-instance ( )
+        {
+            return $(__name__) ;
+        }
+        
+        rule invariant ( )
+        {
+            assert.equal 1 : 1 ;
+        }                
+        
+        rule get-foo ( )
+        {
+            return $(foo) ;
+        }                        
+    }
+#    class myclass ;
+
+    class derived1 : myclass
+    {        
+        rule __init__ ( z_ )
+        {
+            myclass.__init__ $(z_) : X ;
+            z = $(z_) ;            
+        }
+        
+        # override g
+        rule g ( args * )
+        {
+            return derived1.g ;
+        }
+
+        rule h ( )
+        {
+            return derived1.h ;
+        }
+
+        rule get-z ( )
+        {
+            return $(z) ;
+        }
+
+        # Check that 'assert.equal' visible in base class is visible
+        # here.
+        rule invariant2 ( )
+        {
+            assert.equal 2 : 2 ;
+        }                
+        
+        # Check that 'nonempty-variable' visible in base class is
+        # visible here.
+        rule invariant3 ( )
+        {
+            local v = 10 ;
+            nonempty-variable v ;
+        }                
+    }
+#    class derived1 : myclass ;
+
+    class derived2 : myclass 
+    {
+        rule __init__ ( )
+        {            
+            myclass.__init__ 1 : 2 ;
+        }
+        
+        # override g
+        rule g ( args * )
+        {
+            return derived2.g ;
+        }
+
+         rule get-x ( )
+         {
+             # Test the ability to call base class functions with qualification.
+             return [ myclass.get-x ] ;
+         }
+    }
+#    class derived2 : myclass ;
+
+    class derived2a : derived2
+    {
+        rule __init__ 
+        {
+            derived2.__init__ ;
+        }                
+    }
+#    class derived2a : derived2 ;
+
+    local rule expect_derived2 ( [derived2] x ) { }
+
+    local a = [ new myclass 3 4 5 : 4 5 ] ;
+    local b = [ new derived1 4 ] ;
+    local b2 = [ new derived1 4 ] ;
+    local c = [ new derived2 ] ;
+    local d = [ new derived2 ] ;
+    local e = [ new derived2a ] ;
+
+    expect_derived2 $(d) ;
+    expect_derived2 $(e) ;
+
+    # argument checking is set up to call exit(1) directly on
+    # failure, and we can't hijack that with try, so we'd better
+    # not do this test by default.  We could fix this by having
+    # errors look up and invoke the EXIT rule instead; EXIT can be
+    # hijacked (;-)
+    if --fail-typecheck in [ modules.peek : ARGV ]
+    {
+        try ;
+        {
+            expect_derived2 $(a) ;
+        }
+        catch
+          "Expected an instance of derived2 but got" instead
+          ;
+    }
+
+
+    #try ;
+    #{
+    #    new bad_subclass ;
+    #}
+    #catch
+    #  bad_subclass.bad_subclass failed to call base class constructor myclass.__init__
+    #  ;
+
+    #try ;
+    #{
+    #    class bad_subclass ;
+    #}
+    #catch bad_subclass has already been declared ;
+
+    assert.result 3 4 5 : $(a).get-x ;
+    assert.result 4 5 : $(a).get-y ;
+    assert.result 4 : $(b).get-x ;
+    assert.result X : $(b).get-y ;
+    assert.result 4 : $(b).get-z ;
+    assert.result 1 : $(c).get-x ;
+    assert.result 2 : $(c).get-y ;
+    assert.result 4 5 : $(a).f ;
+    assert.result derived1.g : $(b).f ;
+    assert.result derived2.g : $(c).f ;
+    assert.result derived2.g : $(d).f ;
+    
+    assert.result 10 : $(b).get-foo ;
+    
+    $(a).invariant ;
+    $(b).invariant2 ;
+    $(b).invariant3 ;
+    
+    # Check that the __class__  attribute is getting properly set.
+    assert.result myclass : $(a).get-class ;
+    assert.result derived1 : $(b).get-class ;
+    assert.result $(a) : $(a).get-instance ;
+
+    $(a).set-x a.x ;
+    $(b).set-x b.x ;
+    $(c).set-x c.x ;
+    $(d).set-x d.x ;
+    assert.result a.x : $(a).get-x ;
+    assert.result b.x : $(b).get-x ;
+    assert.result c.x : $(c).get-x ;
+    assert.result d.x : $(d).get-x ;
+
+    class derived3 : derived1 derived2 
+    {
+        rule __init__ ( )
+        {
+        }
+    }
+    
+
+    assert.result : bases myclass ;
+    assert.result myclass : bases derived1 ;
+    assert.result myclass : bases derived2 ;
+    assert.result derived1 derived2 : bases derived3 ;
+
+    assert.true is-derived derived1 : myclass ;
+    assert.true is-derived derived2 : myclass ;
+    assert.true is-derived derived3 : derived1 ;
+    assert.true is-derived derived3 : derived2 ;
+    assert.true is-derived derived3 : derived1 derived2 myclass ;
+    assert.true is-derived derived3 : myclass ;
+
+    assert.false is-derived myclass : derived1 ;
+
+    assert.true is-instance $(a) ;
+    assert.false is-instance bar ;
+
+    assert.true is-a $(a) : myclass ;
+    assert.true is-a $(c) : derived2 ;
+    assert.true is-a $(d) : myclass ;
+    assert.false is-a literal : myclass ;
+}
\ No newline at end of file

Added: boost-jam/boost-build/branches/upstream/current/kernel/errors.jam
===================================================================
--- boost-jam/boost-build/branches/upstream/current/kernel/errors.jam	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/kernel/errors.jam	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,249 @@
+#  (C) Copyright David Abrahams 2001. Permission to copy, use, modify, sell and
+#  distribute this software is granted provided this copyright notice appears in
+#  all copies. This software is provided "as is" without express or implied
+#  warranty, and with no claim as to its suitability for any purpose.
+
+# Print a stack backtrace leading to this rule's caller. Each
+# argument represents a line of output to be printed after the first
+# line of the backtrace.
+rule backtrace ( skip-frames prefix messages * : * )
+{
+    local frame-skips = 5 9 13 17 21 25 29 33 37 41 45 49 53 57 61 65 69 73 77 81 ;
+    local drop-elements = $(frame-skips[$(skip-frames)]) ;
+    if ! ( $(skip-frames) in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 )
+    {
+        ECHO warning: backtrace doesn't support skipping
+          $(skip-frames) frames; using 1 instead. ;
+        drop-elements = 5 ;
+    }
+    
+    # get the whole backtrace, then drop the initial quadruples
+    # corresponding to the frames that must be skipped.
+    local bt = [ BACKTRACE ] ;
+    bt = $(bt[$(drop-elements)-]) ; 
+    
+    local args = $(.args) ;
+    while $(bt)
+    {
+        local m = [ MATCH ^(.+)\\.$ : $(bt[3]) ] ;
+        local user-modules = ([Jj]amfile(.jam|.v2)|user-config.jam|site-config.jam|project-root.jam) ;
+        
+        if $(.user-modules-only) 
+        {
+            if [ MATCH $(user-modules) : $(bt[1]:D=) ] 
+            {                
+                ECHO "$(prefix) at $(bt[1]):$(bt[2]) " ;
+            }            
+        }        
+        else          
+        {            
+            ECHO $(bt[1]):$(bt[2]): "in" $(bt[4]) "from module" $(m) ;
+        }
+                
+        # the first time through, print each argument on a separate
+        # line
+        for local n in $(args)
+        {
+            if $($(n))-is-not-empty
+            {
+                ECHO $(prefix) $($(n)) ;
+            }
+        }
+        args = ; # kill args so that this never happens again
+        
+        # Move on to the next quadruple
+        bt = $(bt[5-]) ;
+    }
+}
+
+.args ?= messages 2 3 4 5 6 7 8 9 ;
+.disabled ?= ;
+.last-error-$(.args) ?= ; 
+
+# try-catch --
+#
+# This is not really an exception-handling mechanism, but it does
+# allow us to perform some error-checking on our
+# error-checking. Errors are suppressed after a try, and the first one
+# is recorded. Use catch to check that the error message matched
+# expectations.
+
+# begin looking for error messages
+rule try ( )
+{
+    .disabled += true ;
+    .last-error-$(.args) = ;
+}
+
+# stop looking for error messages; generate an error if an argument of
+# messages is not found in the corresponding argument in the error call.
+rule catch ( messages * : * )
+{
+    .disabled = $(.disabled[2-]) ; # pop the stack    
+    
+    import sequence ;
+
+    if ! $(.last-error-$(.args))-is-nonempty
+    {
+        error-skip-frames 3 expected an error, but none occurred ;
+    }
+    else
+    {
+        for local n in $(.args)
+        {
+            if ! $($(n)) in $(.last-error-$(n))
+            {
+                local v = [ sequence.join $($(n)) : " " ] ;
+                v ?= "" ;
+                local joined = [ sequence.join $(.last-error-$(n)) : " " ] ;
+
+                .last-error-$(.args) = ;
+                error-skip-frames 3 expected \"$(v)\" in argument $(n) of error
+                  : got \"$(joined)\" instead ;
+            }
+        }
+    }
+}
+
+rule error-skip-frames ( skip-frames messages * : * )
+{
+    if ! $(.disabled)
+    {
+        backtrace $(skip-frames) error: $(messages) : $(2) : $(3) : $(4) : $(5) : $(6) : $(7) : $(8) : $(9) ;
+        EXIT ;
+    }
+    else if ! $(.last-error-$(.args))
+    {
+        for local n in $(.args)
+        {
+            # Add an extra empty string so that we always have
+            # something in the event of an error
+            .last-error-$(n) = $($(n)) "" ; 
+        }
+    }
+}
+
+if --no-error-backtrace in [ modules.peek : ARGV ] 
+{
+    .no-error-backtrace = true ;
+}
+
+
+# Print an error message with a stack backtrace and exit.
+rule error ( messages * : * )
+{
+    if $(.no-error-backtrace)
+    {
+        # Print each argument on a separate line.
+        for local n in $(.args)
+        {
+            if $($(n))-is-not-empty
+            {
+                if ! $(first-printed)
+                {                    
+                    ECHO error: $($(n)) ;
+                    first-printed = true ;
+                }
+                else
+                {
+                    ECHO $($(n)) ;                    
+                }                                
+            }
+        }        
+        EXIT ;
+    }
+    else
+    {        
+        error-skip-frames 3 $(1) : $(2) : $(3) : $(4) : $(5) : $(6) : $(7) : $(8) : $(9) ;
+    }    
+}
+
+# Same as 'error', but the generated backtrace will include only user files.
+rule user-error ( messages * : * )
+{
+    .user-modules-only = 1 ;
+    error-skip-frames 3 $(1) : $(2) : $(3) : $(4) : $(5) : $(6) : $(7) : $(8) : $(9) ;
+}
+
+
+# Print a warning message with a stack backtrace and exit.
+rule warning
+{
+    backtrace 2 warning: $(1) : $(2) : $(3) : $(4) : $(5) : $(6) : $(7) : $(8) : $(9) ;
+}
+
+# convert an arbitrary argument list into a list with ":" separators
+# and quoted elements representing the same information. This is
+# mostly useful for formatting descriptions of the arguments with
+# which a rule was called when reporting an error.
+rule lol->list ( * )
+{
+    local result ;
+    local remaining = 1 2 3 4 5 6 7 8 9 ;
+    while $($(remaining))
+    {
+        local n = $(remaining[1]) ;
+        remaining = $(remaining[2-]) ;
+        
+        if $(n) != 1
+        {
+            result += ":" ;
+        }
+        result += \"$($(n))\" ;
+    }
+    return $(result) ;
+}
+
+# Return the file:line for the nearest entry in backtrace which correspond
+# to a user module.
+rule nearest-user-location ( )
+{
+    local bt = [ BACKTRACE ] ;
+    
+    local result ;
+    while $(bt) && ! $(result)
+    {
+        local m = [ MATCH ^(.+)\\.$ : $(bt[3]) ] ;
+        local user-modules = ([Jj]amfile(.jam|.v2|)|user-config.jam|site-config.jam|project-root.jam) ;
+        
+        if [ MATCH $(user-modules) : $(bt[1]:D=) ] 
+        {                
+            result = $(bt[1]):$(bt[2]) ;
+        }            
+        bt = $(bt[5-]) ;
+    }
+    return $(result) ;
+}
+
+
+rule __test__ ( )
+{
+    # show that we can correctly catch an expected error
+    try ;
+    {
+        error an error occurred : somewhere ;
+    }
+    catch an error occurred : somewhere ;
+    
+    # show that unexpected errors generate real errors
+    try ;
+    {
+        try ;
+        {
+            error an error occurred : somewhere ;
+        }
+        catch an error occurred : nowhere ;
+    }
+    catch expected \"nowhere\" in argument 2 ;
+    
+    # show that not catching an error where one was expected is an
+    # error
+    try ;
+    {
+        try ;
+        {
+        }
+        catch ;
+    }
+    catch expected an error, but none occurred ;
+}


Property changes on: boost-jam/boost-build/branches/upstream/current/kernel/errors.jam
___________________________________________________________________
Name: svn:executable
   + 

Added: boost-jam/boost-build/branches/upstream/current/kernel/modules.jam
===================================================================
--- boost-jam/boost-build/branches/upstream/current/kernel/modules.jam	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/kernel/modules.jam	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,329 @@
+#  (C) Copyright David Abrahams 2001. Permission to copy, use, modify, sell and
+#  distribute this software is granted provided this copyright notice appears in
+#  all copies. This software is provided "as is" without express or implied
+#  warranty, and with no claim as to its suitability for any purpose.
+
+# Essentially an include guard; ensures that no module is loaded multiple times
+.loaded ?= ;
+
+# A list of modules currently being loaded for error reporting of circular dependencies
+.loading ?= ;
+
+# A list of modules needing to be tested via __test__ rule
+.untested ?= ;
+
+# A list of modules which have been tested via __test__
+.tested ?= ;
+
+# meant to be invoked from import when no __test__ rule is defined in a given
+# module
+local rule no-test-defined
+{
+    import modules ;
+    if ! ( --quiet in [ modules.peek : ARGV ] )
+    {
+        ECHO warning: no __test__ rule defined in module $(__module__) ;
+    }
+}
+
+# return the binding of the given module
+rule binding ( module )
+{
+    return $($(module).__binding__) ;
+}
+
+# Sets the module-local value of a variable.  This is the most
+# reliable way to set a module-local variable in a different module;
+# it eliminates issues of name shadowing due to dynamic scoping.
+rule poke ( module-name ? : variables + : value * )
+{
+    module $(<)
+    {
+        $(>) = $(3) ;
+    }
+}
+
+# Returns the module-local value of a variable.  This is the most
+# reliable way to examine a module-local variable in a different
+# module; it eliminates issues of name shadowing due to dynamic
+# scoping.
+rule peek ( module-name ? : variables + )
+{
+    module $(<)
+    {
+        return $($(>)) ;
+    }
+}
+
+# Call the given rule locally in the given module. Use this for rules
+# which accept rule names as arguments, so that the passed rule may be
+# invoked in the context of the rule's caller (for example, if the
+# rule accesses module globals or is a local rule).
+rule call-in ( module-name ? : rule-name args * : * )
+{
+    module $(module-name)
+    {
+        return [ $(2) : $(3) : $(4) : $(5) : $(6) : $(7) : $(8) : $(9) ] ;
+    }
+}
+
+# Given a possibly qualified rule name and arguments, remove any
+# initial module qualification from the rule and invoke it in that
+# module.  If there is no module qualification, the rule is invoked in
+# the global module.
+rule call-locally ( qualified-rule-name args * : * )
+{
+    local module-rule = [ MATCH (.*)\\.(.*) : $(qualified-rule-name) ] ;
+    local rule-name = $(module-rule[2]) ;
+    rule-name ?= $(qualified-rule-name) ;
+    return [ 
+      call-in $(module-rule[1])
+        : $(rule-name) $(args) : $(2) : $(3) : $(4) : $(5) : $(6) : $(7) : $(8) : $(9)
+    ] ;
+}
+
+# load the indicated module if it is not already loaded.
+rule load (
+  module-name      # name of module to load. Rules will be defined in this module
+    : filename ?   # (partial) path to file; Defaults to $(module-name).jam
+    : search *     # Directories in which to search for filename. Defaults to $(BOOST_BUILD_PATH)
+)
+{
+    # Avoid loading modules twice
+    if ! ( $(module-name) in $(.loaded) )
+    {
+        filename ?= $(module-name).jam ;
+        
+        # Mark the module loaded so we don't try to load it recursively
+        .loaded += $(module-name) ;
+        
+        # suppress tests if any module loads are already in progress. 
+        local suppress-test = $(.loading[1]) ;
+        
+        # Push this module on the loading stack
+        .loading += $(module-name) ;
+        
+        # Remember that it's untested
+        .untested += $(module-name) ; 
+        
+        # Insert the new module's __name__ and __file__ globals
+        poke $(module-name) : __name__ : $(module-name) ;
+        poke $(module-name) : __file__ : $(filename) ;
+        
+        module $(module-name)
+        {
+            # Prepare a default behavior, in case no __test__ is defined.
+            IMPORT modules : no-test-defined : $(__name__) : __test__ ;
+
+            # Add some grist so that the module will have a unique target name
+            local module-target = $(__file__:G=module@) ;
+            
+            local search = $(3) ;
+            search ?= [ modules.peek : BOOST_BUILD_PATH ] ;
+            SEARCH on $(module-target) = $(search) ;
+            BINDRULE on $(module-target) = modules.record-binding ;
+            
+            include $(module-target) ;
+            
+            # Allow the module to see its own names with full qualification
+            local rules = [ RULENAMES $(__name__) ] ;
+            IMPORT $(__name__) : $(rules) : $(__name__) : $(__name__).$(rules) ;
+        }
+
+        if $(module-name) != modules && ! [ binding $(module-name) ]
+        {
+            import errors ;
+            errors.error "couldn't find module" $(module-name) in $(search) ;
+        }
+        
+        # Pop the loading stack. Must happen before testing or we'll find a circular loading dependency
+        .loading = $(.loading[1--2]) ;
+        
+        # Run any pending tests if this is an outer load
+        if ! $(suppress-test)
+        {
+            local argv = [ peek : ARGV ] ;
+            for local m in $(.untested)
+            {
+                if ( ! $(m) in $(.tested) )    # avoid recursive test invocations
+                   && ( ( --debug in $(argv) ) || ( --debug-module=$(m) in $(argv) ) )
+                {
+                    .tested += $(m) ;
+                    if ! ( --quiet in $(argv) )
+                    {
+                        ECHO testing module $(m)... ;
+                    }
+                    
+                    # Import m's rules into __test-$(m)__ for easy access
+                    IMPORT $(m) : [ RULENAMES $(m) ] : __test-$(m)__ : [ RULENAMES $(m) ] ;
+                    
+                    # execute the module's __test__ rule in its own module to
+                    # eliminate the inadvertent effects of testing
+                    # module dependencies (such as assert) on the module itself.
+                    IMPORT $(m) : __test__ : __test-$(m)__ : __test__ : LOCALIZE ;
+                    
+                    module __test-$(m)__
+                    {
+                        # set up the name of the module we're testing
+                        # so that no-test-defined can find it.
+                        __module__ = $(1) ; 
+                        __test__ ;
+                    }
+                }
+            }
+            .untested = ;
+        }
+    }
+    else if $(module-name) in $(.loading)
+    {
+        import errors ;
+        errors.error loading \"$(module-name)\"
+        : circular module loading dependency:
+        : $(.loading)" ->" $(module-name) ;
+    }
+}
+
+# This helper is used by load (above) to record the binding (path) of
+# each loaded module.
+rule record-binding ( module-target : binding )
+{
+    $(.loading[-1]).__binding__ = $(binding) ;
+}
+
+# Transform each path in the list, with all backslashes converted to
+# forward slashes and all detectable redundancy removed.  Something
+# like this is probably needed in path.jam, but I'm not sure of that,
+# I don't understand it, and I'm not ready to move all of path.jam
+# into the kernel.
+local rule normalize-raw-paths ( paths * )
+{
+    local result ;
+    for p in $(paths:T)
+    {
+        result += [ NORMALIZE_PATH $(p) ] ;
+    }
+    return $(result) ;
+}
+
+# load the indicated module and import rule names into the current
+# module. Any members of rules-opt will be available without
+# qualification in the caller's module. Any members of rename-opt will
+# be taken as the names of the rules in the caller's module, in place
+# of the names they have in the imported module. If rules-opt = '*',
+# all rules from the indicated module are imported into the caller's
+# module. If rename-opt is supplied, it must have the same number of
+# elements as rules-opt.
+rule import ( module-names + : rules-opt * : rename-opt * )
+{
+    if $(rules-opt) = * || ! $(rules-opt) 
+    {
+        if $(rename-opt)
+        {
+            errors.error "rule aliasing is only available for explicit imports." ;
+        }
+    }
+    
+    if $(module-names[2]) && ( $(rules-opt) || $(rename-opt) )
+    {
+        errors.error when loading multiple modules, no specific rules or renaming is allowed ;
+    }
+    
+    local caller = [ CALLER_MODULE ] ;    
+        
+    # Import each specified module
+    for local m in $(module-names)
+    {
+        if ! $(m) in $(.loaded)
+        {           
+            # if the importing module isn't already in the BOOST_BUILD_PATH,
+            # prepend it to the path.  We don't want to invert the search
+            # order of modules that are already there.
+            local cwd = [ PWD ] ;
+            
+            local caller-location ; 
+            if $(caller)
+            {
+                caller-location = [ binding $(caller) ] ;
+                caller-location = $(caller-location:D) ;
+                caller-location = [ normalize-raw-paths $(caller-location:R=$(cwd)) ] ;
+            }
+            
+            local search = [ peek : BOOST_BUILD_PATH ] ;
+            search = [ normalize-raw-paths $(search:R=$(cwd)) ] ;
+            
+            if $(caller-location) && ! $(caller-location) in $(search)
+            {
+                search = $(caller-location) $(search) ;
+            }
+                        
+            load $(m) : : $(search) ;
+        }
+        
+        IMPORT_MODULE $(m) : $(caller) ;
+                    
+        if $(rules-opt)
+        {
+            local source-names ;
+            if $(rules-opt) = *
+            {
+                local all-rules = [ RULENAMES $(m) ] ;
+                source-names = $(all-rules) ;
+            }
+            else
+            {
+                source-names = $(rules-opt) ;
+            }
+            local target-names = $(rename-opt) ;
+            target-names ?= $(source-names) ;
+            IMPORT $(m) : $(source-names) : $(caller) : $(target-names) ;
+        }
+    }
+}
+
+# Define exported copies in $(target-module) of all rules exported
+# from $(source-module).  Also make them available in the global
+# module with qualification, so that it is just as though the rules
+# were defined originally in $(target-module).
+rule clone-rules (
+    source-module
+    target-module 
+    )
+{
+    local rules = [ RULENAMES $(source-module) ] ;
+    
+    IMPORT $(source-module) : $(rules) : $(target-module) : $(rules) : LOCALIZE ;
+    EXPORT $(target-module) : $(rules) ;
+    IMPORT $(target-module) : $(rules) : : $(target-module).$(rules) ;
+}
+
+# These rules need to be available in all modules to implement
+# module loading itself and other fundamental operations.
+local globalize = peek poke record-binding ;
+IMPORT modules : $(globalize) : : modules.$(globalize) ;
+
+local rule __test__ ( )
+{
+    import assert ;
+    import modules : normalize-raw-paths ;
+    
+    module modules.__test__
+    {
+        foo = bar ;
+    }
+    
+    assert.result bar : peek modules.__test__ : foo ;
+    poke modules.__test__ : foo : bar baz ;
+    assert.result bar baz : peek modules.__test__ : foo ;
+    assert.result c:/foo/bar : normalize-raw-paths c:/x/../foo/./xx/yy/../../bar ;
+    assert.result . : normalize-raw-paths . ;
+    assert.result .. : normalize-raw-paths .. ;
+    assert.result ../.. : normalize-raw-paths ../.. ;
+    assert.result .. : normalize-raw-paths ./.. ;
+    assert.result / / : normalize-raw-paths / \\ ;
+    assert.result a : normalize-raw-paths a ;
+    assert.result a : normalize-raw-paths a/ ;
+    assert.result /a : normalize-raw-paths /a/ ;
+    assert.result / : normalize-raw-paths /a/.. ;
+}
+
+


Property changes on: boost-jam/boost-build/branches/upstream/current/kernel/modules.jam
___________________________________________________________________
Name: svn:executable
   + 

Added: boost-jam/boost-build/branches/upstream/current/options/help.jam
===================================================================
--- boost-jam/boost-build/branches/upstream/current/options/help.jam	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/options/help.jam	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,174 @@
+# (C) Copyright David Abrahams, 2003.
+# (C) Copyright Rene Rivera, 2003.
+#
+# See accompanying license for terms and conditions of use.
+#
+
+# This module is the plug-in handler for the --help and --help-.*
+# command-line options
+import modules ;
+import assert ;
+import doc : do-scan set-option set-output set-output-file print-help-usage print-help-top ;
+import sequence ;
+import set ;
+
+
+# List of possible modules, but which really aren't.
+#
+.not-modules =
+    boost-build bootstrap site-config test user-config
+    -tools allyourbase boost-base features python stlport testing unit-tests ;
+
+# The help system options are parsed here and handed off to the doc
+# module to translate into documentation requests and actions. The
+# understood options are::
+#
+#    --help-all
+#    --help-enable-<option>
+#    --help-disable-<option>
+#    --help-output <type>
+#    --help-output-file <file>
+#    --help-options
+#    --help-usage
+#    --help [<module-or-class>]
+#
+rule process (
+    command # The option.
+    : values * # The values, starting after the "=".
+    )
+{
+    assert.result --help : MATCH ^(--help).* : $(command) ;
+    local did-help = ;
+    switch $(command)
+    {
+        case --help-all :
+        local path-to-modules = [ modules.peek : BOOST_BUILD_PATH ] ;
+        path-to-modules ?= . ;
+        local possible-modules = [ GLOB $(path-to-modules) : *\\.jam ] ;
+        local not-modules = [ GLOB $(path-to-modules) : *$(.not-modules)\\.jam ] ;
+        local modules-to-list =
+            [ sequence.insertion-sort
+                [ set.difference $(possible-modules:D=:S=) : $(not-modules:D=:S=) ] ] ;
+        local modules-to-scan ;
+        for local m in $(modules-to-list)
+        {
+            local module-files = [ GLOB $(path-to-modules) : $(m)\\.jam ] ;
+            modules-to-scan += $(module-files[1]) ;
+        }
+        do-scan $(modules-to-scan[1--2]) ;
+        do-scan $(modules-to-scan[-1]) : print-help-all ;
+        did-help = true ;
+        
+        case --help-enable-* :
+        local option = [ MATCH --help-enable-(.*) : $(command) ] ; option = $(option:L) ;
+        set-option $(option) : enabled ;
+        did-help = true ;
+        
+        case --help-disable-* :
+        local option = [ MATCH --help-disable-(.*) : $(command) ] ; option = $(option:L) ;
+        set-option $(option) ;
+        did-help = true ;
+        
+        case --help-output :
+        set-output $(values[1]) ;
+        did-help = true ;
+        
+        case --help-output-file :
+        set-output-file $(values[1]) ;
+        did-help = true ;
+        
+        case --help-options :
+        local doc-module-spec = [ split-symbol doc ] ;
+        do-scan $(doc-module-spec[1]) : print-help-options ;
+        did-help = true ;
+        
+        case --help-usage :
+        print-help-usage ;
+        did-help = true ;
+        
+        case --help :
+        local spec = $(values[1]) ;
+        if $(spec)
+        {
+            local spec-parts = [ split-symbol $(spec) ] ;
+            if $(spec-parts)
+            {
+                if $(spec-parts[2])
+                {
+                    do-scan $(spec-parts[1]) : print-help-classes $(spec-parts[2]) ;
+                    do-scan $(spec-parts[1]) : print-help-rules $(spec-parts[2]) ;
+                    do-scan $(spec-parts[1]) : print-help-variables $(spec-parts[2]) ;
+                }
+                else
+                {
+                    do-scan $(spec-parts[1]) : print-help-module ;
+                }
+            }
+            else
+            {
+                EXIT "Unrecognized help option '"$(command)" "$(spec)"'." ;
+            }
+        }
+        else
+        {
+            print-help-top ;
+        }
+        did-help = true ;
+    }
+    if $(did-help)
+    {
+        UPDATE all ;
+    }
+    return $(did-help) ;
+}
+
+# Split a reference to a symbol into module and symbol parts.
+#
+local rule split-symbol (
+    symbol # The symbol to split.
+    )
+{
+    local path-to-modules = [ modules.peek : BOOST_BUILD_PATH ] ;
+    path-to-modules ?= . ;
+    local module-name = $(symbol) ;
+    local symbol-name = ;
+    local result = ;
+    while ! $(result)
+    {
+        local module-path = [ GLOB $(path-to-modules) : $(module-name)\\.jam ] ;
+        if $(module-path)
+        {
+            # The 'module-name' in fact refers to module. Return the full 
+            # module path and a symbol within it. If 'symbol' passed to this 
+            # rule is already module, 'symbol-name' will be empty. Otherwise, 
+            # it's initialized on the previous loop iteration. 
+            # In case there are several modules by this name, 
+            # use the first one.
+            result = $(module-path[1]) $(symbol-name) ;
+        }
+        else
+        {
+            if ! $(module-name:S)
+            {
+                result = - ;
+            }
+            else
+            {
+                local next-symbol-part = [ MATCH ^.(.*) : $(module-name:S) ] ;
+                if $(symbol-name)
+                {
+                    symbol-name = $(next-symbol-part).$(symbol-name) ;
+                }
+                else
+                {
+                    symbol-name = $(next-symbol-part) ;
+                }
+                module-name = $(module-name:B) ;
+            }
+        }
+    }
+    if $(result) != -
+    {
+        return $(result) ;
+    }
+}


Property changes on: boost-jam/boost-build/branches/upstream/current/options/help.jam
___________________________________________________________________
Name: svn:executable
   + 

Added: boost-jam/boost-build/branches/upstream/current/site-config.jam
===================================================================
--- boost-jam/boost-build/branches/upstream/current/site-config.jam	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/site-config.jam	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1 @@
+# No copyright, since this file is empty

Added: boost-jam/boost-build/branches/upstream/current/test/BoostBuild.py
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/BoostBuild.py	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/BoostBuild.py	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,625 @@
+
+import TestCmd
+from tree import build_tree, trees_difference
+import copy
+import fnmatch
+import os
+import shutil
+import string
+import types
+import time
+import tempfile
+import sys
+import re
+
+def get_toolset():
+    toolset = None;
+    for arg in sys.argv[1:]:
+        if not arg.startswith('-'):
+            toolset = arg
+    return toolset or 'gcc'
+
+windows = 0
+suffixes = {}
+
+# Prepare the map of suffixes
+def prepare_suffix_map(toolset):
+    global windows, suffixes    
+    suffixes = {'.exe': '', '.dll': '.so', '.lib': '.a', '.obj': '.o'}
+    if os.environ.get('OS','').lower().startswith('windows') or \
+       os.__dict__.has_key('uname') and \
+       os.uname()[0].lower().startswith('cygwin'):
+        windows = 1
+        suffixes = {}
+        if toolset in ["gcc"]:
+            suffixes['.lib'] = '.a' # static libs have '.a' suffix with mingw...
+            suffixes['.obj'] = '.o'
+    if os.__dict__.has_key('uname') and os.uname()[0] == 'Darwin':
+        suffixes['.dll'] = '.dylib'
+
+        
+    
+    
+#
+# FIXME: this is copy-pasted from TestSCons.py
+# Should be moved to TestCmd.py?
+#
+if os.name == 'posix':
+    def _failed(self, status = 0):
+        if self.status is None:
+            return None
+        if os.WIFSIGNALED(status):
+            return None
+        return _status(self) != status
+    def _status(self):
+        if os.WIFEXITED(self.status):
+            return os.WEXITSTATUS(self.status)
+        else:
+            return None
+elif os.name == 'nt':
+    def _failed(self, status = 0):
+        return not self.status is None and self.status != status
+    def _status(self):
+        return self.status
+
+class Tester(TestCmd.TestCmd):
+    """Class for testing Boost.Build.
+
+    Optional argument `executable` indicates the name of the
+    executable to invoke. Set this to "jam" to test Boost.Build v1
+    behavior.
+    """
+    def __init__(self, arguments="", executable = 'bjam', match =
+                 TestCmd.match_exact, boost_build_path = None,
+                 translate_suffixes = 1, pass_toolset = 1,
+                 **keywords):
+
+        self.original_workdir = os.getcwd()
+        self.last_build_time = 0
+        self.translate_suffixes = translate_suffixes
+
+        self.toolset = get_toolset()
+        self.pass_toolset = pass_toolset
+        
+        prepare_suffix_map(pass_toolset and self.toolset or 'gcc')
+
+        jam_build_dir = ""
+        if os.name == 'nt':
+            jam_build_dir = "bin.ntx86"
+        elif os.name == 'posix' and os.__dict__.has_key('uname'):
+            if os.uname()[0].lower().startswith('cygwin'):
+                jam_build_dir = "bin.cygwinx86"
+                if 'TMP' in os.environ and os.environ['TMP'].find('~') != -1:
+                    print 'Setting $TMP to /tmp to get around problem with short path names'
+                    os.environ['TMP'] = '/tmp'
+            elif os.uname()[0] == 'Linux':
+                jam_build_dir = "bin.linuxx86"
+            elif os.uname()[0] == 'SunOS':
+                jam_build_dir = "bin.solaris"
+            elif os.uname()[0] == 'Darwin':
+                jam_build_dir = "bin.macosxppc"
+            elif os.uname()[0] == "AIX":
+                jam_build_dir = "bin.aix"
+            elif os.uname()[0] == "IRIX64":
+                jam_build_dir = "bin.irix"
+            else:
+                raise "Don't know directory where jam is build for this system: " + os.name + "/" + os.uname()[0]
+        else:
+            raise "Don't know directory where jam is build for this system: " + os.name
+
+        if boost_build_path is None:
+            boost_build_path = self.original_workdir
+            
+
+        verbosity = ['-d0', '--quiet']
+        if '--verbose' in sys.argv:
+            keywords['verbose'] = 1
+            verbosity = ['-d+2']
+
+        program_list = []
+
+        # Find there jam_src is located.
+        # try for the debug version if it's lying around
+
+        dirs = [os.path.join('../../jam_src', jam_build_dir + '.debug'),
+                os.path.join('../../jam_src', jam_build_dir),
+                os.path.join('../jam_src', jam_build_dir + '.debug'),
+                os.path.join('../jam_src', jam_build_dir),
+                ]
+
+        for d in dirs:
+            if os.path.exists(d):
+                jam_build_dir = d
+                break
+        else:
+            print "Cannot find built Boost.Jam"
+            os.exit(1)                                    
+        
+            
+        program_list.append(os.path.join(jam_build_dir, executable))
+        program_list.append('-sBOOST_BUILD_PATH=' + boost_build_path)
+        if verbosity:
+            program_list += verbosity
+        if arguments:
+            program_list += arguments.split(" ")
+
+        TestCmd.TestCmd.__init__(
+            self
+            , program=program_list
+            , match=match
+            , workdir=''
+            , **keywords)
+
+        os.chdir(self.workdir)
+
+    def cleanup(self):
+        try:
+            TestCmd.TestCmd.cleanup(self)
+            os.chdir(self.original_workdir)
+        except AttributeError:
+            # Whe this is called during by TestCmd.TestCmd.__del__ we can have both
+            # 'TestCmd' and 'os' unavailable in our scope. Do nothing in this case.
+            pass
+            
+    #
+    # Methods that change working directory's content
+    #
+    def set_tree(self, tree_location):
+        # Seem like it's not possible to remove a directory which is
+        # current.
+        d = os.getcwd()
+        os.chdir(os.path.dirname(self.workdir))
+        shutil.rmtree(self.workdir, ignore_errors=0)
+
+        if not os.path.isabs(tree_location):
+                tree_location = os.path.join(self.original_workdir, tree_location)
+        shutil.copytree(tree_location, self.workdir)
+
+        os.chdir(d)
+
+        def make_writable(unused, dir, entries):
+            for e in entries:
+                name = os.path.join(dir, e)
+                os.chmod(name, os.stat(name)[0] | 0222)
+
+        os.path.walk(".", make_writable, None)
+
+
+    def write(self, file, content):
+        self.wait_for_time_change()
+        nfile = self.native_file_name(file)
+        try:
+            os.makedirs(os.path.dirname(nfile))
+        except Exception, e:
+            pass
+        open(nfile, "wb").write(content)
+
+    def rename(self, old, new):
+        try:
+            os.makedirs(os.path.dirname(new))
+        except:
+            pass
+        
+        try:
+            os.remove(new)
+        except:
+            pass
+        
+        os.rename(old, new)
+        self.touch(new);
+
+    def copy(self, src, dst):
+        self.wait_for_time_change()
+        self.write(dst, self.read(src))
+
+    def touch(self, names):
+        self.wait_for_time_change()
+        for name in self.adjust_names(names):
+                os.utime(self.native_file_name(name), None)
+
+    def rm(self, names):
+        self.wait_for_time_change()
+        if not type(names) == types.ListType:
+            names = [names]
+
+        # Avoid attempts to remove current dir
+        os.chdir(self.original_workdir)
+        for name in names:
+            n = self.native_file_name(name)
+            if os.path.isdir(n):
+                shutil.rmtree(n, ignore_errors=0)
+            else:
+                os.unlink(n)
+
+        # Create working dir root again, in case
+        # we've removed it
+        if not os.path.exists(self.workdir):
+            os.mkdir(self.workdir)
+        os.chdir(self.workdir)
+
+    def expand_toolset(self, name):
+        """Expands $toolset in the given file to tested toolset"""
+        content = self.read(name)
+        content = string.replace(content, "$toolset", self.toolset)
+        self.write(name, content)
+                                                        
+    def dump_stdio(self):
+        print "STDOUT ============"
+        print self.stdout()    
+        print "STDERR ============"
+        print self.stderr()
+        print "END ==============="
+                    
+    #
+    #   FIXME: Large portion copied from TestSCons.py, should be moved?
+    #
+    def run_build_system(
+        self, extra_args='', subdir='', stdout = None, stderr = '',
+        status = 0, match = None, pass_toolset = None, **kw):
+
+        self.previous_tree = build_tree(self.workdir)
+
+        if match is None:
+            match = self.match
+
+        if pass_toolset is None:
+            pass_toolset = self.pass_toolset        
+
+        try:
+            kw['program'] = []
+            kw['program'] += self.program
+            if extra_args:
+                kw['program'] += extra_args.split(" ")            
+            if pass_toolset:
+                kw['program'].append(self.toolset)
+            kw['chdir'] = subdir
+            apply(TestCmd.TestCmd.run, [self], kw)
+        except:
+            self.dump_stdio()
+            raise
+
+        if status != None and _failed(self, status):
+            expect = ''
+            if status != 0:
+                expect = " (expected %d)" % status
+
+            print '"%s" returned %d%s' % (
+                kw['program'], _status(self), expect)
+
+            self.fail_test(1)
+
+        if not stdout is None and not match(self.stdout(), stdout):
+            print "Expected STDOUT =========="
+            print stdout
+            print "Actual STDOUT ============"
+            print self.stdout()
+            stderr = self.stderr()
+            if stderr:
+                print "STDERR ==================="
+                print stderr
+            self.maybe_do_diff(self.stdout(), stdout)
+            self.fail_test(1, dump_stdio = 0)
+
+        # Intel tends to produce some message to stderr, which makes tests
+        # fail
+        intel_workaround = re.compile("^xi(link|lib): executing.*\n", re.M)
+        actual_stderr = re.sub(intel_workaround, "", self.stderr())
+
+        if not stderr is None and not match(actual_stderr, stderr):
+            print "STDOUT ==================="
+            print self.stdout()
+            print "Expected STDERR =========="
+            print stderr
+            print "Actual STDERR ============"
+            print actual_stderr
+            self.maybe_do_diff(actual_stderr, stderr)
+            self.fail_test(1, dump_stdio = 0)
+
+        self.tree = build_tree(self.workdir)
+        self.difference = trees_difference(self.previous_tree, self.tree)
+        self.difference.ignore_directories()
+        self.unexpected_difference = copy.deepcopy(self.difference)
+
+        self.last_build_time = time.time()
+
+    def read(self, name):
+        return open(self.native_file_name(name), "rb").read()
+
+    def read_and_strip(self, name):
+        lines = open(self.native_file_name(name), "rb").readlines()
+        result = string.join(map(string.rstrip, lines), "\n")
+        if lines and lines[-1][-1] == '\n':
+            return result + '\n'
+        else:
+            return result
+    
+    def fail_test(self, condition, dump_stdio = 1, *args):
+        # If test failed, print the difference        
+        if condition and hasattr(self, 'difference'):            
+            print '-------- all changes caused by last build command ----------'
+            self.difference.pprint()
+            
+        if condition and dump_stdio:
+            self.dump_stdio()
+
+        if '--preserve' in sys.argv:
+            print 
+            print "*** Copying the state of working dir into 'failed_test' ***"
+            print 
+            path = os.path.join(self.original_workdir, "failed_test")
+            if os.path.isdir(path):
+                shutil.rmtree(path, ignore_errors=0)
+            elif os.path.exists(path):
+                raise "The path " + path + " already exists and is not directory";
+            shutil.copytree(self.workdir, path)
+                        
+        TestCmd.TestCmd.fail_test(self, condition, *args)
+        
+    # A number of methods below check expectations with actual difference
+    # between directory trees before and after build.
+    # All the 'expect*' methods require exact names to be passed.
+    # All the 'ignore*' methods allow wildcards.
+
+    # All names can be lists, which are taken to be directory components
+    def expect_addition(self, names):        
+        for name in self.adjust_names(names):
+                try:
+                        self.unexpected_difference.added_files.remove(name)
+                except:
+                        print "File %s not added as expected" % (name,)
+                        self.fail_test(1)
+
+    def ignore_addition(self, wildcard):
+        self.ignore_elements(self.unexpected_difference.added_files, wildcard)
+
+    def expect_removal(self, names):
+        for name in self.adjust_names(names):
+                try:
+                        self.unexpected_difference.removed_files.remove(name)
+                except:
+                        print "File %s not removed as expected" % (name,)
+                        self.fail_test(1)
+
+    def ignore_removal(self, wildcard):
+        self.ignore_elements(self.unexpected_difference.removed_files, wildcard)
+
+    def expect_modification(self, names):
+        for name in self.adjust_names(names):
+                try:
+                        self.unexpected_difference.modified_files.remove(name)
+                except:
+                        print "File %s not modified as expected" % (name,)
+                        self.fail_test(1)
+
+    def ignore_modification(self, wildcard):
+        self.ignore_elements(self.unexpected_difference.modified_files, wildcard)
+
+    def expect_touch(self, names):
+        
+        d = self.unexpected_difference
+        for name in self.adjust_names(names):
+
+            # We need to check in both touched and modified files.
+            # The reason is that:
+            # (1) for windows binaries often have slight
+            # differences even with identical inputs
+            # (2) Intel's compiler for Linux has the same behaviour        
+            filesets = [d.modified_files, d.touched_files]
+
+            while filesets:
+                try:
+                    filesets[-1].remove(name)
+                    break
+                except ValueError:
+                    filesets.pop()
+
+            if not filesets:
+                print "File %s not touched as expected" % (name,)
+                self.fail_test(1)
+
+
+    def ignore_touch(self, wildcard):
+        self.ignore_elements(self.unexpected_difference.touched_files, wildcard)
+
+    def ignore(self, wildcard):
+        self.ignore_elements(self.unexpected_difference.added_files, wildcard)
+        self.ignore_elements(self.unexpected_difference.removed_files, wildcard)
+        self.ignore_elements(self.unexpected_difference.modified_files, wildcard)
+        self.ignore_elements(self.unexpected_difference.touched_files, wildcard)
+
+    def expect_nothing(self, names):
+        for name in self.adjust_names(names):
+            if name in self.difference.added_files:
+                print "File %s is added, but no action was expected" % (name,)
+                self.fail_test(1)
+            if name in self.difference.removed_files:
+                print "File %s is removed, but no action was expected" % (name,)
+                self.fail_test(1)
+                pass
+            if name in self.difference.modified_files:
+                print "File %s is modified, but no action was expected" % (name,)
+                self.fail_test(1)
+            if name in self.difference.touched_files:
+                print "File %s is touched, but no action was expected" % (name,)
+                self.fail_test(1)
+
+    def expect_nothing_more(self):
+
+        # not totally sure about this change, but I don't see a good alternative
+        if windows:
+            self.ignore('*.ilk') # msvc incremental linking files
+            self.ignore('*.pdb') # msvc program database files
+            self.ignore('*.rsp') # response files
+            self.ignore('*.tds') # borland debug symbols
+
+        # debug builds of bjam built with gcc produce this profiling data
+        self.ignore('gmon.out')
+        self.ignore('*/gmon.out')
+            
+        if not self.unexpected_difference.empty():
+           print 'FAILED'
+           print '------- The following changes were unexpected ------- '
+           self.unexpected_difference.pprint()
+           self.fail_test(1)       
+
+    def expect_content(self, name, content, exact=0):
+        name = self.adjust_names(name)[0]
+        try:
+            if exact:
+                actual = self.read(name)
+            else:
+                actual = string.replace(self.read_and_strip(name), "\\", "/")
+        except IOError:
+            print "Note: could not open file", name
+            self.fail_test(1)
+
+        content = string.replace(content, "$toolset", self.toolset)
+
+        if actual != content:
+            print "Expected:\n"
+            print content
+            print "Got:\n"
+            print actual
+            self.fail_test(1)
+
+    def maybe_do_diff(self, actual, expected):
+        if os.environ.has_key("DO_DIFF") and os.environ["DO_DIFF"] != '':
+            
+            e = tempfile.mktemp("expected")
+            a = tempfile.mktemp("actual")
+            open(e, "w").write(expected)
+            open(a, "w").write(actual)
+            print "DIFFERENCE"
+            if os.system("diff -u " + e + " " + a):
+                print "Unable to compute difference"               
+            os.unlink(e)
+            os.unlink(a)    
+        else:
+            print "Set environmental variable 'DO_DIFF' to examine difference." 
+
+    # Helpers
+    def mul(self, *arguments):
+        if len(arguments) == 0:
+                return None
+        else:
+                here = arguments[0]
+                if type(here) == type(''):
+                        here = [here]
+
+                if len(arguments) > 1:
+                        there = apply(self.mul, arguments[1:])
+                        result = []
+                        for i in here:
+                                for j in there:
+                                        result.append(i + j)
+                        return result
+                else:
+                        return here
+
+
+
+    # Internal methods
+    def ignore_elements(self, list, wildcard):
+        """Removes in-place, element of 'list' that match the given wildcard."""
+        list[:] = filter(lambda x, w=wildcard: not fnmatch.fnmatch(x, w), list)
+
+    def adjust_suffix(self, name):
+        if not self.translate_suffixes:
+            return name
+        
+        pos = string.rfind(name, ".")
+        if pos != -1:
+            suffix = name[pos:]
+            name = name[:pos]
+
+            if suffixes.has_key(suffix):
+                suffix = suffixes[suffix]
+        else:
+            suffix = ''
+
+        return name + suffix
+
+    # Acceps either string of list of string and returns list of strings
+    # Adjusts suffixes on all names.
+    def adjust_names(self, names):
+        if type(names) == types.StringType:
+                names = [names]
+        r = map(self.adjust_suffix, names)
+        r = map(lambda x, t=self.toolset: string.replace(x, "$toolset", t), r)
+        return r
+
+    def native_file_name(self, name):
+        name = self.adjust_names(name)[0]
+        elements = string.split(name, "/")
+        return os.path.normpath(apply(os.path.join, [self.workdir]+elements))
+
+    # Wait while time is no longer equal to the time last "run_build_system"
+    # call finished.
+    def wait_for_time_change(self):
+        while int(time.time()) == int(self.last_build_time):
+            time.sleep(0.1)
+
+            
+class List:
+
+    def __init__(self, s=""):
+        elements = []
+        if isinstance(s, type("")):          
+            # Have to handle espaced spaces correctly
+            s = string.replace(s, "\ ", '\001')
+            elements = string.split(s)
+        else:
+            elements = s;
+            
+        self.l = []            
+        for e in elements:
+            self.l.append(string.replace(e, '\001', ' '))
+
+    def __len__(self):
+        return len(self.l)
+
+    def __getitem__(self, key):
+        return self.l[key]
+
+    def __setitem__(self, key, value):
+        self.l[key] = value
+
+    def __delitem__(self, key):
+        del self.l[key]
+
+    def __str__(self):
+        return str(self.l)
+
+    def __repr__(self):
+        return ( self.__module__ + '.List('
+                 + repr(string.join(self.l, ' '))
+                 + ')')
+
+    def __mul__(self, other):        
+        result = List()
+        if not isinstance(other, List):
+            other = List(other)
+        for f in self:
+            for s in other:
+                result.l.append(f + s)
+        return result
+
+    def __rmul__(self, other):
+        if not isinstance(other, List):
+            other = List(other)        
+        return List.__mul__(other, self)
+
+    def __add__(self, other):
+        result = List()
+        result.l = self.l[:] + other.l[:]
+        return result
+
+# quickie tests. Should use doctest instead.
+if __name__ == '__main__':
+    assert str(List("foo bar") * "/baz") == "['foo/baz', 'bar/baz']"
+    assert repr("foo/" * List("bar baz")) == "__main__.List('foo/bar foo/baz')"
+    print 'tests passed'
+
+
+
+

Added: boost-jam/boost-build/branches/upstream/current/test/Jamfile
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/Jamfile	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/Jamfile	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,7 @@
+
+# establish a project root right here in the test directory, so that we can test
+# things independently of the boost jambase, etc.
+project-root ; 
+
+include check-test-tools.jam ;
+include check-jam-patches.jam ;

Added: boost-jam/boost-build/branches/upstream/current/test/Jamrules
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/Jamrules	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/Jamrules	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,4 @@
+# This simple Jamrules file is used for the Boost.Build test project.
+
+# The testing framework itself gets no boost-Jambase
+BOOST_JAMBASE = empty.jam ;

Added: boost-jam/boost-build/branches/upstream/current/test/TestCmd.py
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/TestCmd.py	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/TestCmd.py	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,602 @@
+"""
+TestCmd.py:  a testing framework for commands and scripts.
+
+The TestCmd module provides a framework for portable automated testing
+of executable commands and scripts (in any language, not just Python),
+especially commands and scripts that require file system interaction.
+
+In addition to running tests and evaluating conditions, the TestCmd module
+manages and cleans up one or more temporary workspace directories, and
+provides methods for creating files and directories in those workspace
+directories from in-line data, here-documents), allowing tests to be
+completely self-contained.
+
+A TestCmd environment object is created via the usual invocation:
+
+    test = TestCmd()
+
+The TestCmd module provides pass_test(), fail_test(), and no_result()
+unbound methods that report test results for use with the Aegis change
+management system.  These methods terminate the test immediately,
+reporting PASSED, FAILED, or NO RESULT respectively, and exiting with
+status 0 (success), 1 or 2 respectively.  This allows for a distinction
+between an actual failed test and a test that could not be properly
+evaluated because of an external condition (such as a full file system
+or incorrect permissions).
+"""
+
+# Copyright 2000 Steven Knight
+# This module is free software, and you may redistribute it and/or modify
+# it under the same terms as Python itself, so long as this copyright message
+# and disclaimer are retained in their original form.
+#
+# IN NO EVENT SHALL THE AUTHOR BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT,
+# SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF
+# THIS CODE, EVEN IF THE AUTHOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+# DAMAGE.
+#
+# THE AUTHOR SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+# PARTICULAR PURPOSE.  THE CODE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS,
+# AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
+# SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+
+from string import join, split
+
+__author__ = "Steven Knight <knight at baldmt.com>"
+__revision__ = "TestCmd.py 0.D002 2001/08/31 14:56:12 software"
+__version__ = "0.02"
+
+from types import *
+
+import os
+import os.path
+import popen2
+import re
+import shutil
+import stat
+import sys
+import tempfile
+import traceback
+
+tempfile.template = 'testcmd.'
+
+_Cleanup = []
+
+def _clean():
+    global _Cleanup
+    list = _Cleanup[:]
+    _Cleanup = []
+    list.reverse()
+    for test in list:
+        test.cleanup()
+
+sys.exitfunc = _clean
+
+def _caller(tblist, skip):
+    string = ""
+    arr = []
+    for file, line, name, text in tblist:
+        if file[-10:] == "TestCmd.py":
+                break
+        arr = [(file, line, name, text)] + arr
+    atfrom = "at"
+    for file, line, name, text in arr[skip:]:
+        if name == "?":
+            name = ""
+        else:
+            name = " (" + name + ")"
+        string = string + ("%s line %d of %s%s\n" % (atfrom, line, file, name))
+        atfrom = "\tfrom"
+    return string
+
+def fail_test(self = None, condition = 1, function = None, skip = 0):
+    """Cause the test to fail.
+
+    By default, the fail_test() method reports that the test FAILED
+    and exits with a status of 1.  If a condition argument is supplied,
+    the test fails only if the condition is true.
+    """
+    if not condition:
+        return
+    if not function is None:
+        function()
+    of = ""
+    desc = ""
+    sep = " "
+    if not self is None:
+        if self.program:
+            of = " of " + join(self.program, " ")
+            sep = "\n\t"
+        if self.description:
+            desc = " [" + self.description + "]"
+            sep = "\n\t"
+
+    at = _caller(traceback.extract_stack(), skip)
+
+    sys.stderr.write("FAILED test" + of + desc + sep + at + """
+in directory: """ + os.getcwd() )
+
+    sys.exit(1)
+
+def no_result(self = None, condition = 1, function = None, skip = 0):
+    """Causes a test to exit with no valid result.
+
+    By default, the no_result() method reports NO RESULT for the test
+    and exits with a status of 2.  If a condition argument is supplied,
+    the test fails only if the condition is true.
+    """
+    if not condition:
+        return
+    if not function is None:
+        function()
+    of = ""
+    desc = ""
+    sep = " "
+    if not self is None:
+        if self.program:
+            of = " of " + self.program
+            sep = "\n\t"
+        if self.description:
+            desc = " [" + self.description + "]"
+            sep = "\n\t"
+
+    at = _caller(traceback.extract_stack(), skip)
+    sys.stderr.write("NO RESULT for test" + of + desc + sep + at)
+
+    sys.exit(2)
+
+def pass_test(self = None, condition = 1, function = None):
+    """Causes a test to pass.
+
+    By default, the pass_test() method reports PASSED for the test
+    and exits with a status of 0.  If a condition argument is supplied,
+    the test passes only if the condition is true.
+    """
+    if not condition:
+        return
+    if not function is None:
+        function()
+    sys.stderr.write("PASSED\n")
+    sys.exit(0)
+
+def match_exact(lines = None, matches = None):
+    """
+    """
+    if not type(lines) is ListType:
+        lines = split(lines, "\n")
+    if not type(matches) is ListType:
+        matches = split(matches, "\n")
+    if len(lines) != len(matches):
+        return
+    for i in range(len(lines)):
+        if lines[i] != matches[i]:
+            return
+    return 1
+
+def match_re(lines = None, res = None):
+    """
+    """
+    if not type(lines) is ListType:
+        lines = split(lines, "\n")
+    if not type(res) is ListType:
+        res = split(res, "\n")
+    if len(lines) != len(res):
+        return
+    for i in range(len(lines)):
+        if not re.compile("^" + res[i] + "$").search(lines[i]):
+            return
+    return 1
+
+class TestCmd:
+    """Class TestCmd
+    """
+
+    def __init__(self, description = None,
+                        program = None,
+                        interpreter = None,
+                        workdir = None,
+                        subdir = None,
+                        verbose = 0,
+                        match = None):
+        self._cwd = os.getcwd()
+        self.description_set(description)
+        self.program_set(program)
+        self.interpreter_set(interpreter)
+        self.verbose_set(verbose)
+        if not match is None:
+            self.match_func = match
+        else:
+            self.match_func = match_re
+        self._dirlist = []
+        self._preserve = {'pass_test': 0, 'fail_test': 0, 'no_result': 0}
+        if os.environ.has_key('PRESERVE') and not os.environ['PRESERVE'] is '':
+            self._preserve['pass_test'] = os.environ['PRESERVE']
+            self._preserve['fail_test'] = os.environ['PRESERVE']
+            self._preserve['no_result'] = os.environ['PRESERVE']
+        else:
+            try:
+                self._preserve['pass_test'] = os.environ['PRESERVE_PASS']
+            except KeyError:
+                pass
+            try:
+                self._preserve['fail_test'] = os.environ['PRESERVE_FAIL']
+            except KeyError:
+                pass
+            try:
+                self._preserve['no_result'] = os.environ['PRESERVE_NO_RESULT']
+            except KeyError:
+                pass
+        self._stdout = []
+        self._stderr = []
+        self.status = None
+        self.condition = 'no_result'
+        self.workdir_set(workdir)
+        self.subdir(subdir)
+
+    def __del__(self):
+        self.cleanup()
+
+    def __repr__(self):
+        return "%x" % id(self)
+
+    def cleanup(self, condition = None):
+        """Removes any temporary working directories for the specified
+        TestCmd environment.  If the environment variable PRESERVE was
+        set when the TestCmd environment was created, temporary working
+        directories are not removed.  If any of the environment variables
+        PRESERVE_PASS, PRESERVE_FAIL, or PRESERVE_NO_RESULT were set
+        when the TestCmd environment was created, then temporary working
+        directories are not removed if the test passed, failed, or had
+        no result, respectively.  Temporary working directories are also
+        preserved for conditions specified via the preserve method.
+
+        Typically, this method is not called directly, but is used when
+        the script exits to clean up temporary working directories as
+        appropriate for the exit status.
+        """
+        if not self._dirlist:
+            return
+        if condition is None:
+            condition = self.condition
+        if self._preserve[condition]:
+            for dir in self._dirlist:
+                print "Preserved directory", dir
+        else:
+            list = self._dirlist[:]
+            list.reverse()
+            for dir in list:
+                self.writable(dir, 1)
+                shutil.rmtree(dir, ignore_errors = 1)
+                
+        self._dirlist = []
+        self.workdir = None
+        os.chdir(self._cwd)            
+        try:
+            global _Cleanup
+            _Cleanup.remove(self)
+        except (AttributeError, ValueError):
+            pass
+
+    def description_set(self, description):
+        """Set the description of the functionality being tested.
+        """
+        self.description = description
+
+#    def diff(self):
+#        """Diff two arrays.
+#        """
+
+    def fail_test(self, condition = 1, function = None, skip = 0):
+        """Cause the test to fail.
+        """
+        if not condition:
+            return
+        self.condition = 'fail_test'
+        fail_test(self = self,
+                  condition = condition,
+                  function = function,
+                  skip = skip)
+
+    def interpreter_set(self, interpreter):
+        """Set the program to be used to interpret the program
+        under test as a script.
+        """
+        self.interpreter = interpreter
+
+    def match(self, lines, matches):
+        """Compare actual and expected file contents.
+        """
+        return self.match_func(lines, matches)
+
+    def match_exact(self, lines, matches):
+        """Compare actual and expected file contents.
+        """
+        return match_exact(lines, matches)
+
+    def match_re(self, lines, res):
+        """Compare actual and expected file contents.
+        """
+        return match_re(lines, res)
+
+    def no_result(self, condition = 1, function = None, skip = 0):
+        """Report that the test could not be run.
+        """
+        if not condition:
+            return
+        self.condition = 'no_result'
+        no_result(self = self,
+                  condition = condition,
+                  function = function,
+                  skip = skip)
+
+    def pass_test(self, condition = 1, function = None):
+        """Cause the test to pass.
+        """
+        if not condition:
+            return
+        self.condition = 'pass_test'
+        pass_test(self = self, condition = condition, function = function)
+
+    def preserve(self, *conditions):
+        """Arrange for the temporary working directories for the
+        specified TestCmd environment to be preserved for one or more
+        conditions.  If no conditions are specified, arranges for
+        the temporary working directories to be preserved for all
+        conditions.
+        """
+        if conditions is ():
+            conditions = ('pass_test', 'fail_test', 'no_result')
+        for cond in conditions:
+            self._preserve[cond] = 1
+
+    def program_set(self, program):
+        """Set the executable program or script to be tested.
+        """
+        if program and program[0] and not os.path.isabs(program[0]):
+            program[0] = os.path.join(self._cwd, program[0])
+        self.program = program
+
+    def read(self, file, mode = 'rb'):
+        """Reads and returns the contents of the specified file name.
+        The file name may be a list, in which case the elements are
+        concatenated with the os.path.join() method.  The file is
+        assumed to be under the temporary working directory unless it
+        is an absolute path name.  The I/O mode for the file may
+        be specified; it must begin with an 'r'.  The default is
+        'rb' (binary read).
+        """
+        if type(file) is ListType:
+            file = apply(os.path.join, tuple(file))
+        if not os.path.isabs(file):
+            file = os.path.join(self.workdir, file)
+        if mode[0] != 'r':
+            raise ValueError, "mode must begin with 'r'"
+        return open(file, mode).read()
+
+    def run(self, program = None,
+                  interpreter = None,
+                  arguments = None,
+                  chdir = None,
+                  stdin = None):
+        """Runs a test of the program or script for the test
+        environment.  Standard output and error output are saved for
+        future retrieval via the stdout() and stderr() methods.
+        """
+        if chdir:
+            oldcwd = os.getcwd()
+            if not os.path.isabs(chdir):
+                chdir = os.path.join(self.workpath(chdir))
+            if self.verbose:
+                sys.stderr.write("chdir(" + chdir + ")\n")
+            os.chdir(chdir)
+        cmd = []
+        if program and program[0]:
+            if not os.path.isabs(program[0]):
+                program[0] = os.path.join(self._cwd, program[0])
+            cmd += program
+        #    if interpreter:
+        #        cmd = interpreter + " " + cmd
+        else:
+            cmd += self.program
+        #    if self.interpreter:
+        #        cmd =  self.interpreter + " " + cmd
+        if arguments:
+            cmd += arguments.split(" ")
+        if self.verbose:
+            sys.stderr.write(join(cmd, " ") + "\n")
+        try:
+            p = popen2.Popen3(cmd, 1)
+        except AttributeError:
+            (tochild, fromchild, childerr) = os.popen3(join(cmd, " "))
+            if stdin:
+                if type(stdin) is ListType:
+                    for line in stdin:
+                        tochild.write(line)
+                else:
+                    tochild.write(stdin)
+            tochild.close()
+            self._stdout.append(fromchild.read())
+            self._stderr.append(childerr.read())                
+            fromchild.close()
+            self.status = childerr.close()
+            if not self.status:
+                self.status = 0
+        except:
+            raise
+        else:
+            if stdin:
+                if type(stdin) is ListType:
+                    for line in stdin:
+                        p.tochild.write(line)
+                else:
+                    p.tochild.write(stdin)
+            p.tochild.close()
+            self._stdout.append(p.fromchild.read())
+            self._stderr.append(p.childerr.read())
+            self.status = p.wait()
+            
+        if self.verbose:
+            sys.stdout.write(self._stdout[-1])
+            sys.stderr.write(self._stderr[-1])
+            
+        if chdir:
+            os.chdir(oldcwd)
+
+    def stderr(self, run = None):
+        """Returns the error output from the specified run number.
+        If there is no specified run number, then returns the error
+        output of the last run.  If the run number is less than zero,
+        then returns the error output from that many runs back from the
+        current run.
+        """
+        if not run:
+            run = len(self._stderr)
+        elif run < 0:
+            run = len(self._stderr) + run
+        run = run - 1
+        if (run < 0):
+            return ''
+        return self._stderr[run]
+
+    def stdout(self, run = None):
+        """Returns the standard output from the specified run number.
+        If there is no specified run number, then returns the standard
+        output of the last run.  If the run number is less than zero,
+        then returns the standard output from that many runs back from
+        the current run.
+        """
+        if not run:
+            run = len(self._stdout)
+        elif run < 0:
+            run = len(self._stdout) + run
+        run = run - 1
+        if (run < 0):
+            return ''
+        return self._stdout[run]
+
+    def subdir(self, *subdirs):
+        """Create new subdirectories under the temporary working
+        directory, one for each argument.  An argument may be a list,
+        in which case the list elements are concatenated using the
+        os.path.join() method.  Subdirectories multiple levels deep
+        must be created using a separate argument for each level:
+
+                test.subdir('sub', ['sub', 'dir'], ['sub', 'dir', 'ectory'])
+
+        Returns the number of subdirectories actually created.
+        """
+        count = 0
+        for sub in subdirs:
+            if sub is None:
+                continue
+            if type(sub) is ListType:
+                sub = apply(os.path.join, tuple(sub))
+            new = os.path.join(self.workdir, sub)
+            try:
+                os.mkdir(new)
+            except:
+                pass
+            else:
+                count = count + 1
+        return count
+
+    def unlink (self, file):
+        """Unlinks the specified file name.
+        The file name may be a list, in which case the elements are
+        concatenated with the os.path.join() method.  The file is
+        assumed to be under the temporary working directory unless it
+        is an absolute path name.
+        """
+        if type(file) is ListType:
+            file = apply(os.path.join, tuple(file))
+        if not os.path.isabs(file):
+            file = os.path.join(self.workdir, file)
+        os.unlink(file)
+
+
+    def verbose_set(self, verbose):
+        """Set the verbose level.
+        """
+        self.verbose = verbose
+
+    def workdir_set(self, path):
+        """Creates a temporary working directory with the specified
+        path name.  If the path is a null string (''), a unique
+        directory name is created.
+        """
+        if (path != None):
+            if path == '':
+                path = tempfile.mktemp()
+            if path != None:
+                os.mkdir(path)
+            self._dirlist.append(path)
+            global _Cleanup
+            try:
+                _Cleanup.index(self)
+            except ValueError:
+                _Cleanup.append(self)
+            # We'd like to set self.workdir like this:
+            #        self.workdir = path
+            # But symlinks in the path will report things
+            # differently from os.getcwd(), so chdir there
+            # and back to fetch the canonical path.
+            cwd = os.getcwd()
+            os.chdir(path)
+            self.workdir = os.getcwd()
+            os.chdir(cwd)
+        else:
+            self.workdir = None
+
+    def workpath(self, *args):
+        """Returns the absolute path name to a subdirectory or file
+        within the current temporary working directory.  Concatenates
+        the temporary working directory name with the specified
+        arguments using the os.path.join() method.
+        """
+        return apply(os.path.join, (self.workdir,) + tuple(args))
+
+    def writable(self, top, write):
+        """Make the specified directory tree writable (write == 1)
+        or not (write == None).
+        """
+
+        def _walk_chmod(arg, dirname, names):
+            st = os.stat(dirname)
+            os.chmod(dirname, arg(st[stat.ST_MODE]))
+            for name in names:
+                n = os.path.join(dirname, name)
+                st = os.stat(n)
+                os.chmod(n, arg(st[stat.ST_MODE]))
+
+        def _mode_writable(mode):
+            return stat.S_IMODE(mode|0200)
+
+        def _mode_non_writable(mode):
+            return stat.S_IMODE(mode&~0200)
+
+        if write:
+            f = _mode_writable
+        else:
+            f = _mode_non_writable
+        try:
+            os.path.walk(top, _walk_chmod, f)
+        except:
+            pass # ignore any problems changing modes
+
+    def write(self, file, content, mode = 'wb'):
+        """Writes the specified content text (second argument) to the
+        specified file name (first argument).  The file name may be
+        a list, in which case the elements are concatenated with the
+        os.path.join() method.        The file is created under the temporary
+        working directory.  Any subdirectories in the path must already
+        exist.  The I/O mode for the file may be specified; it must
+        begin with a 'w'.  The default is 'wb' (binary write).
+        """
+        if type(file) is ListType:
+            file = apply(os.path.join, tuple(file))
+        if not os.path.isabs(file):
+            file = os.path.join(self.workdir, file)
+        if mode[0] != 'w':
+            raise ValueError, "mode must begin with 'w'"
+        open(file, mode).write(content)

Added: boost-jam/boost-build/branches/upstream/current/test/absolute_sources.py
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/absolute_sources.py	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/absolute_sources.py	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,55 @@
+#!/usr/bin/python
+
+# Test that sources with absolute names are handled OK.
+
+from BoostBuild import Tester
+t = Tester()
+
+t.write("project-root.jam", """
+path-constant TOP : . ;
+""")
+t.write("Jamfile", """
+local pwd = [ PWD ] ;
+ECHO $(pwd) XXXXX ;
+exe hello : $(pwd)/hello.cpp $(TOP)/empty.cpp ;
+""")
+t.write("hello.cpp", "int main() { return 0; }\n")
+t.write("empty.cpp", "\n")
+
+t.run_build_system()
+t.expect_addition("bin/$toolset/debug/hello.exe")
+
+# Test a contrived case. There, absolute name is used in
+# standalone project (not Jamfile). Moreover, the target with
+# absolute name is returned by 'alias' and used from other project.
+t.write("a.cpp", """ 
+int main()
+{
+    return 0;
+}
+
+""")
+
+t.write("Jamfile", """ 
+exe a : /standalone//a ; 
+""")
+
+t.write("project-root.jam", """ 
+import standalone ; 
+""")
+
+t.write("standalone.jam", """ 
+import project ;
+
+project.initialize $(__name__) ;
+project standalone ;
+
+local pwd = [ PWD ] ;
+
+alias a : $(pwd)/a.cpp ;
+
+""")
+t.run_build_system()
+t.expect_addition("bin/$toolset/debug/a.exe")
+
+t.cleanup()


Property changes on: boost-jam/boost-build/branches/upstream/current/test/absolute_sources.py
___________________________________________________________________
Name: svn:executable
   + 

Added: boost-jam/boost-build/branches/upstream/current/test/alias.py
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/alias.py	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/alias.py	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,75 @@
+#!/usr/bin/python
+
+from BoostBuild import Tester, List
+t = Tester()
+
+# Test that top-level project can affect build dir
+t.write("project-root.jam", "")
+t.write("Jamfile", """
+
+exe a : a.cpp ;
+exe b : b.cpp ;
+exe c : c.cpp ;
+
+alias bin1 : a ;
+alias bin2 : a b ;
+
+alias src : s.cpp ;
+exe hello : hello.cpp src ;
+
+""")
+t.write("a.cpp", "int main() { return 0; }\n")
+t.copy("a.cpp", "b.cpp")
+t.copy("a.cpp", "c.cpp")
+t.copy("a.cpp", "hello.cpp")
+t.write("s.cpp", "")
+
+# Check that targets to which "bin1" refers are updated,
+# and only those.
+t.run_build_system("bin1")
+t.ignore("*.tds")
+t.expect_addition(List("bin/$toolset/debug/") * "a.exe a.obj")
+t.expect_nothing_more()
+
+# Try again with "bin2"
+t.run_build_system("bin2")
+t.ignore("*.tds")
+t.expect_addition(List("bin/$toolset/debug/") * "b.exe b.obj")
+t.expect_nothing_more()
+
+# Try building everything, making sure 'hello' target is
+# created
+t.run_build_system()
+t.ignore("*.tds")
+t.expect_addition("bin/$toolset/debug/hello.exe")
+
+# Regression test.
+# Check if usage requirements are propagated via "alias"
+           
+t.write("l.cpp", """ 
+void
+#if defined(_WIN32)
+__declspec(dllexport)
+#endif
+foo() {}
+
+""")
+
+t.write("Jamfile", """ 
+lib l : l.cpp : : : <define>WANT_MAIN ;
+alias la : l ;
+exe main : main.cpp la ; 
+""")
+
+t.write("main.cpp", """ 
+#ifdef WANT_MAIN
+int main() { return 0; }
+#endif
+
+""")
+
+t.write("project-root.jam", "")
+
+t.run_build_system()
+
+t.cleanup()


Property changes on: boost-jam/boost-build/branches/upstream/current/test/alias.py
___________________________________________________________________
Name: svn:executable
   + 

Added: boost-jam/boost-build/branches/upstream/current/test/alternatives.py
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/alternatives.py	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/alternatives.py	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,115 @@
+#!/usr/bin/python
+
+# Test main target alternatives.
+
+from BoostBuild import Tester
+from string import find
+t = Tester()
+
+
+# Test that basic alternatives selection works.
+t.write("project-root.jam", " ")
+t.write("Jamfile", """
+
+exe a : a_empty.cpp ;
+exe a : a.cpp : <variant>release ;
+""")
+t.write("a_empty.cpp", "")
+t.write("a.cpp", "int main() { return 0; }\n")
+
+t.run_build_system("release")
+t.expect_addition("bin/$toolset/release/a.exe")
+
+# Test that alternative selection works for ordinary
+# properties, in particular user-defined.
+t.write("project-root.jam", " ")
+t.write("Jamfile", """
+
+import feature ;
+feature.feature X : off on : propagated ;
+
+exe a : b.cpp ;
+exe a : a.cpp : <X>on ;
+""")
+t.write("b.cpp", "int main() { return 0; }\n")
+
+t.rm("bin")
+
+t.run_build_system()
+t.expect_addition("bin/$toolset/debug/b.obj")
+
+t.run_build_system("X=on")
+t.expect_addition("bin/$toolset/debug/X-on/a.obj")
+
+t.rm("bin")
+
+# Test that everything works ok even with default
+# build.
+
+t.write("Jamfile", """
+
+exe a : a_empty.cpp : <variant>release ;
+exe a : a.cpp : <variant>debug ;
+""")
+
+t.run_build_system()
+t.expect_addition("bin/$toolset/debug/a.exe")
+
+# Test that only properties which are in build request
+# matters when selection alternative. IOW, alternative
+# with <variant>release is better than one with
+# <variant>debug when building release version.
+t.write("Jamfile", """
+
+exe a : a_empty.cpp : <variant>debug ;
+exe a : a.cpp : <variant>release ;
+""")
+
+t.run_build_system("release")
+t.expect_addition("bin/$toolset/release/a.exe")
+
+# Test that free properties do not matter. We really don't
+# want <cxxflags> property in build request to affect
+# alternative selection.
+t.write("Jamfile", """
+exe a : a_empty.cpp : <variant>debug <define>FOO <include>BAR ;
+exe a : a.cpp : <variant>release ;
+""")
+
+t.rm("bin/$toolset/release/a.exe")
+t.run_build_system("release define=FOO")
+t.expect_addition("bin/$toolset/release/a.exe")
+
+# Test that abibuity is reported correctly
+t.write("Jamfile", """
+exe a : a_empty.cpp ;
+exe a : a.cpp ;
+""")
+t.run_build_system("--no-error-backtrace", status=1)
+t.fail_test(find(t.stdout(), "because no best-matching alternative could be found") == -1)
+
+# Another ambiguity test: two matches properties in one alternative are
+# neither better nor worse than a single one in another alternative.
+t.write("Jamfile", """
+exe a : a_empty.cpp : <optimization>off <profiling>off ;
+exe a : a.cpp : <debug-symbols>on ;
+""")
+
+t.run_build_system("--no-error-backtrace", status=1)
+t.fail_test(find(t.stdout(), "because no best-matching alternative could be found") == -1)
+
+
+
+# Test that we can have alternative without sources
+t.write("Jamfile", """
+alias specific-sources ;
+import feature ;
+feature.extend os : MAGIC ;
+alias specific-sources : b.cpp : <os>MAGIC ;
+exe a : a.cpp specific-sources ;
+""")
+t.rm("bin")
+t.run_build_system()
+
+           
+t.cleanup()        


Property changes on: boost-jam/boost-build/branches/upstream/current/test/alternatives.py
___________________________________________________________________
Name: svn:executable
   + 

Added: boost-jam/boost-build/branches/upstream/current/test/assert-equal.jam
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/assert-equal.jam	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/assert-equal.jam	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,29 @@
+# Evaluates [ rulename arg1... : arg2... : ... : argN... ] and compares the
+# result to expected-results. If there is a mismatch, prints an error message
+# and exits.
+rule assert-equal ( expected-results *
+    : rulename a1 * :  a2 * : a3 * : a4 * : a5 * : a6 * : a7 * : a8 * : a9 * )
+{
+
+    local results = [ $(rulename) $(a1) : $(a2) : $(a3)
+                        : $(a4) : $(a5) : $(a6) : $(a7) : $(a8) ] ;
+                      
+    if $(results) != $(expected-results)
+    {
+        EXIT ******ASSERTION FAILURE******* "
+    [ $(rulename) " $(a1)
+        ": "$(a2[1]) $(a2[2-])
+        ": "$(a3[1]) $(a3[2-])
+        ": "$(a4[1]) $(a4[2-])
+        ": "$(a5[1]) $(a5[2-])
+        ": "$(a6[1]) $(a6[2-])
+        ": "$(a7[1]) $(a7[2-])
+        ": "$(a8[1]) $(a8[2-]) "]
+expected:
+    (" $(expected-results) ")
+result was:
+    (" $(results) ")"
+       ;
+    
+    }
+}

Added: boost-jam/boost-build/branches/upstream/current/test/bad_dirname.py
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/bad_dirname.py	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/bad_dirname.py	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,25 @@
+#!/usr/bin/python
+
+#  Copyright (C) Vladimir Prus 2003. Permission to copy, use, modify, sell and
+#  distribute this software is granted provided this copyright notice appears in
+#  all copies. This software is provided "as is" without express or implied
+#  warranty, and with no claim as to its suitability for any purpose.
+
+
+#  Regression test: when directory of project root contained regex metacharacters,
+#  Boost.Build failed to work. Bug reported by Michael Stevens
+
+from BoostBuild import Tester, List
+
+t = Tester()
+
+t.write("bad[abc]dirname/Jamfile", """ 
+""")
+
+t.write("bad[abc]dirname/project-root.jam", """ 
+""")
+
+t.run_build_system(subdir="bad[abc]dirname")
+
+t.cleanup()
+


Property changes on: boost-jam/boost-build/branches/upstream/current/test/bad_dirname.py
___________________________________________________________________
Name: svn:executable
   + 

Added: boost-jam/boost-build/branches/upstream/current/test/boost-build.jam
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/boost-build.jam	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/boost-build.jam	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,10 @@
+
+# Assume BOOST_BUILD_PATH point to the 'test' directory.
+# We need to leave 'test' there, so that 'test-config.jam'
+# can be found, but also add parent directory, to find
+# all the other modules.
+
+BOOST_BUILD_PATH = $(BOOST_BUILD_PATH)/.. $(BOOST_BUILD_PATH) ;
+
+# Find the boost build system in the ../kernel directory.
+boost-build ../kernel ;

Added: boost-jam/boost-build/branches/upstream/current/test/build_dir.py
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/build_dir.py	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/build_dir.py	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,51 @@
+#!/usr/bin/python
+
+# Test that we can change build directory using 
+# the 'build-dir' project attribute.
+
+from BoostBuild import Tester
+t = Tester()
+
+
+# Test that top-level project can affect build dir
+t.write("project-root.jam", "import gcc ; ")
+t.write("Jamfile", """
+project
+    : build-dir build
+    ;
+    
+exe a : a.cpp ;
+build-project src ;    
+""")
+t.write("a.cpp", "int main() { return 0; }\n")
+
+t.write("src/Jamfile", "exe b : b.cpp ; ")
+t.write("src/b.cpp", "int main() { return 0; }\n")
+
+t.run_build_system()
+
+t.expect_addition(["build/$toolset/debug/a.exe",
+                   "build/src/$toolset/debug/b.exe"])
+           
+# Test that building from child projects work
+t.run_build_system(subdir='src')
+t.expect_nothing_more()        
+           
+# Test that project can override build dir
+t.write("Jamfile", """
+exe a : a.cpp ;
+build-project src ;
+""")           
+
+t.write("src/Jamfile", """
+project
+    : build-dir build 
+    ;
+exe b : b.cpp ;    
+""")
+
+t.run_build_system()
+t.expect_addition(["bin/$toolset/debug/a.exe",
+                   "src/build/$toolset/debug/b.exe"])
+           
+t.cleanup()        


Property changes on: boost-jam/boost-build/branches/upstream/current/test/build_dir.py
___________________________________________________________________
Name: svn:executable
   + 

Added: boost-jam/boost-build/branches/upstream/current/test/c_file.py
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/c_file.py	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/c_file.py	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,35 @@
+#!/usr/bin/python
+
+#  Copyright (C) Vladimir Prus 2003. Permission to copy, use, modify, sell and
+#  distribute this software is granted provided this copyright notice appears in
+#  all copies. This software is provided "as is" without express or implied
+#  warranty, and with no claim as to its suitability for any purpose.
+
+#  Test that C files are compiled by C compiler
+from BoostBuild import Tester, List
+
+t = Tester()
+
+t.write("project-root.jam", "")
+t.write("Jamfile", """
+project ;
+
+exe hello : hello.cpp a.c ;
+""")
+t.write("hello.cpp", """
+extern "C" int foo();
+int main() { return foo(); }
+""")
+t.write("a.c", """
+// This won't compile unless in C mode
+int foo()
+{
+    int new = 0;
+    new = (new+1)*7;
+    return new;
+}
+""")
+t.run_build_system()
+t.expect_addition("bin/$toolset/debug/hello.exe")
+
+t.cleanup()


Property changes on: boost-jam/boost-build/branches/upstream/current/test/c_file.py
___________________________________________________________________
Name: svn:executable
   + 

Added: boost-jam/boost-build/branches/upstream/current/test/chain.py
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/chain.py	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/chain.py	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,55 @@
+#!/usr/bin/python
+
+# This tests that 
+# 1) the 'make' correctly assigns types to produced targets
+# 2) than if 'make' create targets of type CPP, they are
+# correctly used (there was a bug with it).
+
+from BoostBuild import Tester
+t = Tester()
+
+# In order to correctly link this app, 'b.cpp', created by 'make'
+# rule, should be compiled.
+t.write("project-root.jam", "import gcc ;")
+t.write("Jamfile", r'''
+rule create ( dst : src * : properties * )
+{
+    # hack to echo a space under NT
+    setup on $(dst) = "set x=int main(){ return 0; }" ;
+}
+
+import modules ;
+if [ modules.peek : NT ]
+{
+    actions create 
+    {
+        $(setup)
+        echo %x% > $(<)
+    }
+}
+else
+{
+    actions create 
+    {
+        echo "int main(){ return 0; }" > $(<)
+    }
+}
+
+IMPORT $(__name__) : create : : create ;
+
+exe a : l dummy.cpp ;
+
+# needs to be static lib for Windows - main cannot appear in DLL
+static-lib l : a.cpp b.cpp ;
+
+make b.cpp : : create ;
+
+''')
+t.write("a.cpp", "")
+t.write("dummy.cpp", "// msvc needs at least one object file\n")
+
+t.run_build_system()
+
+t.expect_addition("bin/$toolset/debug/a.exe")
+
+t.cleanup()


Property changes on: boost-jam/boost-build/branches/upstream/current/test/chain.py
___________________________________________________________________
Name: svn:executable
   + 

Added: boost-jam/boost-build/branches/upstream/current/test/check-arguments.jam
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/check-arguments.jam	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/check-arguments.jam	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,73 @@
+# (C) Copyright David Abrahams 2001. Permission to copy, use,
+# modify, sell and distribute this software is granted provided this
+# copyright notice appears in all copies. This software is provided
+# "as is" without express or implied warranty, and with no claim as
+# to its suitability for any purpose.
+
+#
+# Jam code for testing the named-argument patch.
+#
+
+include recursive.jam ;
+
+# Prefixes for all of the jam code we're going to test
+local ECHO_ARGS = "include echo_args.jam ; echo_args "
+   ;
+
+local ECHO_VARARGS = "include echo_args.jam ; echo_varargs "
+   ;
+
+# Check that it will find missing arguments
+Jam-fail $(ECHO_ARGS)";"
+    : "missing argument a"
+    ;
+
+# Check that it will find if too many arguments are passed
+Jam-fail $(ECHO_ARGS)"1 2 : 3 : 4 : 5 ;"
+    : "extra argument 5"
+    ;
+
+# Check that it will find when an argument has too many elements
+Jam-fail $(ECHO_ARGS)"a b c1 c2 : d ;"
+    : "extra argument c2"
+    ;
+
+# Check modifier '?'
+Jam $(ECHO_ARGS)"1 2 3 : 4 ;"
+    : "a= 1 b= 2 c= 3 : d= 4 : e=" ;
+Jam $(ECHO_ARGS)"1 2 : 3 ;"
+    : "a= 1 b= 2 c= : d= 3 : e=" ;
+Jam $(ECHO_ARGS)"1 : 2 ;"
+    : "a= 1 b= c= : d= 2 : e=" ;
+
+# Check modifier '+'
+Jam-fail $(ECHO_ARGS)"1 ;"
+    : "missing argument d" ;
+Jam $(ECHO_ARGS)"1 : 2 3 ;"
+    : "a= 1 b= c= : d= 2 3 : e=" ;
+Jam $(ECHO_ARGS)"1 : 2 3 4 ;"
+    : "a= 1 b= c= : d= 2 3 4 : e=" ;
+
+# Check modifier '*'
+Jam $(ECHO_ARGS)"1 : 2 : 3 ;"
+    : "a= 1 b= c= : d= 2 : e= 3" ;
+Jam $(ECHO_ARGS)"1 : 2 : 3 4 ;"
+    : "a= 1 b= c= : d= 2 : e= 3 4" ;
+Jam $(ECHO_ARGS)"1 : 2 : 3 4 5 ;"
+    : "a= 1 b= c= : d= 2 : e= 3 4 5" ;
+
+#
+# Check varargs
+#
+Jam $(ECHO_VARARGS)"1 : 2 : 3 4 5 ;"
+    : "a= 1 b= c= : d= 2 : e= 3 4 5" ;
+Jam $(ECHO_VARARGS)"1 : 2 : 3 4 5 : 6 ;"
+    : "a= 1 b= c= : d= 2 : e= 3 4 5 : rest= 6" ;
+Jam $(ECHO_VARARGS)"1 : 2 : 3 4 5 : 6 7 ;"
+    : "a= 1 b= c= : d= 2 : e= 3 4 5 : rest= 6 7" ;
+Jam $(ECHO_VARARGS)"1 : 2 : 3 4 5 : 6 7 : 8 ;"
+    : "a= 1 b= c= : d= 2 : e= 3 4 5 : rest= 6 7 : 8" ;
+Jam $(ECHO_VARARGS)"1 : 2 : 3 4 5 : 6 7 : 8 : 9 ;"
+    : "a= 1 b= c= : d= 2 : e= 3 4 5 : rest= 6 7 : 8 : 9" ;
+
+

Added: boost-jam/boost-build/branches/upstream/current/test/check-bindrule.jam
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/check-bindrule.jam	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/check-bindrule.jam	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,25 @@
+# This rule establishes a dependency, with no special build actions
+rule do-nothing ( target : source )
+{
+    DEPENDS $(target) : $(source) ;
+}
+actions quietly do-nothing
+{
+}
+
+# Make a non-file target which depends on a file that exists
+NOTFILE fake-target ;
+SEARCH on file-to-bind = subdir1 ;
+
+do-nothing fake-target
+    : file-to-bind ;
+
+# Set jam up to call our bind-rule
+BINDRULE = bind-rule ;
+
+rule bind-rule ( target : path )
+{
+    ECHO found: $(target) at $(path) ;
+}
+
+DEPENDS all : fake-target ;
\ No newline at end of file

Added: boost-jam/boost-build/branches/upstream/current/test/check-jam-patches.jam
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/check-jam-patches.jam	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/check-jam-patches.jam	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,289 @@
+# Get the recursive Jam invocation code
+include recursive.jam ;
+include assert-equal.jam ;
+
+Jam "include check-bindrule.jam ;"
+    : "found: file-to-bind at subdir1$(SLASH)file-to-bind"
+    ;
+
+include check-arguments.jam ;
+
+if $(NT)
+{
+    # if this one fails, you don't have the line length patch
+    Jam "include test_nt_line_length.jam ;" ;
+}
+
+# a little utility for assertions
+rule identity ( list * )
+{
+    return $(list) ;
+}
+
+#
+# test rule indirection
+#
+rule select ( n list * )
+{
+    return $(list[$(n)]) ;
+}
+
+rule indirect1 ( rule + : args * )
+{
+    return [ $(rule) $(args) ] ;
+}
+
+assert-equal a : indirect1 select 1 : a b c d e ;
+assert-equal b : indirect1 select 2 : a b c d e ;
+
+x = reset ;
+rule reset-x ( new-value )
+{
+    x = $(new-value) ; 
+}
+$(x)-x bar ;                       # invokes reset-x...
+assert-equal bar : identity $(x) ; # which changes x
+
+# Check that unmatched subst returns an empty list
+assert-equal # nothing
+    : SUBST "abc" "d+" x ;
+
+# Check that a matched subst works
+assert-equal x
+    : SUBST "ddd" "d+" x ;
+    
+# Check that we can get multiple substitutions from a single invocation
+assert-equal x y x-y
+    : SUBST "x/y/z" "([^/]*)/([^/]*).*" "\\1" $2 "\\1-\\2" ;
+
+#
+# test local foreach modification
+#
+{
+    local x = 0 ;
+    local entered = ;
+    for local x in a b c # x declared local to for loop.
+    {
+        entered = 1 ;
+        if ! ( $(x) in a b c )
+        {
+            EXIT "local foreach: expected one of a, b, c; got" $(x) ;
+        }
+    }
+    
+    if $(x) != 0 # if x was modified, it failed to be a local variable
+    {
+        EXIT "local foreach failed" ;
+    }
+}
+
+#
+# test while loops
+#
+{
+    local x = a b c ;
+    local y = $(x) ;
+    local z = ;
+    
+    while $(y)
+    {
+        z += $(y[1]) ;
+        y = $(y[2-]) ;
+    }
+    
+    if $(z) != $(x)
+    {
+        EXIT "while loops failed" ;
+    }
+}
+
+#
+# test negative list indices and slices
+#
+{
+    local x = a b c d e ;
+    
+    rule assert-index ( index : list * )
+    {
+        if $(x[$(index)]) != $(list)
+        {
+            ECHO with x= $(x) ;
+            ECHO x[$(index)] == $(x[$(index)]) ;
+            EXIT expected $(list) ;
+        }
+    }
+    
+    assert-index 1 : a ;
+    assert-index 3 : c ;
+    assert-index 1-2 : a b ;
+    assert-index -1 : e ;
+    assert-index -2 : d ;
+    assert-index 2--2 : b c d ;
+    assert-index -3--2 : c d ;
+    assert-index 1--2 : a b c d ;
+    assert-index 1--2 : a b c d ;
+    assert-index 1--10 : ;
+    x = a ;
+    assert-index 1--2 : ;
+    assert-index 1--2 : ;
+}
+
+#
+# test module primitives
+#
+{
+    local x = a b c d e f g h i j ;
+    local y = $(x[3-]) ;
+
+    rule shift1 ( dummy ) { }
+
+    rule my_module.not_really ( ) { return something ; }
+
+    # import the identity rule into my_module as "id"
+    IMPORT  : identity : my_module : id ;
+    module my_module
+    {
+        # assert-equal operates in its own module, so call id in here and use
+        # identity later.
+        local f = [ id x y z ] ;
+        assert-equal x y z : identity $(f) ;
+        
+        w = ;
+        y = ;
+        x2 = 1 2 3 ;
+        x3 = $(x2) ;
+        z = $(x2) ;
+        
+        x3 = ; # should reset x3
+        
+        # drops one element from the head of x
+        # moves the first element of z from the head of z to the head of y
+        rule shift1 ( )
+        {
+            x = $(x[2-]) ;
+            y = $(z[1]) $(y) ;
+            z = $(z[2-]) ;
+        }
+
+        rule shift2 ( )
+        {
+            shift1 ;
+        }
+        
+        shift1 ;
+        shift2 ;
+
+        rule get ( symbol )
+        {
+            return $($(symbol)) ;
+        }
+        local rule not_really ( ) { return nothing ; }
+    }
+    
+    local expected = shift1 shift2 get ;
+    if ! ( $(expected) in [ RULENAMES my_module ] )
+      || ! ( [ RULENAMES my_module ] in $(expected) )
+    {
+        EXIT "[ RULENAMES my_module ] =" [ RULENAMES my_module ] "!=" shift1 shift2 get ;
+    }        
+    
+          
+    # show that not_really was actually a local definition
+    assert-equal something : my_module.not_really ;
+
+    if not_really in [ RULENAMES my_module ]
+    {
+        EXIT unexpectedly found local rule "not_really" in "my_module" ;
+    }
+    EXPORT my_module : not_really ;
+    
+    if ! ( not_really in [ RULENAMES my_module ] )
+    {
+        EXIT unexpectedly failed to find exported rule "not_really" in "my_module" ;
+    }
+    
+    # show that my_module doesn't have access to our variables
+    my_module.shift1 ;
+    assert-equal $(x[3-]) : identity $(y) ;
+
+    # check module locals
+    assert-equal : my_module.get w ;
+    assert-equal 3 2 1 : my_module.get y ;
+    assert-equal 1 2 3 : my_module.get x2 ;
+    assert-equal : my_module.get x3 ;
+    assert-equal : my_module.get z ;
+    
+    my_module.shift2 ;
+    x = $(x[3-]) ;
+    assert-equal $(x) : identity $(y) ;
+
+    # Prove that the module's rule is not exposed to the world at large without
+    # qualification
+    shift1 nothing ;
+    assert-equal $(x) : identity $(y) ;
+
+    # import my_module.shift1 into the global module as "shifty", and
+    # my_module.shift2 into the global module as "shift2".
+    IMPORT my_module : shift1 shift2 : : shifty shift2 ;
+
+    shifty ;
+    assert-equal $(x) : identity $(y) ;
+
+    shift2 ;
+    assert-equal $(x) : identity $(y) ;
+
+    # Now do the same with localization
+    IMPORT my_module : shift1 : : shifty : LOCALIZE ;
+
+    shifty ;
+    y = $(y[3-]) ;
+    assert-equal $(x) : identity $(y) ;
+
+    # import everything from my_module into the global module using
+    # the same names.
+    IMPORT my_module : [ RULENAMES my_module ] : : [ RULENAMES my_module ] : LOCALIZE ;
+
+    shift1 ;
+    y = $(y[2-]) ;
+    assert-equal $(x) : identity $(y) ;
+
+    shift2 ;
+    y = $(y[2-]) ;
+    assert-equal $(x) : identity $(y) ;
+}
+
+#
+# test CALLER_MODULE and backtrace
+#
+{
+    rule backtrace ( )
+    {
+        local bt = [ BACKTRACE ] ;
+        bt = $(bt[5-]) ;
+        while $(bt)
+        {
+            ECHO $(bt[1]):$(bt[2]): "in" $(bt[4]) ;
+            bt = $(bt[5-]) ;
+        }
+    }
+    module module1
+    {
+        rule f ( )
+        {
+            local m = [ CALLER_MODULE ] ;
+            assert-equal : identity $(m) ;
+            module2.f ;
+        }
+
+    }
+    module module2
+    {
+        rule f ( )
+        {
+            local m = [ CALLER_MODULE ] ;
+            assert-equal module1 : identity $(m) ;
+            backtrace ;
+        }
+    }
+    module1.f ;
+}
\ No newline at end of file

Added: boost-jam/boost-build/branches/upstream/current/test/check-test-tools.jam
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/check-test-tools.jam	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/check-test-tools.jam	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,22 @@
+include recursive.jam ;
+include assert-equal.jam ;
+
+#####################################
+# Test the testing tools right here #
+#####################################
+
+# This command always exits with a failure.
+Jam-fail "EXIT error ;" ;
+
+# This should fail to fail
+Jam-fail
+     "include recursive.jam ; Jam-fail \"# this innocuous Jamfile should fail to fail\" ;"
+      ;
+
+# the ECHO rule always has an empty result.
+Jam-fail "include assert-equal.jam ; assert-equal fubar : ECHO checking that assertions fail ;"
+    : "ASSERTION FAILURE"
+    ;
+
+local NOTHING = ;
+assert-equal $(NOTHING) : ECHO checking that assertions succeed ;

Added: boost-jam/boost-build/branches/upstream/current/test/composite.py
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/composite.py	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/composite.py	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,30 @@
+#!/usr/bin/python
+
+#  Copyright (C) Vladimir Prus 2003. Permission to copy, use, modify, sell and
+#  distribute this software is granted provided this copyright notice appears in
+#  all copies. This software is provided "as is" without express or implied
+#  warranty, and with no claim as to its suitability for any purpose.
+
+#  Test that composite properties are handled correctly.
+from BoostBuild import Tester, List
+
+t = Tester()
+
+t.write("project-root.jam", "")
+t.write("Jamfile", """
+exe hello : hello.cpp : <variant>release ;
+""")
+t.write("hello.cpp", """
+int main()
+{
+    return 0;
+}
+
+""")
+
+t.run_build_system()
+
+t.expect_addition("bin/$toolset/release/hello.exe")
+
+
+t.cleanup()


Property changes on: boost-jam/boost-build/branches/upstream/current/test/composite.py
___________________________________________________________________
Name: svn:executable
   + 

Added: boost-jam/boost-build/branches/upstream/current/test/conditionals.py
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/conditionals.py	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/conditionals.py	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,50 @@
+#!/usr/bin/python
+
+# Test conditional properties
+
+from BoostBuild import Tester, List
+import os
+from string import strip
+
+t = Tester()
+
+# Arrange a project which will build only if
+# 'a.cpp' is compiled with "STATIC" define.
+t.write("project-root.jam", "import gcc ;")
+t.write("a.cpp", """
+#ifdef STATIC
+int main() {  return 0; }
+#endif
+""")
+t.write("Jamfile", "exe a : a.cpp : <link>static:<define>STATIC ;")
+t.run_build_system("link=static")
+t.expect_addition("bin/$toolset/debug/link-static/a.exe")
+
+t.write("Jamfile", """
+project : requirements <link>static:<define>STATIC ;
+exe a : a.cpp ;
+""")
+t.rm("bin")
+t.run_build_system("link=static")
+t.expect_addition("bin/$toolset/debug/link-static/a.exe")
+
+# Regression test for a bug found by Ali Azarbayejani.
+# Conditionals inside usage requirement were not evaluated.
+# This breaks 
+
+t.write("Jamfile", """
+lib l : l.cpp : : : <link>static:<define>STATIC ;
+exe a : a.cpp l ;
+""")
+t.write("l.cpp", "")
+t.write("l.cpp", """
+int i;
+""")
+
+t.rm("bin")
+t.run_build_system("link=static")
+t.expect_addition("bin/$toolset/debug/link-static/a.exe")
+
+
+
+t.cleanup()


Property changes on: boost-jam/boost-build/branches/upstream/current/test/conditionals.py
___________________________________________________________________
Name: svn:executable
   + 

Added: boost-jam/boost-build/branches/upstream/current/test/conditionals2.py
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/conditionals2.py	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/conditionals2.py	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,49 @@
+#!/usr/bin/python
+
+#  Copyright (C) Vladimir Prus 2003. Permission to copy, use, modify, sell and
+#  distribute this software is granted provided this copyright notice appears in
+#  all copies. This software is provided "as is" without express or implied
+#  warranty, and with no claim as to its suitability for any purpose.
+
+#  Regression test: it was possible that due to evaluation of conditional
+#  requirements, two different values of non-free features were present in
+#  property set.
+
+from BoostBuild import Tester, List
+
+t = Tester()
+
+t.write("project-root.jam", "")
+
+t.write("a.cpp", "")
+
+t.write("Jamfile", """ 
+import feature : feature ;
+import common : file-creation-command ;
+
+feature the_feature : false true : propagated ;
+
+rule maker ( targets * : sources * : properties * )
+{
+    if <the_feature>false in $(properties)
+    && <the_feature>true in $(properties)
+    {
+        EXIT "Oops, two different values of non-free feature" ;
+    }    
+    CMD on $(targets) = [ file-creation-command ] ;
+}
+
+actions maker
+{
+    $(CMD) $(<) ;
+}
+
+make a : a.cpp :  maker : <variant>debug:<the_feature>true ; 
+""")
+
+t.run_build_system()
+
+t.cleanup()
+
+
+


Property changes on: boost-jam/boost-build/branches/upstream/current/test/conditionals2.py
___________________________________________________________________
Name: svn:executable
   + 

Added: boost-jam/boost-build/branches/upstream/current/test/conditionals3.py
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/conditionals3.py	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/conditionals3.py	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,34 @@
+#!/usr/bin/python
+
+#  Copyright (C) Vladimir Prus 2003. Permission to copy, use, modify, sell and
+#  distribute this software is granted provided this copyright notice appears in
+#  all copies. This software is provided "as is" without express or implied
+#  warranty, and with no claim as to its suitability for any purpose.
+
+#  Test that conditional properties work, even if property is free, and
+#  value includes colon.
+from BoostBuild import Tester, List
+
+
+t = Tester()
+
+# Create the needed files
+t.write("project-root.jam", "")
+t.write("Jamfile", """
+exe hello : hello.cpp : <variant>debug:<define>CLASS=Foo::Bar ;
+""")
+t.write("hello.cpp", """
+namespace Foo { class Bar { } ; }
+int main()
+{
+    CLASS c;
+    return 0;
+}
+
+""")
+
+# Don't check stderr, which can include warning about unused 'c'.
+t.run_build_system(stdout=None, stderr=None)
+t.expect_addition("bin/$toolset/debug/hello.exe")
+
+t.cleanup()


Property changes on: boost-jam/boost-build/branches/upstream/current/test/conditionals3.py
___________________________________________________________________
Name: svn:executable
   + 

Added: boost-jam/boost-build/branches/upstream/current/test/core_d12.py
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/core_d12.py	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/core_d12.py	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,36 @@
+#!/usr/bin/python
+
+# This tests correct handling of "-d1" and "-d2" options.
+
+import BoostBuild
+
+t = BoostBuild.Tester(pass_toolset=0)
+
+t.write("file.jam", """
+actions a {    
+}
+
+actions quietly b {
+}
+
+ALWAYS all ;
+
+a all ;
+b all ;
+""")
+
+t.run_build_system("-ffile.jam -d0", stdout="")
+
+t.run_build_system("-ffile.jam -d1", stdout=
+"""...found 1 target...
+...updating 1 target...
+a all
+...updated 1 target...
+""")
+
+t.run_build_system("-ffile.jam -d2")
+
+t.fail_test(t.stdout().find("a all") == -1)
+t.fail_test(t.stdout().find("b all") == -1)
+
+t.cleanup()


Property changes on: boost-jam/boost-build/branches/upstream/current/test/core_d12.py
___________________________________________________________________
Name: svn:executable
   + 

Added: boost-jam/boost-build/branches/upstream/current/test/core_delete_module.py
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/core_delete_module.py	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/core_delete_module.py	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,47 @@
+#!/usr/bin/python
+
+# This tests the facilities for deleting modules.
+
+import BoostBuild
+
+t = BoostBuild.Tester(pass_toolset=0)
+
+t.write("file.jam", """
+module foo
+{
+    rule bar { }
+    var = x y ;
+}
+DELETE_MODULE foo ;
+if [ RULENAMES foo ]
+{
+     EXIT DELETE_MODULE failed to kill foo's rules: [ RULENAMES foo ] ;
+}
+
+module foo
+{
+     if $(var)
+     {
+         EXIT DELETE_MODULE failed to kill foo's variables ;
+     }
+     
+     rule bar { }
+     var = x y ;
+     
+     DELETE_MODULE foo ;
+     
+     if $(var)
+     {
+         EXIT internal DELETE_MODULE failed to kill foo's variables ;
+     }
+     if [ RULENAMES foo ]
+     {
+         EXIT internal DELETE_MODULE failed to kill foo's rules: [ RULENAMES foo ] ;
+     }
+}
+DEPENDS all : xx ;
+NOTFILE xx ;
+""")
+
+t.run_build_system("-ffile.jam", status=0)
+t.cleanup()


Property changes on: boost-jam/boost-build/branches/upstream/current/test/core_delete_module.py
___________________________________________________________________
Name: svn:executable
   + 

Added: boost-jam/boost-build/branches/upstream/current/test/core_dependencies.py
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/core_dependencies.py	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/core_dependencies.py	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,152 @@
+#!/usr/bin/python
+
+# This tests correct handling of dependencies, specifically, on
+# generated sources, and from generated sources.
+
+import BoostBuild
+from string import find
+
+t = BoostBuild.Tester(pass_toolset=0)
+
+t.write("core-dependency-helpers", """
+rule hdrrule
+{
+   INCLUDES $(1) : $(2) ;
+}
+actions copy
+{
+   cp $(>) $(<)
+}
+""")
+
+code = """include core-dependency-helpers ;
+DEPENDS all : a ;
+DEPENDS a : b ;
+
+actions create-b
+{
+   echo '#include <foo.h>' > $(<) 
+}
+copy a : b ;
+create-b b ;
+HDRRULE on b foo.h bar.h = hdrrule ;
+HDRSCAN on b foo.h bar.h = \"#include <(.*)>\" ;
+"""
+
+# This creates 'a' which depends on 'b', which is generated.
+# The generated 'b' contains '#include <foo.h>' and no rules for
+# foo.h are given. The system should error out on the first invocation.
+t.run_build_system("-f-", stdin=code)
+t.fail_test(find(t.stdout(), "...skipped a for lack of foo.h...") == -1)
+
+t.rm('b')
+# Now test that if target 'c' also depends on 'b', then it won't be built, as well.
+t.run_build_system("-f-", stdin=code + " copy c : b ; DEPENDS c : b ; DEPENDS all : c ; ")
+t.fail_test(find(t.stdout(), "...skipped c for lack of foo.h...") == -1)
+
+
+# Now add a rule for creating foo.h
+t.rm('b')
+code += """
+actions create-foo
+{
+    echo // > $(<)
+}
+create-foo foo.h ;
+"""
+t.run_build_system("-f-", stdin=code)
+
+# Run two times, adding explicit dependency from all to foo.h at
+# the beginning and at the end, to make sure that foo.h is generated before
+# 'a' in all cases.
+
+def mk_right_order_func(s1, s2):
+    def right_order(s):
+        n1 = find(s, s1)
+        n2 = find(s, s2)
+        return n1 != -1 and n2 != -1 and n1 < n2
+    return right_order
+
+right_order = mk_right_order_func("create-foo", "copy a")
+
+t.rm(["a", "b", "foo.h"])
+t.run_build_system("-d+2 -f-", stdin=code + " DEPENDS all : foo.h ;")
+t.fail_test(not right_order(t.stdout()))
+
+t.rm(["a", "b", "foo.h"])
+t.run_build_system("-d+2 -f-", stdin=" DEPENDS all : foo.h ; " + code)
+t.fail_test(not right_order(t.stdout()))
+
+# Now foo.h exists. Test include from b -> foo.h -> bar.h -> biz.h
+# b and foo.h already have updating actions. 
+t.rm(["a", "b"])
+t.write("foo.h", "#include <bar.h>")
+t.write("bar.h", "#include <biz.h>")
+t.run_build_system("-d+2 -f-", stdin=code)
+t.fail_test(find(t.stdout(), "...skipped a for lack of biz.h...") == -1)
+
+# Add an action for biz.h
+code += """
+actions create-biz
+{
+   echo // > $(<)
+}
+create-biz biz.h ;
+"""
+t.rm(["b"])
+right_order = mk_right_order_func("create-biz", "copy a")
+t.run_build_system("-d+2 -f-", stdin=code + " DEPENDS all : biz.h ;")
+t.fail_test(not right_order(t.stdout()))
+
+t.rm(["a", "biz.h"])
+t.run_build_system("-d+2 -f-", stdin=" DEPENDS all : biz.h ; " + code)
+t.fail_test(not right_order(t.stdout()))           
+
+
+t.write("a", "")
+
+code="""
+DEPENDS all : main d ;
+
+actions copy 
+{
+    cp $(>) $(<) ;
+}
+
+DEPENDS main : a ;
+copy main : a ;
+
+INCLUDES a : <1>c ;
+
+NOCARE <1>c ;
+SEARCH on <1>c = . ;
+
+actions create-c 
+{
+    echo d > $(<)    
+}
+
+actions create-d
+{
+    echo // > $(<)
+}
+
+create-c <2>c ;
+LOCATE on <2>c = . ;
+create-d d ;
+
+HDRSCAN on <1>c = (.*) ;
+HDRRULE on <1>c = hdrrule ;
+
+rule hdrrule 
+{
+    INCLUDES $(1) : d ;
+}
+"""
+right_order = mk_right_order_func("create-d", "copy main")
+t.run_build_system("-d2 -f-", stdin=code)
+t.fail_test(not right_order(t.stdout()))
+
+
+
+t.cleanup()


Property changes on: boost-jam/boost-build/branches/upstream/current/test/core_dependencies.py
___________________________________________________________________
Name: svn:executable
   + 

Added: boost-jam/boost-build/branches/upstream/current/test/core_import_module.py
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/core_import_module.py	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/core_import_module.py	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,65 @@
+#!/usr/bin/python
+
+#  Copyright (C) Vladimir Prus 2003. Permission to copy, use, modify, sell and
+#  distribute this software is granted provided this copyright notice appears in
+#  all copies. This software is provided "as is" without express or implied
+#  warranty, and with no claim as to its suitability for any purpose.
+
+from BoostBuild import Tester, List
+
+
+t = Tester(pass_toolset=0)
+
+# Test that 
+
+t.write("code", """
+module a {
+    rule r1 ( )
+    {
+        ECHO R1 ;
+    }
+}
+module a2 {
+    rule r2 ( )
+    {
+        ECHO R2 ;
+    }
+}
+IMPORT a2 : r2 : : a2.r2 ;
+
+module b {
+    IMPORT_MODULE a : b ;
+
+    rule test
+    {
+        # Call rule visible via IMPORT_MODULE
+        a.r1 ;
+        # Call rule in global scope
+        a2.r2 ;
+    }
+}
+
+IMPORT b : test : : test ;
+test ;
+
+module c {
+    rule test
+    {
+        ECHO CTEST ;
+    }
+}    
+
+IMPORT_MODULE c : ;
+c.test ;
+
+actions do-nothing { }
+do-nothing all ;
+
+""")
+
+t.run_build_system("-fcode", stdout="""R1
+R2
+CTEST
+""")
+
+t.cleanup()


Property changes on: boost-jam/boost-build/branches/upstream/current/test/core_import_module.py
___________________________________________________________________
Name: svn:executable
   + 

Added: boost-jam/boost-build/branches/upstream/current/test/core_modifiers.py
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/core_modifiers.py	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/core_modifiers.py	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,56 @@
+#!/usr/bin/python
+
+# This tests the "existing" and "updated" modifiers on actions.
+
+import BoostBuild
+from string import strip, replace
+
+t = BoostBuild.Tester(pass_toolset=0)
+
+code = """
+
+DEPENDS all : a ;
+ALWAYS a ;
+NOTFILE a ;
+
+actions existing make-a
+{
+    echo $(>) > list
+}
+make-a a : a-1 a-2 a-3 ;
+DEPENDS a : a-1 a-2 a-3 ;
+NOCARE a-1 a-2 ;
+
+actions make-a3
+{
+   echo foo > $(<)
+}
+make-a3 a-3 ;
+"""
+
+t.write("file.jam", code)
+t.write("a-1", "")
+
+t.run_build_system("-ffile.jam")
+t.fail_test(strip(t.read("list")) != "a-1")
+t.rm(["a-3", "list"])
+
+code = replace(code, "existing", "updated")
+t.write("file.jam", code)
+t.run_build_system("-ffile.jam")
+t.fail_test(strip(t.read("list")) != "a-3")
+
+code = replace(code, "updated", "existing updated")
+t.write("file.jam", code)
+t.run_build_system("-ffile.jam")
+t.fail_test(strip(t.read("list")) != "a-1 a-3")
+
+
+
+
+
+
+
+
+
+t.cleanup()


Property changes on: boost-jam/boost-build/branches/upstream/current/test/core_modifiers.py
___________________________________________________________________
Name: svn:executable
   + 

Added: boost-jam/boost-build/branches/upstream/current/test/core_typecheck.py
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/core_typecheck.py	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/core_typecheck.py	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,43 @@
+#!/usr/bin/python
+
+# This tests the typechecking facilities.
+
+import BoostBuild
+
+t = BoostBuild.Tester(pass_toolset=0)
+
+t.write("file.jam", """
+module .typecheck 
+{
+    rule [path] ( x )
+    {
+        if ! [ MATCH "^(::)" : $(x) ] 
+        {
+            ECHO "Error: $(x) is not a path" ;
+            return true ;
+        }
+    }
+}
+
+rule do ( [path] a )
+{
+}
+
+do $(ARGUMENT) ;
+
+actions dummy { } 
+dummy all ;
+""")
+
+t.run_build_system("-ffile.jam -sARGUMENT=::a/b/c")
+t.run_build_system("-ffile.jam -sARGUMENT=a/b/c", status=1,
+                   stdout="""Error: a/b/c is not a path
+file.jam:18: in module scope
+*** argument error
+* rule do ( [path] a )
+* called with: ( a/b/c )
+* true a
+file.jam:16:see definition of rule 'do' being called
+""")
+
+t.cleanup()


Property changes on: boost-jam/boost-build/branches/upstream/current/test/core_typecheck.py
___________________________________________________________________
Name: svn:executable
   + 

Added: boost-jam/boost-build/branches/upstream/current/test/core_varnames.py
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/core_varnames.py	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/core_varnames.py	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,33 @@
+#!/usr/bin/python
+
+# This tests the core rule for enumerating the variable names in a module
+
+import BoostBuild
+
+t = BoostBuild.Tester(pass_toolset=0)
+
+t.write("file.jam", """
+module foo
+{
+    rule bar { }
+    var1 = x y ;
+    var2 = fubar ;
+}
+
+expected = var1 var2 ;
+names = [ VARNAMES foo ] ;
+if $(names) in $(expected) && $(expected) in $(names)
+{
+    # everything OK
+}
+else
+{
+    EXIT expected to find variables $(expected:J=", ") in module foo,
+    but found $(names:J=", ") instead. ;
+}
+DEPENDS all : xx ;
+NOTFILE xx ;
+""")
+
+t.run_build_system("-ffile.jam", status=0)
+t.cleanup()


Property changes on: boost-jam/boost-build/branches/upstream/current/test/core_varnames.py
___________________________________________________________________
Name: svn:executable
   + 

Added: boost-jam/boost-build/branches/upstream/current/test/custom_generator.py
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/custom_generator.py	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/custom_generator.py	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,56 @@
+#!/usr/bin/python
+
+#  Copyright (C) Vladimir Prus 2003. Permission to copy, use, modify, sell and
+#  distribute this software is granted provided this copyright notice appears in
+#  all copies. This software is provided "as is" without express or implied
+#  warranty, and with no claim as to its suitability for any purpose.
+
+
+from BoostBuild import Tester, List
+
+
+t = Tester()
+
+# Attempt to declare a generator for creating OBJ from RC files.
+# That generator should be considered together with standard
+# CPP->OBJ generators and successfully create the target.
+# Since we don't have RC compiler everywhere, we fake the action.
+# The resulting OBJ will be unusable, but it must be created.
+
+t.write("project-root.jam", """ 
+import rcc ; 
+""")
+
+t.write("rcc.jam", """ 
+import type ;
+import generators ;
+import print ;
+
+# Use 'RCC' to avoid conflicts with definitions in
+# the standard rc.jam and msvc.jam
+type.register RCC : rcc ;
+
+rule resource-compile ( targets * : sources * : properties * )
+{
+    print.output $(targets[1]) ;
+    print.text "rc-object" ;
+}
+
+generators.register-standard rcc.resource-compile : RCC : OBJ ;
+
+""")
+
+t.write("Jamfile", """ 
+obj r : r.rcc ; 
+""")
+
+t.write("r.rcc", """ 
+""")
+
+t.run_build_system()
+t.expect_content("bin/$toolset/debug/r.obj", "rc-object\n")
+
+t.cleanup()
+
+
+


Property changes on: boost-jam/boost-build/branches/upstream/current/test/custom_generator.py
___________________________________________________________________
Name: svn:executable
   + 

Added: boost-jam/boost-build/branches/upstream/current/test/default_build.py
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/default_build.py	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/default_build.py	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,87 @@
+#!/usr/bin/python
+
+# Test that default build clause actually has any effect.
+
+from BoostBuild import Tester, List
+t = Tester()
+
+t.write("project-root.jam", "import gcc ;")
+t.write("Jamfile", "exe a : a.cpp : : debug release ;")
+t.write("a.cpp", "int main() { return 0; }\n")
+
+t.run_build_system()
+t.expect_addition("bin/$toolset/debug/a.exe")
+t.expect_addition("bin/$toolset/release/a.exe")
+
+# Check that explictly-specified build variant supresses
+# default-build
+t.rm("bin")
+t.run_build_system("release")
+t.expect_addition(List("bin/$toolset/release/") * "a.exe a.obj")
+t.expect_nothing_more()
+
+# Now check that we can specify explicit build request and
+# default-build will be combined with it
+t.run_build_system("optimization=space")
+t.expect_addition("bin/$toolset/debug/optimization-space/a.exe")
+t.expect_addition("bin/$toolset/release/optimization-space/a.exe")
+
+# Test that default-build must be identical in all alternatives. Error case.
+t.write("Jamfile", """
+exe a : a.cpp : : debug ;
+exe a : b.cpp : : ;
+""")
+expected="""error: default build must be identical in all alternatives
+main target is ./a
+with
+differing from previous default build <variant>debug
+
+"""
+t.run_build_system("-n --no-error-backtrace", status=1, stdout=expected)
+
+# Test that default-build must be identical in all alternatives. No Error case, empty default build.
+t.write("Jamfile", """
+exe a : a.cpp : <variant>debug ;
+exe a : b.cpp : <variant>release ;
+""")
+t.run_build_system("-n --no-error-backtrace", status=0)
+
+
+# Now try a harder example: default build which contains <define>
+# should cause <define> to be present when "b" is compiled.
+# This happens only of "build-project b" is placed first.
+t.write("Jamfile", """
+    project 
+        : default-build <define>FOO 
+    ;
+
+    build-project a ;
+    build-project b ;   
+""")
+
+t.write("a/Jamfile", """
+    exe a : a.cpp ../b//b ;
+""")
+t.write("a/a.cpp", """
+#ifdef _WIN32
+__declspec(dllimport)
+#endif
+void foo();
+int main() { foo(); return 0; }
+""")
+
+t.write("b/Jamfile", """
+    lib b : b.cpp ;
+""")
+t.write("b/b.cpp", """
+#ifdef FOO
+#ifdef _WIN32
+__declspec(dllexport)
+#endif
+void foo() {}
+#endif
+""")
+
+t.run_build_system()
+
+t.cleanup()

Added: boost-jam/boost-build/branches/upstream/current/test/default_features.py
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/default_features.py	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/default_features.py	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,57 @@
+#!/usr/bin/python
+
+#  Copyright (C) Vladimir Prus 2003. Permission to copy, use, modify, sell and
+#  distribute this software is granted provided this copyright notice appears in
+#  all copies. This software is provided "as is" without express or implied
+#  warranty, and with no claim as to its suitability for any purpose.
+
+#  Test that features with default values are always present 
+#  in build properties of any target.
+
+from BoostBuild import Tester, List
+
+t = Tester()
+
+# Declare *non-propagated* feature foo.
+t.write("project-root.jam", """
+import feature : feature ;
+
+feature foo : on off ;
+""")
+
+# Note that '<foo>on' won't be propagated
+# to 'd/l'.
+t.write("Jamfile", """
+exe hello : hello.cpp d//l ;
+""")
+t.write("hello.cpp", """
+#ifdef _WIN32
+__declspec(dllimport)
+#endif
+void foo();
+int main()
+{
+   foo();
+   return 1;
+}
+
+""")
+
+t.write("d/Jamfile", """
+lib l : l.cpp : <foo>on:<define>FOO ;
+""")
+t.write("d/l.cpp", """
+#ifdef _WIN32
+__declspec(dllexport)
+#endif
+#ifdef FOO
+void foo() {}
+#endif
+
+""")
+
+t.run_build_system()
+
+t.expect_addition("bin/$toolset/debug/hello.exe")
+
+t.cleanup()


Property changes on: boost-jam/boost-build/branches/upstream/current/test/default_features.py
___________________________________________________________________
Name: svn:executable
   + 

Added: boost-jam/boost-build/branches/upstream/current/test/dependency-test/Jamfile
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/dependency-test/Jamfile	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/dependency-test/Jamfile	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,21 @@
+
+project test 
+    : requirements <include>src1 
+    ;
+
+exe a 
+    : x.foo a.cpp 
+    ;
+    
+exe b
+    : b.cpp
+    ;    
+    
+# Because of <define>, c.cpp will be compiled to different
+# directory than everything for main target "a". Therefore
+# without <implicit-dependency>, it won't find "x.h", which is part
+# of "a"'s dependency graph.
+exe c
+    : c.cpp 
+    : <define>FOO <implicit-dependency>a
+    ;    

Added: boost-jam/boost-build/branches/upstream/current/test/dependency-test/a.cpp
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/dependency-test/a.cpp	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/dependency-test/a.cpp	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,17 @@
+//  Copyright (c) 2003 Vladimir Prus
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  http://www.boost.org
+// 
+
+#include <a.h>
+# include "a.h"
+#include <x.h>
+
+int main()
+{
+    return 0;
+}

Added: boost-jam/boost-build/branches/upstream/current/test/dependency-test/a.h
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/dependency-test/a.h	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/dependency-test/a.h	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,8 @@
+//  Copyright (c) 2003 Vladimir Prus
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  http://www.boost.org
+// 

Added: boost-jam/boost-build/branches/upstream/current/test/dependency-test/b.cpp
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/dependency-test/b.cpp	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/dependency-test/b.cpp	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,14 @@
+//  Copyright (c) 2003 Vladimir Prus
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  http://www.boost.org
+// 
+
+#include "a.h"
+
+int main()
+{
+}

Added: boost-jam/boost-build/branches/upstream/current/test/dependency-test/b.h
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/dependency-test/b.h	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/dependency-test/b.h	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,8 @@
+//  Copyright (c) 2003 Vladimir Prus
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  http://www.boost.org
+// 

Added: boost-jam/boost-build/branches/upstream/current/test/dependency-test/c.cpp
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/dependency-test/c.cpp	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/dependency-test/c.cpp	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,14 @@
+//  Copyright (c) 2003 Vladimir Prus
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  http://www.boost.org
+// 
+
+#include "x.h"
+
+int main()
+{
+}

Added: boost-jam/boost-build/branches/upstream/current/test/dependency-test/e.cpp
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/dependency-test/e.cpp	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/dependency-test/e.cpp	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,15 @@
+//  Copyright (c) 2003 Vladimir Prus
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  http://www.boost.org
+// 
+
+#include "x.h"
+
+int main()
+{
+    return 0;
+}

Added: boost-jam/boost-build/branches/upstream/current/test/dependency-test/foo.jam
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/dependency-test/foo.jam	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/dependency-test/foo.jam	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,35 @@
+import type ;
+import generators ;
+import os ;
+import print ;
+
+type.register FOO : foo ;
+
+generators.register-standard foo.foo : FOO : CPP H ;
+
+rule foo ( targets * : sources * : properties * )
+{
+    # On NT, you need an exported symbol in order to have an import lib generated
+    if [ os.name ] = NT && <main-target-type>LIB in $(properties)
+    {
+        .decl =  "echo void __declspec(dllexport) foo(){}" ;
+    }
+    if [ modules.peek : OS ] in CYGWIN &&  <main-target-type>LIB in $(properties) && $toolset != gcc
+    {
+        .decl =  "echo 'void __declspec(dllexport) foo(){}'" ;
+    }
+
+
+    .decl1 on $(<) = $(.decl:E="echo //") ;
+    
+    # Further files must be touched also; NT doesn't have a touch command
+    local i = [ print.echo-cmd "#include <z.h>" ] ;
+    .decl2 on $(<) = "      
+    $(i) > " ;
+}
+
+actions foo
+{
+    $(.decl1) > $(<[1]) $(.decl2)$(<[2-])
+}
+

Added: boost-jam/boost-build/branches/upstream/current/test/dependency-test/project-root.jam
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/dependency-test/project-root.jam	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/dependency-test/project-root.jam	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,3 @@
+
+import gcc ;
+import foo ;

Added: boost-jam/boost-build/branches/upstream/current/test/dependency-test/src1/a.h
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/dependency-test/src1/a.h	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/dependency-test/src1/a.h	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,10 @@
+//  Copyright (c) 2003 Vladimir Prus
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  http://www.boost.org
+// 
+
+#include "b.h"

Added: boost-jam/boost-build/branches/upstream/current/test/dependency-test/src1/b.h
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/dependency-test/src1/b.h	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/dependency-test/src1/b.h	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,10 @@
+//  Copyright (c) 2003 Vladimir Prus
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  http://www.boost.org
+// 
+
+#include "c.h"

Added: boost-jam/boost-build/branches/upstream/current/test/dependency-test/src1/c.h
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/dependency-test/src1/c.h	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/dependency-test/src1/c.h	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,8 @@
+//  Copyright (c) 2003 Vladimir Prus
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  http://www.boost.org
+// 

Added: boost-jam/boost-build/branches/upstream/current/test/dependency-test/src1/z.h
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/dependency-test/src1/z.h	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/dependency-test/src1/z.h	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1 @@
+

Added: boost-jam/boost-build/branches/upstream/current/test/dependency-test/src2/b.h
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/dependency-test/src2/b.h	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/dependency-test/src2/b.h	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,8 @@
+//  Copyright (c) 2003 Vladimir Prus
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  http://www.boost.org
+// 

Added: boost-jam/boost-build/branches/upstream/current/test/dependency-test/x.foo
===================================================================

Added: boost-jam/boost-build/branches/upstream/current/test/dependency-test/y.foo
===================================================================

Added: boost-jam/boost-build/branches/upstream/current/test/dependency_property.py
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/dependency_property.py	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/dependency_property.py	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,42 @@
+#!/usr/bin/python
+
+#  Copyright (C) Vladimir Prus 2003. Permission to copy, use, modify, sell and
+#  distribute this software is granted provided this copyright notice appears in
+#  all copies. This software is provided "as is" without express or implied
+#  warranty, and with no claim as to its suitability for any purpose.
+
+# Regression test: virtual targets with different dependency properties
+# were considered different by 'virtual-target.register', but the code
+# which determined target paths ignored dependency properties --- so both
+# targets used to be placed to the same location.
+
+from BoostBuild import Tester, List
+from string import find
+
+
+t = Tester()
+
+t.write("project-root.jam", "")
+t.write("Jamfile", """
+lib foo : foo.cpp ;
+exe hello : hello.cpp ;
+exe hello2 : hello.cpp : <library>foo ;
+""")
+t.write("hello.cpp", """
+int main()
+{
+    return 0;
+}
+
+""")
+t.write("foo.cpp", """
+#ifdef _WIN32
+__declspec(dllexport)
+#endif
+void foo() {}
+""")
+
+t.run_build_system("--no-error-backtrace", status=1)
+t.fail_test(find(t.stdout(), "Duplicate name of actual target") == -1)
+
+t.cleanup()


Property changes on: boost-jam/boost-build/branches/upstream/current/test/dependency_property.py
___________________________________________________________________
Name: svn:executable
   + 

Added: boost-jam/boost-build/branches/upstream/current/test/dependency_test.py
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/dependency_test.py	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/dependency_test.py	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,70 @@
+#!/usr/bin/python
+
+from BoostBuild import Tester, List
+
+t = Tester()
+
+t.set_tree("dependency-test")
+t.run_build_system()
+# Check that main target 'c' was able to find 'x.h' from
+# 'a's dependency graph
+t.expect_addition("bin/$toolset/debug/c.exe")
+
+# Check handling of first level includes.
+
+# Both 'a' and 'b' include "a.h" and should be updated
+t.touch("a.h")
+t.run_build_system()
+
+t.expect_touch("bin/$toolset/debug/a.exe")
+t.expect_touch("bin/$toolset/debug/a.obj")
+t.expect_touch("bin/$toolset/debug/b.exe")
+t.expect_touch("bin/$toolset/debug/b.obj")
+# Now, <dependency> does not add dependency.
+# It sound weird, but is intentional. Need
+# to rename <dependency> eventually.
+#t.expect_touch("bin/$toolset/debug/main-target-c/c.exe")
+t.ignore("*.tds")
+t.expect_nothing_more()
+
+# Only 'a' include <a.h> and should be updated
+t.touch("src1/a.h")
+t.run_build_system()
+
+t.expect_touch("bin/$toolset/debug/a.exe")
+t.expect_touch("bin/$toolset/debug/a.obj")
+t.ignore("*.tds")
+t.expect_nothing_more()
+
+# "src/a.h" includes "b.h" (in the same dir)
+t.touch("src1/b.h")
+t.run_build_system()
+t.expect_touch("bin/$toolset/debug/a.exe")
+t.expect_touch("bin/$toolset/debug/a.obj")
+t.ignore("*.tds")
+t.expect_nothing_more()
+
+# included by "src/b.h". We had a bug: file included via "",
+# like "b.h" is in this case was not scanned at all.
+t.touch("src1/c.h")
+t.run_build_system()
+t.expect_touch("bin/$toolset/debug/a.exe")
+
+t.touch("b.h")
+t.run_build_system()
+t.expect_nothing_more()
+
+# Test dependency on generated header.
+# TODO: we have also to check that generated header is found correctly
+# if it is different for different subvariants. Lacking any toolset
+# support, this check will be implemented later.
+t.touch("x.foo")
+t.run_build_system()
+t.expect_touch("bin/$toolset/debug/a.obj")
+
+# Check that generated headers are scanned for dependencies as well
+t.touch("src1/z.h")
+t.run_build_system()
+t.expect_touch("bin/$toolset/debug/a.obj")
+
+t.cleanup()


Property changes on: boost-jam/boost-build/branches/upstream/current/test/dependency_test.py
___________________________________________________________________
Name: svn:executable
   + 

Added: boost-jam/boost-build/branches/upstream/current/test/direct-request-test/Jamfile
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/direct-request-test/Jamfile	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/direct-request-test/Jamfile	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,9 @@
+
+# This will link correctly only if symbol MACROS is defined when compiling
+# b.cpp. However, this is only possible if that symbol is requested
+# on command line and b.cpp is compiled with directly requested
+# properties.
+
+exe a : a.cpp b ;
+
+lib b : b.cpp ;
\ No newline at end of file

Added: boost-jam/boost-build/branches/upstream/current/test/direct-request-test/Jamfile2
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/direct-request-test/Jamfile2	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/direct-request-test/Jamfile2	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,9 @@
+
+# This will link correctly only if symbol MACROS is not defined when 
+# compiling b.cpp. This tests if direct build request
+# 'release <define>MACROS' to 'b' does not add 'MACROS' when 'b'
+# is compiled with 'debug' -- the version needed by 'a'.
+
+exe a : a.cpp b : <variant>debug ;
+
+lib b : b.cpp ;
\ No newline at end of file

Added: boost-jam/boost-build/branches/upstream/current/test/direct-request-test/a.cpp
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/direct-request-test/a.cpp	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/direct-request-test/a.cpp	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,19 @@
+//  Copyright (c) 2003 Vladimir Prus
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  http://www.boost.org
+// 
+
+void
+# ifdef _WIN32
+__declspec(dllimport)
+# endif 
+foo();
+
+int main() 
+{
+    foo();
+}

Added: boost-jam/boost-build/branches/upstream/current/test/direct-request-test/b.cpp
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/direct-request-test/b.cpp	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/direct-request-test/b.cpp	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,22 @@
+//  Copyright (c) 2003 Vladimir Prus
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  http://www.boost.org
+// 
+
+// This file will declare 'foo' is 'MACROS' is defined.
+
+#ifdef MACROS
+void
+# ifdef _WIN32
+__declspec(dllexport)
+# endif 
+foo() {}
+#endif
+
+# ifdef _WIN32
+int __declspec(dllexport) force_implib_creation;
+# endif 

Added: boost-jam/boost-build/branches/upstream/current/test/direct-request-test/b_inverse.cpp
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/direct-request-test/b_inverse.cpp	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/direct-request-test/b_inverse.cpp	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,22 @@
+//  Copyright (c) 2003 Vladimir Prus
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  http://www.boost.org
+// 
+
+// This file will declare 'foo' is 'MACROS' is NOT defined.
+
+#ifndef MACROS
+void
+# ifdef _WIN32
+__declspec(dllexport)
+# endif 
+foo() {}
+#endif
+
+# ifdef _WIN32
+int __declspec(dllexport) force_implib_creation;
+# endif 

Added: boost-jam/boost-build/branches/upstream/current/test/direct-request-test/project-root.jam
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/direct-request-test/project-root.jam	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/direct-request-test/project-root.jam	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,2 @@
+
+import gcc ;

Added: boost-jam/boost-build/branches/upstream/current/test/direct_request_test.py
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/direct_request_test.py	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/direct_request_test.py	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,46 @@
+#!/usr/bin/python
+
+from BoostBuild import Tester, List
+import os
+from string import strip
+
+t = Tester()
+
+# First check some startup
+t.set_tree("direct-request-test")
+t.run_build_system(extra_args="define=MACROS")
+
+t.expect_addition("bin/$toolset/debug/" 
+                  * (List("a.obj b.obj b.dll a.exe")))
+
+# When building debug version, the 'define' still applies
+t.rm("bin")
+t.run_build_system(extra_args="debug define=MACROS")
+t.expect_addition("bin/$toolset/debug/" 
+                  * (List("a.obj b.obj b.dll a.exe")))
+
+# When building release version, the 'define' should not
+# apply: we'll have direct build request 'release <define>MACROS'
+# and real build properties 'debug'.
+t.copy("Jamfile2", "Jamfile")
+t.copy("b_inverse.cpp", "b.cpp")
+t.rm("bin")
+t.run_build_system(extra_args="release define=MACROS")
+
+
+# Regression test: direct build request was not working
+# when there's more than one level of 'build-project'
+
+t.rm(".")
+t.write('project-root.jam', '')
+t.write('Jamfile', 'build-project a ;')
+t.write('a/Jamfile', 'build-project b ;')
+t.write('a/b/Jamfile', '')
+
+t.run_build_system("release")
+
+
+
+
+
+t.cleanup()


Property changes on: boost-jam/boost-build/branches/upstream/current/test/direct_request_test.py
___________________________________________________________________
Name: svn:executable
   + 

Added: boost-jam/boost-build/branches/upstream/current/test/dll_path.py
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/dll_path.py	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/dll_path.py	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,128 @@
+#!/usr/bin/python
+
+#  Copyright (C) Vladimir Prus 2003. Permission to copy, use, modify, sell and
+#  distribute this software is granted provided this copyright notice appears in
+#  all copies. This software is provided "as is" without express or implied
+#  warranty, and with no claim as to its suitability for any purpose.
+
+#  Test that the <dll-path> property is correctly set when using
+#  <hardcode-dll-paths>true.
+from BoostBuild import Tester, List
+from string import find
+
+
+t = Tester()
+
+# The point of this test is to have exe "main" which uses library "b",
+# which uses library "a". When "main" is built with <hardcode-dll-paths>true,
+# paths to both libraries should be present as values of <dll-path> feature.
+# We create a special target type which reports <dll-path> values on its sources
+# and compare the list of found values with out expectations.
+
+t.write("Jamfile", """ 
+exe main : main.cpp b//b ;
+explicit main ;
+
+path-list mp : main ; 
+""")
+
+t.write("main.cpp", """ 
+int main() { return 0; }
+
+""")
+
+t.write("project-root.jam", """ 
+using dll-paths ; 
+""")
+
+t.write("dll-paths.jam", """ 
+import type ;
+import generators ;
+import feature ;
+import sequence ;
+import print ;
+import "class" : new ;
+
+rule init ( ) 
+{ 
+    type.register PATH_LIST : pathlist : : main ;
+    
+    class dll-paths-list-generator : generator 
+    {
+        rule __init__ ( )
+        {
+            generator.__init__ dll-paths.list : EXE : PATH_LIST ;
+        }
+        
+        rule generated-targets ( sources + : property-set : project name ? )        
+        {
+            local dll-paths ;
+            for local s in $(sources)
+            {
+                local a = [ $(s).action ] ;
+                if $(a)
+                {
+                    local p = [ $(a).properties ] ;
+                    dll-paths += [ $(p).get <dll-path> ] ;
+                }                                                
+            }
+            return [ generator.generated-targets $(sources) 
+              : [ $(property-set).add-raw $(dll-paths:G=<dll-path>) ] : $(project) $(name) ] ;
+            
+        }
+    }
+    generators.register [ new dll-paths-list-generator ] ;
+    
+}
+
+rule list ( target : sources * : properties * )
+{
+    local paths = [ feature.get-values <dll-path> : $(properties) ] ;
+    paths = [ sequence.insertion-sort $(paths) ] ;
+    print.output $(target) ;
+    print.text $(paths) ;
+}
+
+""")
+
+t.write("a/a.cpp", """ 
+void
+#if defined(_WIN32)
+__declspec(dllexport)
+#endif
+foo() {}
+
+
+""")
+
+t.write("a/Jamfile", """ 
+lib a : a.cpp ; 
+""")
+
+t.write("b/b.cpp", """ 
+void
+#if defined(_WIN32)
+__declspec(dllexport)
+#endif
+bar() {}
+
+
+""")
+
+t.write("b/Jamfile", """ 
+lib b : b.cpp ../a//a ; 
+""")
+
+t.run_build_system("hardcode-dll-paths=true")
+
+t.expect_addition("bin/$toolset/debug/mp.pathlist")
+
+es1 = t.adjust_names(["a/bin/$toolset/debug"])[0]
+es2 = t.adjust_names(["b/bin/$toolset/debug"])[0]
+content = t.read("bin/$toolset/debug/mp.pathlist")
+
+t.fail_test(find(content, es1) == -1)
+t.fail_test(find(content, es2) == -1)
+
+t.cleanup()
+


Property changes on: boost-jam/boost-build/branches/upstream/current/test/dll_path.py
___________________________________________________________________
Name: svn:executable
   + 

Added: boost-jam/boost-build/branches/upstream/current/test/double_loading.py
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/double_loading.py	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/double_loading.py	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,47 @@
+#!/usr/bin/python
+
+#  Copyright (C) Vladimir Prus 2003. Permission to copy, use, modify, sell and
+#  distribute this software is granted provided this copyright notice appears in
+#  all copies. This software is provided "as is" without express or implied
+#  warranty, and with no claim as to its suitability for any purpose.
+
+from BoostBuild import Tester, List
+import string
+
+t = Tester()
+
+#  Regression test for double loading of the same Jamfile.
+t.write("Jamfile", """ 
+build-project subdir ; 
+""")
+
+t.write("project-root.jam", """ 
+""")
+
+t.write("subdir/Jamfile", """ 
+ECHO "Loaded subdir" ; 
+""")
+
+t.run_build_system(subdir="subdir")
+t.fail_test(string.count(t.stdout(), "Loaded subdir") != 1)
+
+#  Regression test for a more contrived case. The top-level
+#  jamfile refers to subdir via use-project, while subdir's
+#  Jamfile is being loaded. The motivation why use-project
+#  referring to subprojects are usefull can be found at
+#  http://article.gmane.org/gmane.comp.lib.boost.build/3906/
+t.write("Jamfile", """ 
+use-project /subdir : subdir ; 
+""")
+
+t.write("project-root.jam", """ 
+""")
+
+t.write("subdir/Jamfile", """ 
+project subdir ; 
+""")
+
+t.run_build_system(subdir="subdir");
+
+t.cleanup()
+


Property changes on: boost-jam/boost-build/branches/upstream/current/test/double_loading.py
___________________________________________________________________
Name: svn:executable
   + 

Added: boost-jam/boost-build/branches/upstream/current/test/duplicate.py
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/duplicate.py	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/duplicate.py	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,44 @@
+#!/usr/bin/python
+
+#  Copyright (C) Vladimir Prus 2004. Permission to copy, use, modify, sell and
+#  distribute this software is granted provided this copyright notice appears in
+#  all copies. This software is provided "as is" without express or implied
+#  warranty, and with no claim as to its suitability for any purpose.
+
+#  This test tries to stage the same file to the same location by *two*
+#  different stage rules, in two different projects. This is not exactly
+#  good thing to do, but still, V2 should handle this. We had two bugs:
+#  - since the file is referred from two projects, we created to different
+#    virtual targets
+#  - we also failed to figure out that the two target corresponding to the
+#    copied files (created in two projects) are actually equivivalent.
+
+from BoostBuild import Tester, List
+
+
+t = Tester()
+
+t.write("a.cpp", """ 
+""")
+
+t.write("Jamfile", """ 
+build-project a ;
+build-project b ; 
+""")
+
+t.write("project-root.jam", """ 
+""")
+
+t.write("a/Jamfile", """ 
+stage bin : ../a.cpp : <location>../dist ; 
+""")
+
+t.write("b/Jamfile", """ 
+stage bin : ../a.cpp : <location>../dist ; 
+""")
+
+t.run_build_system()
+t.expect_addition("dist/a.cpp")
+
+
+t.cleanup()


Property changes on: boost-jam/boost-build/branches/upstream/current/test/duplicate.py
___________________________________________________________________
Name: svn:executable
   + 

Added: boost-jam/boost-build/branches/upstream/current/test/echo_args.jam
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/echo_args.jam	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/echo_args.jam	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,16 @@
+rule echo_args ( a b ? c ? : d + : e * )
+{
+    ECHO a= $(a) b= $(b) c= $(c) ":" d= $(d) ":" e= $(e) ;
+}
+
+rule echo_varargs ( a b ? c ? : d + : e * : * )
+{
+    ECHO a= $(a) b= $(b) c= $(c) ":" d= $(d) ":" e= $(e)
+      ": rest= "$(4[1]) $(4[2])
+      ": "$(5[1]) $(5[2])
+      ": "$(6[1]) $(6[2])
+      ": "$(7[1]) $(7[2])
+      ": "$(8[1]) $(8[2])
+      ": "$(9[1]) $(9[2]) ;
+}
+

Added: boost-jam/boost-build/branches/upstream/current/test/empty.jam
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/empty.jam	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/empty.jam	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1 @@
+# This file is empty; it just suppresses warnings
\ No newline at end of file

Added: boost-jam/boost-build/branches/upstream/current/test/expansion.py
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/expansion.py	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/expansion.py	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,92 @@
+#!/usr/bin/python
+
+#  Copyright (C) Vladimir Prus 2003. Permission to copy, use, modify, sell and
+#  distribute this software is granted provided this copyright notice appears in
+#  all copies. This software is provided "as is" without express or implied
+#  warranty, and with no claim as to its suitability for any purpose.
+
+#  This file is template for Boost.Build tests. It creates a simple
+#  project that builds one exe from one source, and checks that the exe
+#  is really created.
+from BoostBuild import Tester, List
+
+
+t = Tester()
+
+t.write("a.cpp", """ 
+#ifdef CF_IS_OFF
+int main() { return 0; }
+#endif
+
+""")
+
+t.write("b.cpp", """ 
+#ifdef CF_1
+int main() { return 0; }
+#endif
+
+""")
+
+t.write("c.cpp", """
+#ifdef FOO
+int main() { return 0; }
+#endif
+
+""")
+
+
+t.write("Jamfile", """ 
+# See if default value of composite feature 'cf'
+# will be expanded to <define>CF_IS_OFF
+exe a : a.cpp ;
+
+# See if subfeature in requirements in expanded.
+exe b : b.cpp : <cf>on-1 ;
+
+# See if conditional requirements are recursively expanded.
+exe c : c.cpp : <toolset>$toolset:<variant>release <variant>release:<define>FOO ;
+""")
+
+t.write("project-root.jam", """ 
+import feature ;
+
+feature.feature cf : off on : composite incidental ;
+
+feature.compose <cf>off : <define>CF_IS_OFF ;
+
+feature.subfeature cf on : version : 1 2 : composite optional incidental ;
+
+feature.compose <cf-on:version>1 : <define>CF_1 ;
+        
+""")
+
+t.expand_toolset("Jamfile")
+
+t.run_build_system()
+t.expect_addition(["bin/$toolset/debug/a.exe",
+                   "bin/$toolset/debug/b.exe",
+                   "bin/$toolset/release/c.exe",
+                   ])
+
+t.rm("bin")
+
+# Test for issue BB60
+t.write("test.cpp", """
+#include "header.h"
+int main() { return 0; }
+""")
+t.write("Jamfile", """
+project
+    : requirements <toolset>$toolset:<include>foo
+    ;
+exe test : test.cpp : <toolset>$toolset ;
+""")
+t.expand_toolset("Jamfile")
+t.write("foo/header.h", """
+""")
+t.write("project-root.jam", "")
+t.run_build_system()
+t.expect_addition("bin/$toolset/debug/test.exe")
+
+t.cleanup()
+


Property changes on: boost-jam/boost-build/branches/upstream/current/test/expansion.py
___________________________________________________________________
Name: svn:executable
   + 

Added: boost-jam/boost-build/branches/upstream/current/test/explicit.py
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/explicit.py	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/explicit.py	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,40 @@
+#!/usr/bin/python
+
+#  Copyright (C) Vladimir Prus 2003. Permission to copy, use, modify, sell and
+#  distribute this software is granted provided this copyright notice appears in
+#  all copies. This software is provided "as is" without express or implied
+#  warranty, and with no claim as to its suitability for any purpose.
+
+#  This file is template for Boost.Build tests. It creates a simple
+#  project that builds one exe from one source, and checks that the exe
+#  is really created.
+from BoostBuild import Tester, List
+
+t = Tester()
+
+t.write("project-root.jam", "")
+t.write("Jamfile", """
+
+exe hello : hello.cpp ;
+exe hello2 : hello.cpp ;
+
+explicit hello2 ;
+""")
+t.write("hello.cpp", """
+int main()
+{
+    return 0;
+}
+
+""")
+
+t.run_build_system()
+t.ignore("*.tds")
+t.expect_addition(List("bin/$toolset/debug/hello") * [".exe", ".obj"])
+t.expect_nothing_more()
+
+t.run_build_system("hello2")
+t.expect_addition("bin/$toolset/debug/hello2.exe")
+
+
+t.cleanup()


Property changes on: boost-jam/boost-build/branches/upstream/current/test/explicit.py
___________________________________________________________________
Name: svn:executable
   + 

Added: boost-jam/boost-build/branches/upstream/current/test/gcc_runtime.py
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/gcc_runtime.py	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/gcc_runtime.py	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,34 @@
+#!/usr/bin/python
+
+#  Copyright (C) Vladimir Prus 2004. Permission to copy, use, modify, sell and
+#  distribute this software is granted provided this copyright notice appears in
+#  all copies. This software is provided "as is" without express or implied
+#  warranty, and with no claim as to its suitability for any purpose.
+
+#  Tests that on gcc, we correctly report problem when static runtime
+#  is requested when building DLL.
+from BoostBuild import Tester, List
+import string
+
+t = Tester()
+
+# Create the needed files
+t.write("project-root.jam", "")
+t.write("Jamfile", """
+lib hello : hello.cpp ;
+""")
+t.write("hello.cpp", """
+int main()
+{
+    return 0;
+}
+""")
+
+t.run_build_system("link-runtime=static", status=1)
+t.fail_test(string.find(t.stdout(),
+                        "on gcc, DLL can't be build with <link-runtime>static") == -1)
+
+t.run_build_system("link=static link-runtime=static")
+t.expect_addition("bin/$toolset/debug/link-runtime-static/link-static/hello.lib")
+
+t.cleanup()


Property changes on: boost-jam/boost-build/branches/upstream/current/test/gcc_runtime.py
___________________________________________________________________
Name: svn:executable
   + 

Added: boost-jam/boost-build/branches/upstream/current/test/generators-test/Jamfile
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/generators-test/Jamfile	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/generators-test/Jamfile	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,15 @@
+
+project 
+    # This is needed to supress gcc warning on flex output, which otherwise
+    # results in test failure
+    : requirements <define>YY_NO_UNPUT
+    ;
+
+exe a : a.cpp b.cxx obj_1 obj_2 c.ui d.wd x.l y.x_pro lib//auxilliary ;
+# This should not cause second compilation of a.cpp 
+exe f : a.cpp b.cxx obj_1 obj_2 lib//auxilliary ;
+
+obj obj_1 : z.cpp : <define>SELECT=1 ;
+obj obj_2 : z.cpp : <define>SELECT=2 ;
+
+nm-exe e : e.cpp ;

Added: boost-jam/boost-build/branches/upstream/current/test/generators-test/a.cpp
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/generators-test/a.cpp	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/generators-test/a.cpp	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,22 @@
+//  Copyright (c) 2003 Vladimir Prus
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  http://www.boost.org
+// 
+
+int foo();
+int bar();
+
+void z1(), z2();
+
+int main()
+{
+    foo();
+    bar();
+    z1();
+    z2();
+    return 0;
+}

Added: boost-jam/boost-build/branches/upstream/current/test/generators-test/b.cxx
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/generators-test/b.cxx	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/generators-test/b.cxx	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,10 @@
+//  Copyright (c) 2003 Vladimir Prus
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  http://www.boost.org
+// 
+
+int foo() { return 0; }

Added: boost-jam/boost-build/branches/upstream/current/test/generators-test/c.ui
===================================================================

Added: boost-jam/boost-build/branches/upstream/current/test/generators-test/d.wd
===================================================================

Added: boost-jam/boost-build/branches/upstream/current/test/generators-test/e.cpp
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/generators-test/e.cpp	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/generators-test/e.cpp	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,8 @@
+//  Copyright (c) 2003 Vladimir Prus
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  http://www.boost.org
+// 

Added: boost-jam/boost-build/branches/upstream/current/test/generators-test/extra.jam
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/generators-test/extra.jam	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/generators-test/extra.jam	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,68 @@
+
+import type ;
+import generators ;
+
+type.register WHL : whl ;
+type.register DLP : dlp ;
+type.register WHL_LR0 : lr0 ;
+type.register WD : wd ;
+
+generators.register-standard extra.whale : WHL : CPP WHL_LR0 H H(%_symbols) ;
+generators.register-standard extra.dolphin : DLP : CPP ;
+generators.register-standard extra.wd : WD : WHL(%_parser) DLP(%_lexer) ;
+
+rule whale ( targets * : sources * : properties * )
+{
+}
+
+actions whale 
+{
+    echo "Whale consuming " $(>)
+    touch $(<)
+}
+
+rule dolphin ( targets * : source * : properties * )
+{
+}
+
+actions dolphin
+{    
+    echo "Dolphin consuming" $(>)
+    touch $(<)        
+}
+
+rule wd ( targets * : source * : properties * )
+{
+}
+
+actions wd
+{    
+    echo "WD consuming" $(>)
+    touch $(<)        
+}
+
+rule x ( target * : source * : properties * )
+{
+}
+
+
+actions x 
+{
+    echo "X: source is " $(>)
+    touch $(<)
+}
+
+rule x_pro ( target * : source * : properties * )
+{
+}
+
+
+actions x_pro
+{
+    echo "X_PRO: source is " $(>)
+    touch $(<)
+}
+
+
+
+

Added: boost-jam/boost-build/branches/upstream/current/test/generators-test/lex.jam
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/generators-test/lex.jam	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/generators-test/lex.jam	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,26 @@
+#  Copyright (C) Vladimir Prus 2002. Permission to copy, use, modify, sell and
+#  distribute this software is granted provided this copyright notice appears in
+#  all copies. This software is provided "as is" without express or implied
+#  warranty, and with no claim as to its suitability for any purpose.
+
+import type ;
+import generators ;
+import feature ;
+import property ;
+import print ;
+
+type.register LEX : l ;
+
+generators.register-standard lex.lex : LEX : C ;
+
+rule lex ( targets * : sources * : properties * )
+{
+    print.output $(<) ;
+    # Need to supress SunCC's warning about empty source
+    # file.
+    print.text "void foo() {}" ;
+}
+
+actions lex 
+{
+}
\ No newline at end of file

Added: boost-jam/boost-build/branches/upstream/current/test/generators-test/lib/Jamfile
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/generators-test/lib/Jamfile	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/generators-test/lib/Jamfile	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,4 @@
+
+static-lib auxilliary : c.cpp ;
+
+lib auxilliary2 : c.cpp ;
\ No newline at end of file

Added: boost-jam/boost-build/branches/upstream/current/test/generators-test/lib/c.cpp
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/generators-test/lib/c.cpp	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/generators-test/lib/c.cpp	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,10 @@
+//  Copyright (c) 2003 Vladimir Prus
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  http://www.boost.org
+// 
+
+int bar() { return 0; }

Added: boost-jam/boost-build/branches/upstream/current/test/generators-test/nm.jam
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/generators-test/nm.jam	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/generators-test/nm.jam	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,34 @@
+import modules ;
+
+rule target-source ( targets * : sources * : properties * )
+{
+    if [ modules.peek : NT ]
+    {
+        main on $(<) = "int main() { return 0; }" ;
+    }
+    else
+    {
+        main on $(<) = "\"int main() { return 0; }\"" ;
+    }
+}
+
+actions target-source
+{
+    echo "NM target source consuming " $(>)
+    echo $(main) > $(<)      
+}
+
+rule cpp-mark ( targets * : sources * : properties * )
+{
+}
+
+actions cpp-mark
+{
+    echo "CPP-MARK consuming " $(>)
+    touch $(<)
+}
+
+
+
+
+

Added: boost-jam/boost-build/branches/upstream/current/test/generators-test/project-root.jam
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/generators-test/project-root.jam	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/generators-test/project-root.jam	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,91 @@
+
+import "class" : new ;
+
+import lex ;
+import qt ;
+import extra ;
+
+import type ;
+
+type.register UI : ui ;
+type.register UIC_H ;
+type.set-generated-target-suffix UIC_H : : h ;
+
+type.register X1 : x1 ;
+type.register X2 : x2  ;
+type.register X_PRO : x_pro ;
+
+import generators ;
+
+generators.register-standard qt.uic : UI UIC_H : CPP ;
+generators.register-standard qt.uic-h : UI : UIC_H ;
+
+# That's an interesting example. Currently, X_PRO will be processed
+# twice.
+generators.register-standard extra.x : X1 X2 : CPP ;
+generators.register-standard extra.x_pro : X_PRO : X1 X2 ;
+
+# The point of this setup of to implement this functionality
+# "When main target type is EST_EXE, build OBJ from CPP-MARKED, not
+# for anything else (like CPP)
+# Unfortunately, this does not really works.
+
+#if $(no-var) {
+import nm ;
+
+type.register CPP_MARKED : marked.cpp : CPP ;
+type.register POSITIONS : positions ;
+type.register NM.TARGET.CPP : target.cpp : CPP ;
+type.register NM_EXE : : EXE : main ;
+
+generators.register-standard nm.target-source : CPP_MARKED : NM.TARGET.CPP ;
+generators.register-standard nm.cpp-mark : CPP : CPP_MARKED POSITIONS ;
+    
+class nm::target::cpp-obj-generator : generator
+{
+    rule __init__ ( )
+    {        
+        generator.__init__ nm.target-obj : NM.TARGET.CPP : OBJ ;
+    }
+    
+    rule requirements ( )
+    {
+        return <main-target-type>NM_EXE ;
+    }
+        
+    # Consider: it it OK to ignore all other generated targets except for the first?
+    rule run ( project name ? : properties * : source : multiple ? ) 
+    {
+        if [ $(source).type ] = CPP {    
+            local converted = [ generators.construct $(project) : NM.TARGET.CPP : $(properties) : $(source) ] ;
+        if $(converted[1])
+            {            
+                local result = [ generators.construct $(project) : OBJ : $(properties) : $(converted[1]) ] ;
+                return $(result) ;
+            }
+            else
+            {
+                return ;
+            }        
+        }
+        else
+        {
+            return ;
+        }        
+    }                
+}
+
+generators.register [ new nm::target::cpp-obj-generator ] ;
+
+generators.override nm.target-obj : all ;
+
+#}
+
+
+
+
+
+
+
+
+

Added: boost-jam/boost-build/branches/upstream/current/test/generators-test/qt.jam
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/generators-test/qt.jam	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/generators-test/qt.jam	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,29 @@
+import modules ;
+
+if [ modules.peek : NT ]
+{
+    comment = // ;
+}
+else
+{
+    comment = \"//\" ;
+}
+
+rule uic ( target : sources * : properties * )
+{
+    comment on $(<) = $(comment) ;
+}
+rule uic-h ( target : sources * : properties * )
+{
+    comment on $(<) = $(comment) ;
+}
+
+actions uic 
+{
+    echo $(comment) $(>) > $(<)
+}
+
+actions uic-h
+{
+    echo $(comment) $(>) > $(<)
+}

Added: boost-jam/boost-build/branches/upstream/current/test/generators-test/x.l
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/generators-test/x.l	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/generators-test/x.l	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,5 @@
+%option noyywrap
+
+%%
+
+%%
\ No newline at end of file

Added: boost-jam/boost-build/branches/upstream/current/test/generators-test/y.x_pro
===================================================================

Added: boost-jam/boost-build/branches/upstream/current/test/generators-test/z.cpp
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/generators-test/z.cpp	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/generators-test/z.cpp	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,16 @@
+//  Copyright (c) 2003 Vladimir Prus
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  http://www.boost.org
+// 
+
+#if SELECT == 1
+void z1() {}
+#elif SELECT == 2
+void z2() {}
+#else
+#error Invlid value of SELECT
+#endif

Added: boost-jam/boost-build/branches/upstream/current/test/generators_test.py
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/generators_test.py	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/generators_test.py	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,36 @@
+#!/usr/bin/python
+
+from BoostBuild import Tester, List
+import os
+
+t = Tester()
+
+t.set_tree("generators-test")
+t.run_build_system()
+
+t.expect_addition(
+    "bin/$toolset/debug/"
+    * (
+    List(   
+       "a.obj b.obj c.h c.cpp c.obj d_parser.whl d_lexer.dlp d_parser.cpp d_lexer.cpp "
+        + "d_parser.lr0 d_parser.h d_parser_symbols.h x.c x.obj y.x1 y.x2 "
+        + "y.cpp y.obj e.marked.cpp e.positions e.target.cpp e.obj "))
+    )
+ok = 0
+
+t.expect_addition("bin/$toolset/debug/a.exe")
+
+t.expect_addition(["lib/bin/$toolset/debug/c.obj",
+                   "lib/bin/$toolset/debug/auxilliary.lib",
+                   ])
+
+
+t.run_build_system(subdir='lib')
+
+t.expect_addition(["lib/bin/$toolset/debug/auxilliary2.dll"])
+
+t.run_build_system(subdir='lib', extra_args="link=static")
+
+t.expect_addition(["lib/bin/$toolset/debug/link-static/auxilliary2.lib"])
+
+t.cleanup()


Property changes on: boost-jam/boost-build/branches/upstream/current/test/generators_test.py
___________________________________________________________________
Name: svn:executable
   + 

Added: boost-jam/boost-build/branches/upstream/current/test/glob.py
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/glob.py	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/glob.py	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,91 @@
+#!/usr/bin/python
+
+#  Copyright (C) Vladimir Prus 2003. Permission to copy, use, modify, sell and
+#  distribute this software is granted provided this copyright notice appears in
+#  all copies. This software is provided "as is" without express or implied
+#  warranty, and with no claim as to its suitability for any purpose.
+
+#  Test the 'glob' rule in Jamfile context.
+from BoostBuild import Tester, List
+
+# Create a temporary working directory
+t = Tester()
+
+t.write("project-root.jam", """ 
+""")
+
+t.write("Jamfile", """ 
+""")
+
+t.write("d1/a.cpp", """ 
+int main() { return 0; }
+
+""")
+
+t.write("d1/Jamfile", """ 
+exe a : [ glob *.cpp ] ../d2/d//l ; 
+""")
+
+t.write("d2/d/l.cpp", """ 
+#if defined(_WIN32)
+__declspec(dllexport)
+void force_import_lib_creation() {}
+#endif
+""")
+
+t.write("d2/d/Jamfile", """ 
+lib l : [ glob *.cpp ] ; 
+""")
+
+t.run_build_system(subdir="d1")
+
+t.expect_addition("d1/bin/$toolset/debug/a.exe")
+
+t.rm("d2/d/bin")
+t.run_build_system(subdir="d2/d")
+t.expect_addition("d2/d/bin/$toolset/debug/l.dll")
+
+# Test that when 'source-location' is explicitly-specified
+# glob works relatively to source location
+t.rm("d1")
+
+t.write("d1/src/a.cpp", """ 
+int main() { return 0; }
+
+""")
+
+t.write("d1/Jamfile", """
+project : source-location src ;
+exe a : [ glob *.cpp ] ../d2/d//l ; 
+""")
+
+t.run_build_system(subdir="d1")
+t.expect_addition("d1/bin/$toolset/debug/a.exe")
+
+# Test that wildcards can include directories
+t.rm("d1")
+
+t.write("d1/src/foo/a.cpp", """
+void bar();
+int main() { bar(); return 0; }
+
+""")
+
+t.write("d1/src/bar/b.cpp", """
+void bar() {}
+
+""")
+
+
+t.write("d1/Jamfile", """
+project : source-location src ;
+exe a : [ glob foo/*.cpp bar/*.cpp ] ../d2/d//l ; 
+""")
+
+t.run_build_system(subdir="d1")
+t.expect_addition("d1/bin/$toolset/debug/a.exe")
+
+
+
+
+t.cleanup()


Property changes on: boost-jam/boost-build/branches/upstream/current/test/glob.py
___________________________________________________________________
Name: svn:executable
   + 

Added: boost-jam/boost-build/branches/upstream/current/test/inherit_toolset.py
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/inherit_toolset.py	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/inherit_toolset.py	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,78 @@
+#!/usr/bin/python
+
+#  Copyright (C) Vladimir Prus 2003. Permission to copy, use, modify, sell and
+#  distribute this software is granted provided this copyright notice appears in
+#  all copies. This software is provided "as is" without express or implied
+#  warranty, and with no claim as to its suitability for any purpose.
+
+from BoostBuild import Tester, List
+from string import find
+
+t = Tester(pass_toolset=0)
+
+t.write("a.cpp", """ 
+""")
+
+t.write("yfc1.jam", """ 
+import toolset ;
+import generators ;
+
+toolset.register yfc1 ;
+
+rule init ( )
+{
+}
+
+generators.register-standard yfc1.compile : CPP : OBJ : <toolset>yfc1 ;
+generators.register-standard yfc1.link : OBJ : EXE : <toolset>yfc1 ;
+
+actions compile
+{
+    yfc1-compile 
+}
+
+actions link
+{
+    yfc1-link
+}
+
+
+""")
+
+t.write("yfc2.jam", """ 
+import toolset ;
+
+toolset.register yfc2 ;
+toolset.inherit yfc2 : yfc1 ;
+
+rule init ( )
+{
+}
+
+actions link
+{
+    yfc2-link
+} 
+""")
+
+t.write("Jamfile", """ 
+exe a : a.cpp ; 
+""")
+
+t.write("project-root.jam", """
+using yfc1 ;
+""")
+
+t.run_build_system("-n -d2 yfc1")
+t.fail_test(find(t.stdout(), "yfc1-link") == -1)
+
+# Make sure we don't have to explicit 'use' yfc1.
+t.write("project-root.jam", """
+using yfc2 ;
+""")
+
+t.run_build_system("-n -d2 yfc2")
+t.fail_test(find(t.stdout(), "yfc2-link") == -1)
+
+t.cleanup()
+


Property changes on: boost-jam/boost-build/branches/upstream/current/test/inherit_toolset.py
___________________________________________________________________
Name: svn:executable
   + 

Added: boost-jam/boost-build/branches/upstream/current/test/inline.py
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/inline.py	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/inline.py	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,50 @@
+#!/usr/bin/python
+
+#  Copyright (C) Vladimir Prus 2003. Permission to copy, use, modify, sell and
+#  distribute this software is granted provided this copyright notice appears in
+#  all copies. This software is provided "as is" without express or implied
+#  warranty, and with no claim as to its suitability for any purpose.
+
+from BoostBuild import Tester, List
+
+t = Tester()
+
+t.write("project-root.jam", "")
+t.write("Jamfile", """ 
+alias everything : [ exe a : a.cpp ] ; 
+""")
+
+t.write("a.cpp", """ 
+int main()
+{
+    return 0;
+}
+
+""")
+
+t.run_build_system()
+t.expect_addition("bin/$toolset/debug/everything..a.exe")
+t.rm("bin/$toolset/debug/everything..a.exe")
+
+t.run_build_system("everything..a")
+t.expect_addition("bin/$toolset/debug/everything..a.exe")
+
+t.rm("bin")
+
+# Now check that inline targets with the same name but
+# present in different places are not confused between
+# each other, and with top-level targets.
+t.write("Jamfile", """
+exe a : a.cpp ;
+alias everything : [ exe a : a.cpp ] ;
+alias everything2 : [ exe a : a.cpp ] ; 
+""")
+
+t.run_build_system()
+t.expect_addition("bin/$toolset/debug/a.exe")
+t.expect_addition("bin/$toolset/debug/everything..a.exe")
+t.expect_addition("bin/$toolset/debug/everything2..a.exe")
+
+
+t.cleanup()
+


Property changes on: boost-jam/boost-build/branches/upstream/current/test/inline.py
___________________________________________________________________
Name: svn:executable
   + 

Added: boost-jam/boost-build/branches/upstream/current/test/library_chain.py
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/library_chain.py	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/library_chain.py	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,94 @@
+#!/usr/bin/python
+
+#  Copyright (C) Vladimir Prus 2003. Permission to copy, use, modify, sell and
+#  distribute this software is granted provided this copyright notice appears in
+#  all copies. This software is provided "as is" without express or implied
+#  warranty, and with no claim as to its suitability for any purpose.
+
+#  Test that a chain of libraries work ok, not matter if we use static or
+#  shared linking.
+from BoostBuild import Tester, List
+import string
+
+t = Tester()
+
+t.write("Jamfile", """
+# Stage the binary, so that it will be relinked
+# without hardcode-dll-paths. That will chech that
+# we pass correct -rpath-link, even if not passing
+# -rpath.
+stage dist : main ;
+exe main : main.cpp b ; 
+""")
+
+t.write("main.cpp", """ 
+void foo();
+
+int main() { foo(); return 0; }
+
+""")
+
+t.write("project-root.jam", """ 
+""")
+
+t.write("a/a.cpp", """
+void
+#if defined(_WIN32)
+__declspec(dllexport)
+#endif
+gee() {}
+void
+#if defined(_WIN32)
+__declspec(dllexport)
+#endif
+geek() {} 
+""")
+
+t.write("a/Jamfile", """ 
+lib a : a.cpp ; 
+""")
+
+t.write("b/b.cpp", """ 
+void geek();
+
+void 
+#if defined(_WIN32)
+__declspec(dllexport)
+#endif
+foo() { geek(); }
+
+""")
+
+t.write("b/Jamfile", """ 
+lib b : b.cpp ../a//a ; 
+""")
+
+t.run_build_system(stderr=None)
+t.expect_addition("bin/$toolset/debug/main.exe")
+t.rm(["bin", "a/bin", "b/bin"])
+
+t.run_build_system("link=static")
+t.expect_addition("bin/$toolset/debug/link-static/main.exe")
+t.rm(["bin", "a/bin", "b/bin"])
+
+t.write("b/Jamfile", """ 
+lib b : b.cpp ../a//a/<link>shared : <link>static ; 
+""")
+
+t.run_build_system()
+t.expect_addition("bin/$toolset/debug/main.exe")
+t.rm(["bin", "a/bin", "b/bin"])
+
+# Test that putting library in sources of a searched library
+# works.
+t.write("Jamfile", """
+exe main : main.cpp png ;
+lib png : z : <name>png ;
+lib z : : <name>zzz ;
+""")
+t.run_build_system("-a -n -d+2")
+t.fail_test(string.find(t.stdout(), "zzz") == -1)
+
+
+
+t.cleanup()


Property changes on: boost-jam/boost-build/branches/upstream/current/test/library_chain.py
___________________________________________________________________
Name: svn:executable
   + 

Added: boost-jam/boost-build/branches/upstream/current/test/library_order.py
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/library_order.py	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/library_order.py	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,123 @@
+#!/usr/bin/python
+
+#  Copyright (C) Vladimir Prus 2004. Permission to copy, use, modify, sell and
+#  distribute this software is granted provided this copyright notice appears in
+#  all copies. This software is provided "as is" without express or implied
+#  warranty, and with no claim as to its suitability for any purpose.
+
+from BoostBuild import Tester, List
+import string
+
+
+#  Test that on compilers which are sensitive to library order on
+#  linker's command line, we generate the right order.
+t = Tester()
+
+t.write("a.cpp", """ 
+void b();
+
+void a()
+{
+   b();
+}
+
+""")
+
+t.write("b.cpp", """ 
+void c();
+
+void b()
+{
+    c();
+} 
+""")
+
+t.write("c.cpp", """ 
+void d();
+
+void c() 
+{
+    d();    
+}
+
+""")
+
+t.write("d.cpp", """ 
+void d() {}
+
+""")
+
+# The order of libraries in 'main' is crafted so that
+# we get error unless we do something about the order ourselfs.
+t.write("Jamfile", """ 
+exe main : main.cpp libd libc libb liba ;
+lib libd : d.cpp ;
+lib libc : c.cpp : <link>static <use>libd ;
+lib libb : b.cpp : <use>libc ;
+lib liba : a.cpp : <use>libb ;
+
+""")
+
+t.write("main.cpp", """ 
+void a();
+
+int main()
+{
+    a();
+    return 0;
+}
+
+""")
+
+t.write("project-root.jam", """ 
+""")
+
+t.run_build_system()
+t.expect_addition("bin/$toolset/debug/main.exe")
+
+# Test the order between searched libraries
+t.write("Jamfile", """
+exe main : main.cpp png z ;
+lib png : z : <name>png ;
+lib z : : <name>zzz ;
+""")
+
+t.run_build_system("-a -n -d+2")
+t.fail_test(string.find(t.stdout(), "png") > string.find(t.stdout(), "zzz"))
+
+t.write("Jamfile", """
+exe main : main.cpp png z ;
+lib png : : <name>png ;
+lib z : png : <name>zzz ;
+""")
+
+t.run_build_system("-a -n -d+2")
+t.fail_test(string.find(t.stdout(), "png") < string.find(t.stdout(), "zzz"))
+
+# Test the order between prebuilt libraries
+
+t.write("first.a", "")
+t.write("second.a", "")
+
+t.write("Jamfile", """
+exe main : main.cpp first second ;
+lib first : second : <file>first.a ;
+lib second : : <file>second.a ;
+""")
+
+t.run_build_system("-a -n -d+2")
+t.fail_test(string.find(t.stdout(), "first") > string.find(t.stdout(), "second"))
+
+t.write("Jamfile", """
+exe main : main.cpp first second ;
+lib first : : <file>first.a ;
+lib second : first : <file>second.a ;
+""")
+
+t.run_build_system("-a -n -d+2")
+t.fail_test(string.find(t.stdout(), "first") < string.find(t.stdout(), "second"))
+
+
+
+
+t.cleanup()


Property changes on: boost-jam/boost-build/branches/upstream/current/test/library_order.py
___________________________________________________________________
Name: svn:executable
   + 

Added: boost-jam/boost-build/branches/upstream/current/test/library_property.py
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/library_property.py	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/library_property.py	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,63 @@
+#!/usr/bin/python
+
+#  Copyright (C) Vladimir Prus 2004. Permission to copy, use, modify, sell and
+#  distribute this software is granted provided this copyright notice appears in
+#  all copies. This software is provided "as is" without express or implied
+#  warranty, and with no claim as to its suitability for any purpose.
+
+#  Test that the <library> property has no effect on "obj" targets.
+#  Previously, it affected all targets, so
+#
+#     project : requirements <library>foo ;
+#     exe a : a.cpp helper ;
+#     obj helper : helper.cpp : <optimization>off ;
+#
+#  caused 'foo' to be built with with and without optimization.
+from BoostBuild import Tester, List
+
+# Create a temporary working directory
+t = Tester()
+
+t.write("Jamfile", """ 
+project
+   : requirements <library>lib//x
+   ;
+exe a : a.cpp foo ;
+obj foo : foo.cpp : <variant>release ; 
+""")
+
+t.write("a.cpp", """
+void aux();
+int main() { aux(); }
+""")
+
+t.write("foo.cpp", """
+void gee();
+void aux() { gee(); }
+""")
+
+t.write("project-root.jam", """ 
+""")
+
+t.write("lib/x.cpp", """
+void
+#if defined(_WIN32)
+__declspec(dllexport)
+#endif
+gee() {}
+""")
+
+t.write("lib/Jamfile", """ 
+lib x : x.cpp ;
+""")
+
+t.write("lib/project-root.jam", """ 
+""")
+
+
+t.run_build_system()
+t.expect_addition("bin/$toolset/debug/a.exe")
+t.expect_nothing("lib/bin/$toolset/release/x.obj")
+t.cleanup()
+
+


Property changes on: boost-jam/boost-build/branches/upstream/current/test/library_property.py
___________________________________________________________________
Name: svn:executable
   + 

Added: boost-jam/boost-build/branches/upstream/current/test/load_dir.py
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/load_dir.py	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/load_dir.py	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,58 @@
+#!/usr/bin/python
+
+"""
+Traverses a directory and output the code that would
+create the same directory structure during testing.
+Assumes that the instance of Tester is called 't'. 
+"""
+
+import sys
+import os
+import stat
+import string
+
+def usage():
+    print "usage: load_dir.py directory"
+
+def remove_first_component(path):
+    result = [path]
+    while 1:
+        s = os.path.split(result[0])
+        if not s[0]:
+            break
+        result[:1] = list(s)
+    return apply(os.path.join, result[1:])
+    
+    
+
+def create_file(arg, dirname, fnames):
+    for n in fnames:
+        path = os.path.join(dirname, n)
+        if not os.path.isdir(path):
+            print "t.write(\"%s\", \"\"\"" % (remove_first_component(path),),
+            f = open(path, "r")
+            for l in f:
+                print l,
+            print '\n""")\n'
+
+def main():
+    if len(sys.argv) != 2:
+        usage()
+    else:
+        path = sys.argv[1]
+
+        if not os.access(path, os.F_OK):
+            print "Path '%s' does not exist" % (path,)
+            sys.exit(1)
+
+        if not os.path.isdir(path):
+            print "Path '%s' is not a directory" % (path,)
+        
+        os.path.walk(path, create_file, None)
+
+if __name__ == '__main__':
+    main()
+
+        
+        
+    


Property changes on: boost-jam/boost-build/branches/upstream/current/test/load_dir.py
___________________________________________________________________
Name: svn:executable
   + 

Added: boost-jam/boost-build/branches/upstream/current/test/loop.py
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/loop.py	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/loop.py	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,28 @@
+#!/usr/bin/python
+
+#  Copyright (C) Vladimir Prus 2003. Permission to copy, use, modify, sell and
+#  distribute this software is granted provided this copyright notice appears in
+#  all copies. This software is provided "as is" without express or implied
+#  warranty, and with no claim as to its suitability for any purpose.
+
+from BoostBuild import Tester, List
+from string import find
+
+t = Tester()
+
+
+t.write("project-root.jam", "")
+t.write("Jamfile", """ 
+
+lib main : main.cpp l ;
+lib l : l.cpp main ; 
+""")
+
+t.write("main.cpp", "")
+t.write("l.cpp", "")
+
+t.run_build_system("--no-error-backtrace", status=1)
+t.fail_test(find(t.stdout(), "error: Recursion in main target references") == -1)
+t.fail_test(find(t.stdout(), "./main ./l ./main") == -1)
+
+t.cleanup()


Property changes on: boost-jam/boost-build/branches/upstream/current/test/loop.py
___________________________________________________________________
Name: svn:executable
   + 

Added: boost-jam/boost-build/branches/upstream/current/test/m1-01.py
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/m1-01.py	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/m1-01.py	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,60 @@
+#!/usr/bin/python
+# Test the very basic 'make' functionality.
+
+from BoostBuild import Tester, List
+
+t = Tester()
+t.set_tree("test1")
+
+
+# Check that we can build something
+
+t.run_build_system("-sTOOLSET=yfc")
+
+t.expect_addition("bin/a.obj/yfc/debug/runtime-link-dynamic/a.obj")
+t.expect_addition("bin/a/yfc/debug/runtime-link-dynamic/a")
+t.expect_nothing_more()
+
+t.fail(t.read("bin/a.obj/yfc/debug/runtime-link-dynamic/a.obj") !=\
+"""
+<optimization>off <rtti>on <runtime-link>dynamic <toolset>yfc <variant>debug
+a.cpp
+""")
+
+t.fail(t.read("bin/a/yfc/debug/runtime-link-dynamic/a") !=\
+"""
+<optimization>off <rtti>on <runtime-link>dynamic <toolset>yfc <variant>debug
+<optimization>off <rtti>on <runtime-link>dynamic <toolset>yfc <variant>debug
+a.cpp
+""")
+
+# Check that we have vanilla target names available
+
+t.touch("a.cpp")
+t.run_build_system("-sTOOLSET a.obj")
+t.expect_touch("bin/a.obj/yfc/debug/runtime-link-dynamic/a.obj")
+t.expect_no_modification("bin/a/yfc/debug/runtime-link-dynamic/a")
+
+
+# Check that if build request cannot be completely matches, a warning is
+# issued and subvariant with link-compatible properties is used
+
+t.write("Jamfile", t.read("Jamfile2"))
+stdout="""Warning: cannot exactly satisfy request for ./a with properties
+    <optimization>off <rtti>on <runtime-link>dynamic <toolset>yfc <variant>debug
+Using
+    <optimization>space <rtti>on <runtime-link>dynamic <toolset>yfc <variant>debug
+instead.
+""")
+t.run_build_system("-sTOOLSET=yfc", stdout=stdout)
+
+# Check that conflicting link-incompatible requirements prevent building.
+t.write("Jamfile", t.read("Jamfile3"))
+stdout="""Warning: cannot satisfy request for ./a with properties
+    <optimization>off <rtti>on <runtime-link>dynamic <toolset>yfc <variant>debug
+Nothing will be built.
+""")
+t.run_build_system("-sTOOLSET=yfc", stdout=stdout, status=1)
+
+t.pass_test()
+


Property changes on: boost-jam/boost-build/branches/upstream/current/test/m1-01.py
___________________________________________________________________
Name: svn:executable
   + 

Added: boost-jam/boost-build/branches/upstream/current/test/m1-02.py
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/m1-02.py	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/m1-02.py	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,88 @@
+#!/usr/bin/python
+
+# Tests that 'make' accepts target from other directories and that
+# build request for those targets can be overriden.
+
+from BoostBuild import Tester, List
+
+t = Tester()
+t.set_tree("test1")
+
+t.run_build_system("-sTOOLSET=yfc")
+
+t.expect_addition("bin/a.obj/yfc/debug/runtime-link-dynamic/a.obj")
+t.expect_addition("auxillary/bin/b.obj/yfc/debug/runtime-link-dynamic/optimization-space/b.obj")
+t.expect_addition("bin/a/yfc/debug/runtime-link-dynamic/a")
+t.expect_nothing_more()
+
+t.fail(t.read("bin/a.obj/yfc/debug/runtime-link-dynamic/a.obj") !=\
+"""
+<optimization>off <rtti>on <runtime-link>dynamic <toolset>yfc <variant>debug
+a.cpp
+""")
+
+t.fail(t.read("auxillary/bin/b.obj/yfc/debug/runtime-link-dynamic/b.obj") !=\
+"""
+<optimization>space <rtti>on <runtime-link>dynamic <toolset>yfc <variant>debug
+b.cpp
+""")
+
+
+t.fail(t.read("bin/a/yfc/debug/runtime-link-dynamic/a") !=\
+"""
+<optimization>off <rtti>on <runtime-link>dynamic <toolset>yfc <variant>debug
+<optimization>off <rtti>on <runtime-link>dynamic <toolset>yfc <variant>debug
+a.cpp
+<optimization>space <rtti>on <runtime-link>dynamic <toolset>yfc <variant>debug
+b.cpp
+""")
+
+# Check that we have vanilla target names available in subdirs
+
+t.touch("auxillary/b.cpp")
+t.run_build_system("-sTOOLSET b.obj", subdir="auxillary")
+t.expect_touch("auxillary/bin/b.obj/yfc/debug/runtime-link-dynamic/optimization-space/b.obj")
+t.expect_no_modification("bin/a.obj/yfc/debug/runtime-link-dynamic/a.obj")
+t.expect_no_modification("bin/a/yfc/debug/runtime-link-dynamic/a")
+
+
+# Check that we cannot request link-incompatible property for source target
+
+t.write('Jamfile', t.read('Jamfile2'))
+stdout="""Error: subvariant of target ./a with properties
+    <optimization>off <rtti>on <runtime-link>dynamic <toolset>yfc <variant>debug
+requests link-incompatible property
+    <rtti>off
+for source @auxillary/b.obj
+"""
+t.run_build_system("-sTOOLSET=yfc", stdout=stdout)
+
+# Check that if we request link-compatible property then requirement for
+# the source target will override it, with warning. This is similar to
+# the way build requests are satisfied (see the first test)
+# CONSIDER: should be print the main target which requests this one
+# (and modifies requiremenets)?
+
+t.write('Jamfile3', t.read('Jamfile3'))
+t.write('auxillary/Jamfile3', t.read('auxillary/Jamfile3'))
+stdout="""Warning: cannot exactly satisfy request for auxillary/b.obj with properties
+    <optimization>space <rtti>on <runtime-link>dynamic <toolset>yfc <variant>debug
+Using
+    <optimization>speed <rtti>on <runtime-link>dynamic <toolset>yfc <variant>debug
+instead.
+"""
+t.run_build_system("-sTOOLSET=yfc", stdout=stdout)
+
+
+# Check for link-incompatible properties
+
+t.write('Jamfile4', t.read('Jamfile4'))
+t.write('auxillary/Jamfile4', t.read('auxillary/Jamfile4'))
+stdout="""Warning: cannot satisfy request for auxillary/b.obj with properties
+    <optimization>space <rtti>on <runtime-link>dynamic <toolset>yfc <variant>debug
+Nothing will be built.
+""")
+
+
+t.pass_test()
+


Property changes on: boost-jam/boost-build/branches/upstream/current/test/m1-02.py
___________________________________________________________________
Name: svn:executable
   + 

Added: boost-jam/boost-build/branches/upstream/current/test/m1-03.py
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/m1-03.py	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/m1-03.py	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,56 @@
+#!/usr/bin/python
+# Tests that we can use objects from other projects
+# (i.e. with other project root)
+# Test also that we can refer to those target using project-id.
+
+from BoostBuild import Tester, List
+
+t = Tester()
+t.set_tree("test1")
+
+t.run_build_system("-sTOOLSET=yfc", subdir="p1")
+
+t.expect_addition("p1/bin/a.obj/yfc/debug/runtime-link-dynamic/a.obj")
+t.expect_addition("p1/auxillary/bin/b.obj/yfc/debug/runtime-link-dynamic/optimization-space/b.obj")
+t.expect_addition("p2/bin/c.obj/yfc/debug/runtime-link-dynamic/c.obj")
+t.expect_addition("bin/a/yfc/debug/runtime-link-dynamic/a")
+t.expect_nothing_more()
+
+t.fail(t.read("p1/bin/a.obj/yfc/debug/runtime-link-dynamic/a.obj") !=\
+"""
+<optimization>off <rtti>on <runtime-link>dynamic <toolset>yfc <variant>debug
+a.cpp
+""")
+
+t.fail(t.read("p1/auxillary/bin/b.obj/yfc/debug/runtime-link-dynamic/b.obj") !=\
+"""
+<optimization>space <rtti>on <runtime-link>dynamic <toolset>yfc <variant>debug
+b.cpp
+""")
+
+t.fail(t.read("p2/bin/c.obj/yfc/debug/runtime-link-dynamic/c.obj") !=\
+"""
+<include>everything <optimization>off <rtti>on <runtime-link>dynamic <toolset>yfc <variant>debug
+a.cpp
+""")
+
+
+t.fail(t.read("bin/a/yfc/debug/runtime-link-dynamic/a") !=\
+"""
+<optimization>off <rtti>on <runtime-link>dynamic <toolset>yfc <variant>debug
+<optimization>off <rtti>on <runtime-link>dynamic <toolset>yfc <variant>debug
+a.cpp
+<optimization>space <rtti>on <runtime-link>dynamic <toolset>yfc <variant>debug
+b.cpp
+<include>everything <optimization>space <rtti>on <runtime-link>dynamic <toolset>yfc <variant>debug
+c.cpp
+""")
+
+t.expect_nothing_more()
+
+# TODO: need to write test cases for referring to targets using project-id.
+
+
+
+t.pass_test()
+


Property changes on: boost-jam/boost-build/branches/upstream/current/test/m1-03.py
___________________________________________________________________
Name: svn:executable
   + 

Added: boost-jam/boost-build/branches/upstream/current/test/make_rule.py
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/make_rule.py	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/make_rule.py	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,59 @@
+#!/usr/bin/python
+
+# Test the 'make' rule
+
+from BoostBuild import Tester
+from string import find
+
+t = Tester(pass_toolset=1)
+
+t.write("project-root.jam", "")
+t.write("Jamfile", """
+
+rule creator ( string targets * : sources * : * )
+{
+    STRING on $(targets) = $(string) ;
+    creator2 $(targets) : $(sources) ;
+}
+
+actions creator2
+{
+    echo $(STRING) > $(<)
+}
+
+make foo.bar : : creator foobar ;
+""")
+
+t.run_build_system()
+t.expect_addition("bin/$toolset/debug/foo.bar")
+t.fail_test(find(t.read("bin/$toolset/debug/foo.bar"), "foobar") == -1)
+
+# Regression test. Make sure that if main target requested two times,
+# and build request differ only in incidental properties, the main target
+# if created only once. The bug was discovered by Kirill Lapshin.
+
+t.write("Jamfile", """ 
+# Make sure that incidental property does not
+# cause second creation of 'hello1.cpp'.
+exe a : dir//hello1.cpp ;
+exe b : dir//hello1.cpp/<hardcode-dll-paths>true ; 
+""")
+
+t.write("project-root.jam", "")
+
+t.write("dir/Jamfile", """ 
+import common ;
+make hello1.cpp : hello.cpp : common.copy ;
+
+""")
+
+t.write("dir/hello.cpp", """
+int main()
+{
+    return 1;
+}
+""")
+t.run_build_system("-d2")
+t.fail_test(t.stdout().count("common.copy") != 1)
+
+t.cleanup()


Property changes on: boost-jam/boost-build/branches/upstream/current/test/make_rule.py
___________________________________________________________________
Name: svn:executable
   + 

Added: boost-jam/boost-build/branches/upstream/current/test/module-actions/boost-build.jam
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/module-actions/boost-build.jam	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/module-actions/boost-build.jam	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1 @@
+boost-build . ;

Added: boost-jam/boost-build/branches/upstream/current/test/module-actions/bootstrap.jam
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/module-actions/bootstrap.jam	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/module-actions/bootstrap.jam	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,79 @@
+# Demonstration that module variables have the right effect in actions
+
+# Set a variable which says how to dump a file to stdout
+if $(NT)
+{ 
+    CATENATE = type ;
+}
+else
+{
+    CATENATE = cat ;
+}
+
+# invoke the given action rule `act' to build target from sources
+rule do-make ( target : sources * : act )
+{
+    DEPENDS $(target) : $(sources) ;
+    $(act) $(target) : $(sources) ;
+}
+
+# top-level version of do-make which causes target to be built by
+# default
+rule make ( target : sources * : act )
+{
+    DEPENDS all : $(target) ;
+    do-make $(target) : $(sources) : $(act) ;
+}
+
+X1 = X1-global ;
+X2 = X2-global ;
+X3 = X3-global ;
+
+module A
+{
+    X1 = X1-A ;
+    
+    rule act ( target )
+    {
+        NOTFILE $(target) ;
+        ALWAYS $(target) ;
+    }
+    
+    actions act
+    {
+        echo A.act $(<):  $(X1)  $(X2)  $(X3)
+    }
+    
+    make t1 : : A.act ;
+    make t2 : : A.act ;
+    make t3 : : A.act ;
+}
+
+module B
+{
+    X2 = X2-B ;
+    
+    actions act
+    {
+        echo B.act $(<):  $(X1)  $(X2)  $(X3)
+    }
+    
+    make t1 : : B.act ;
+    make t2 : : B.act ;
+    make t3 : : B.act ;
+}
+
+actions act
+{
+    echo act $(<):  $(X1)  $(X2)  $(X3)
+}
+
+make t1 : : act ;
+make t2 : : act ;
+make t3 : : act ;
+
+X1 on t1 = X1-t1 ;
+X2 on t2 = X2-t2 ;
+X3 on t3 = X3-t3 ;
+
+DEPENDS all : t1 t2 t3 ;

Added: boost-jam/boost-build/branches/upstream/current/test/module_actions.py
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/module_actions.py	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/module_actions.py	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,38 @@
+#!/usr/bin/python
+
+from BoostBuild import Tester, List
+import os
+import re
+
+spaces_re = re.compile("\ \ +")
+trailing_spaces_re = re.compile("\ +\n")
+
+t = Tester(pass_toolset=0)
+
+t.set_tree('module-actions')
+
+expected = r'''A.act t1:   X1-t1     
+B.act t1:   X1-t1   X2-B   
+act t1:   X1-t1   X2-global   X3-global 
+A.act t2:   X1-A   X2-t2   
+B.act t2:     X2-t2   
+act t2:   X1-global   X2-t2   X3-global 
+A.act t3:   X1-A     X3-t3 
+B.act t3:     X2-B   X3-t3 
+act t3:   X1-global   X2-global   X3-t3 
+'''
+
+# On Unixes, call to 'echo 1     2      3' produces '1 2 3' (note spacing)
+# Accomodate for that fact.
+if os.name != 'nt':
+    expected = re.sub(spaces_re, " ", expected)
+    expected = re.sub(trailing_spaces_re, "\n", expected)    
+
+# We expect t5 and t7's output to be dumped to stdout
+t.run_build_system(
+    stdout = expected
+)
+
+t.expect_nothing_more()
+t.cleanup()
+

Added: boost-jam/boost-build/branches/upstream/current/test/ndebug.py
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/ndebug.py	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/ndebug.py	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,47 @@
+#!/usr/bin/python
+
+#  Copyright (C) Vladimir Prus 2003. Permission to copy, use, modify, sell and
+#  distribute this software is granted provided this copyright notice appears in
+#  all copies. This software is provided "as is" without express or implied
+#  warranty, and with no claim as to its suitability for any purpose.
+
+#  Test that building with optimization brings NDEBUG define, and, more
+#  importantly, that dependency targets are built with NDEBUG as well,
+#  even if they are not directly requested.
+
+
+from BoostBuild import Tester, List
+
+
+t = Tester()
+
+t.write("project-root.jam", "")
+t.write("Jamfile", """
+exe hello : hello.cpp lib//lib1 ;
+""")
+t.write("hello.cpp", """
+#ifdef NDEBUG
+void foo();
+int main()
+{
+    foo();
+    return 0;
+}
+#endif
+""")
+t.write("lib/Jamfile", """
+lib lib1 : lib1.cpp ;        
+""")
+t.write("lib/lib1.cpp", """
+#ifdef NDEBUG
+void foo() {}
+#endif
+""")
+
+# 'release' builds should get NDEBUG define
+# use static linking to avoid messing with
+# imports/exports on windows.
+t.run_build_system("link=static release")
+
+
+t.cleanup()


Property changes on: boost-jam/boost-build/branches/upstream/current/test/ndebug.py
___________________________________________________________________
Name: svn:executable
   + 

Added: boost-jam/boost-build/branches/upstream/current/test/no_type.py
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/no_type.py	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/no_type.py	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,18 @@
+#!/usr/bin/python
+
+# Test that we cannot specify targets of unknown type as sources.
+# This is based on the fact that Unix 'ar' will happily consume
+# just about anything.
+
+from BoostBuild import Tester
+t = Tester()
+
+t.write("project-root.jam", "import gcc ;")
+t.write("Jamfile", """
+static-lib a : a.foo ;
+""")
+t.write("a.foo", "")
+
+t.run_build_system(status=1)
+
+t.cleanup()


Property changes on: boost-jam/boost-build/branches/upstream/current/test/no_type.py
___________________________________________________________________
Name: svn:executable
   + 

Added: boost-jam/boost-build/branches/upstream/current/test/ordered_properties.py
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/ordered_properties.py	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/ordered_properties.py	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,46 @@
+#!/usr/bin/python
+
+#  Copyright (C) Vladimir Prus 2004. Permission to copy, use, modify, sell and
+#  distribute this software is granted provided this copyright notice appears in
+#  all copies. This software is provided "as is" without express or implied
+#  warranty, and with no claim as to its suitability for any purpose.
+
+#  This file is template for Boost.Build tests. It creates a simple
+#  project that builds one exe from one source, and checks that the exe
+#  is really created.
+from BoostBuild import Tester, List
+
+# This checks that Boost.Build does not reorder <include> properties
+# lexicographically.
+t = Tester()
+
+t.write("a.cpp", """ 
+#include <a.h>
+
+int main()
+{
+   foo();
+   return 0;
+}
+
+""")
+
+t.write("Jamfile", """ 
+exe a : a.cpp : <include>d2 <include>d1 ; 
+""")
+
+t.write("project-root.jam", """ 
+""")
+
+t.write("d1/a.h", """ 
+""")
+
+t.write("d2/a.h", """ 
+inline void foo() {}
+
+""")
+
+t.run_build_system()
+t.expect_addition("bin/$toolset/debug/a.exe")
+
+t.cleanup()


Property changes on: boost-jam/boost-build/branches/upstream/current/test/ordered_properties.py
___________________________________________________________________
Name: svn:executable
   + 

Added: boost-jam/boost-build/branches/upstream/current/test/path_features.py
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/path_features.py	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/path_features.py	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,78 @@
+#!/usr/bin/python
+
+from BoostBuild import Tester
+t = Tester()
+
+t.write("project-root.jam", "import gcc ;")
+t.write("Jamfile", "lib a : a.cpp : <include>. ;")
+t.write("a.cpp", """
+#include <a.h>
+void
+# ifdef _WIN32
+__declspec(dllexport)
+# endif 
+foo() {}
+""")
+t.write("a.h", "//empty file\n")
+
+t.write("d/Jamfile", "exe b : b.cpp ..//a ; ")
+t.write("d/b.cpp", """
+    void foo();
+    int main() { foo(); }
+""")
+
+t.run_build_system(subdir="d")
+
+# Now test the path features with condition work as well
+t.write("Jamfile", "lib a : a.cpp : <variant>debug:<include>.  ;")
+t.rm("bin")
+t.run_build_system(subdir="d")
+
+# Test path features with condtion in usage requirements
+t.write("Jamfile", "lib a : a.cpp : <include>. : : <variant>debug:<include>. ;")
+t.write("d/b.cpp", """
+#include <a.h>
+void foo();
+int main() { foo(); }
+""")
+t.rm("d/bin")
+t.run_build_system(subdir="d")
+
+# Test that absolute paths inside requirements are ok. The problem
+# appear only when building targets in subprojects.
+t.write("project-root.jam", "")
+t.write("Jamfile", "build-project x ; ")
+t.write("x/Jamfile", """
+local pwd = [ PWD ] ;
+project : requirements <include>$(pwd)/x/include ;
+exe m : m.cpp : <include>$(pwd)/x/include2 ;
+""")
+t.write("x/m.cpp", """
+#include <h1.hpp>
+#include <h2.hpp>
+
+int main() {}
+""")
+t.write("x/include/h1.hpp", "\n")
+t.write("x/include2/h2.hpp", "\n")
+
+t.run_build_system()
+t.expect_addition("x/bin/$toolset/debug/m.exe")
+
+# Test that "&&" in path features is handled correctly.
+t.rm("bin")
+t.write("Jamfile", "build-project sub ;")
+t.write("sub/Jamfile", """
+exe a : a.cpp : <include>../h1&&../h2 ;
+""")
+t.write("sub/a.cpp", """
+#include <header.h>
+int main() { return OK; }
+""")
+t.write("h2/header.h", """
+const int OK = 0;
+""")
+t.run_build_system()
+t.expect_addition("sub/bin/$toolset/debug/a.exe")        
+
+t.cleanup()


Property changes on: boost-jam/boost-build/branches/upstream/current/test/path_features.py
___________________________________________________________________
Name: svn:executable
   + 

Added: boost-jam/boost-build/branches/upstream/current/test/prebuilt/Jamfile
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/prebuilt/Jamfile	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/prebuilt/Jamfile	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,9 @@
+
+project test
+    : requirements <variant>release:<define>RELEASE
+    ;
+
+use-project /ext : ext ;
+
+exe hello : hello.cpp /ext//a ;
+

Added: boost-jam/boost-build/branches/upstream/current/test/prebuilt/ext/Jamfile
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/prebuilt/ext/Jamfile	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/prebuilt/ext/Jamfile	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,6 @@
+
+project ext 
+    : requirements <variant>release:<define>RELEASE
+    ;
+
+lib a : a.cpp ;
\ No newline at end of file

Added: boost-jam/boost-build/branches/upstream/current/test/prebuilt/ext/Jamfile2
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/prebuilt/ext/Jamfile2	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/prebuilt/ext/Jamfile2	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,34 @@
+
+import modules ;
+
+local dll-suffix = so ;
+if [ modules.peek : OS ] in CYGWIN NT
+{
+   if $toolset = gcc
+   {
+      dll-suffix = dll ;
+   }
+   else
+   {
+      dll-suffix = lib ;
+   }
+}
+if $toolset = darwin
+{
+   dll-suffix = dylib ;
+}
+
+project ext ;
+
+lib a : 
+    : <file>bin/$toolset/debug/a.$(dll-suffix) <variant>debug
+    :
+    : <include>debug
+    ;
+    
+lib a :
+    : <file>bin/$toolset/release/a.$(dll-suffix) <variant>release
+    :
+    : <include>release
+    ;
+    

Added: boost-jam/boost-build/branches/upstream/current/test/prebuilt/ext/Jamfile3
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/prebuilt/ext/Jamfile3	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/prebuilt/ext/Jamfile3	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,43 @@
+
+# This Jamfile is the same as Jamfile2, except that
+# it tries to access prebuilt targets using absolute
+# paths. It used to be broken on Windows.
+
+import modules ;
+
+local dll-suffix = so ;
+if [ modules.peek : OS ] in CYGWIN NT
+{
+   if $toolset = gcc
+   {
+      dll-suffix = dll ;
+   }
+   else
+   {
+      dll-suffix = lib ;
+   }
+}
+if $toolset = darwin
+{
+   dll-suffix = dylib ;
+}
+
+
+
+project ext ;
+
+# Assumed bjam was invoked from the project root
+local pwd = [ PWD ] ;
+
+lib a : 
+    : <file>$(pwd)/ext/bin/$toolset/debug/a.$(dll-suffix) <variant>debug
+    :
+    : <include>debug
+    ;
+    
+lib a :
+    : <file>$(pwd)/ext/bin/$toolset/release/a.$(dll-suffix) <variant>release
+    :
+    : <include>release
+    ;
+    

Added: boost-jam/boost-build/branches/upstream/current/test/prebuilt/ext/a.cpp
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/prebuilt/ext/a.cpp	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/prebuilt/ext/a.cpp	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,17 @@
+//  Copyright (c) 2003 Vladimir Prus
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  http://www.boost.org
+// 
+
+#ifdef _WIN32
+__declspec(dllexport)
+#endif
+#ifdef RELEASE
+void release() {}
+#else
+void debug() {}
+#endif

Added: boost-jam/boost-build/branches/upstream/current/test/prebuilt/ext/debug/a.h
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/prebuilt/ext/debug/a.h	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/prebuilt/ext/debug/a.h	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,13 @@
+//  Copyright (c) 2003 Vladimir Prus
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  http://www.boost.org
+// 
+
+#ifdef _WIN32
+__declspec(dllimport)
+#endif
+void debug();

Added: boost-jam/boost-build/branches/upstream/current/test/prebuilt/ext/project-root.jam
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/prebuilt/ext/project-root.jam	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/prebuilt/ext/project-root.jam	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1 @@
+

Added: boost-jam/boost-build/branches/upstream/current/test/prebuilt/ext/release/a.h
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/prebuilt/ext/release/a.h	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/prebuilt/ext/release/a.h	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,13 @@
+//  Copyright (c) 2003 Vladimir Prus
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  http://www.boost.org
+// 
+
+#ifdef _WIN32
+__declspec(dllimport)
+#endif
+void release();

Added: boost-jam/boost-build/branches/upstream/current/test/prebuilt/hello.cpp
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/prebuilt/hello.cpp	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/prebuilt/hello.cpp	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,20 @@
+//  Copyright (c) 2003 Vladimir Prus
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  http://www.boost.org
+// 
+
+#include <a.h>
+
+int main()
+{
+    #ifdef RELEASE
+    release();
+    #else
+    debug();
+    #endif
+    return 0;
+}

Added: boost-jam/boost-build/branches/upstream/current/test/prebuilt/project-root.jam
===================================================================

Added: boost-jam/boost-build/branches/upstream/current/test/prebuilt.py
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/prebuilt.py	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/prebuilt.py	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,39 @@
+#!/usr/bin/python
+
+# Test that we can use already built sources
+
+from BoostBuild import Tester
+t = Tester()
+
+t.set_tree('prebuilt')
+
+t.expand_toolset("ext/project-root.jam")
+t.expand_toolset("project-root.jam")
+# First, build the external project
+t.run_build_system("debug release", subdir="ext")
+
+# Then pretend that we don't have the sources for the external project,
+# and can only use compiled binaries
+t.copy("ext/Jamfile2", "ext/Jamfile")
+t.expand_toolset("ext/Jamfile")
+
+# Now check that we can build the main project, and that
+# correct prebuilt file is picked, depending of variant.
+# This also checks that correct includes for prebuilt
+# libraries are used.
+
+t.run_build_system("debug release")
+t.expect_addition("bin/$toolset/debug/hello.exe")
+t.expect_addition("bin/$toolset/release/hello.exe")
+
+t.rm("bin")
+# Now test that prebuilt file specified by absolute name 
+# works too.
+t.copy("ext/Jamfile3", "ext/Jamfile")
+t.expand_toolset("ext/Jamfile")
+t.run_build_system("debug release")
+t.expect_addition("bin/$toolset/debug/hello.exe")
+t.expect_addition("bin/$toolset/release/hello.exe")
+
+
+t.cleanup()


Property changes on: boost-jam/boost-build/branches/upstream/current/test/prebuilt.py
___________________________________________________________________
Name: svn:executable
   + 

Added: boost-jam/boost-build/branches/upstream/current/test/print.py
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/print.py	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/print.py	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,45 @@
+#!/usr/bin/python
+
+from BoostBuild import Tester, List
+
+t = Tester()
+
+t.write("project-root.jam", "import gcc ;")
+t.write("Jamfile", """
+import print ;
+print.output foo ;
+print.text \\\"Something\\\" ;
+DEPENDS all : foo ;
+ALWAYS foo ;
+""")
+
+t.run_build_system()
+t.expect_content("foo", """\"Something\"
+""")
+
+t.write("Jamfile", """
+import print ;
+print.output foo ;
+print.text \\\"Somethingelse\\\" ;
+DEPENDS all : foo ;
+ALWAYS foo ;
+""")
+
+t.run_build_system()
+t.expect_content("foo", """\"Something\"
+\"Somethingelse\"
+""")
+
+t.write("Jamfile", """
+import print ;
+print.output foo ;
+print.text \\\"Different\\\" : true ;
+DEPENDS all : foo ;
+ALWAYS foo ;
+""")
+
+t.run_build_system()
+t.expect_content("foo", """\"Different\"
+""")
+
+t.cleanup()

Added: boost-jam/boost-build/branches/upstream/current/test/project-test1/Jamfile
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/project-test1/Jamfile	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/project-test1/Jamfile	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,5 @@
+project /boost-build-test-project-1
+    : requirements <threading>multi <include>/home/ghost/local/include ;
+
+build-project dir2 ;
+build-project dir ;

Added: boost-jam/boost-build/branches/upstream/current/test/project-test1/dir/Jamfile
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/project-test1/dir/Jamfile	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/project-test1/dir/Jamfile	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,5 @@
+
+project /boost-build-test-project-1/dir 
+    : source-location src 
+    : default-build release
+    ;
\ No newline at end of file

Added: boost-jam/boost-build/branches/upstream/current/test/project-test1/dir2/Jamfile
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/project-test1/dir2/Jamfile	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/project-test1/dir2/Jamfile	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,4 @@
+
+project /cool-library 
+    : requirements <include>/home/ghost/build/boost-cvs 
+    ;

Added: boost-jam/boost-build/branches/upstream/current/test/project-test1/dir2/project-root.jam
===================================================================

Added: boost-jam/boost-build/branches/upstream/current/test/project-test1/project-root.jam
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/project-test1/project-root.jam	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/project-test1/project-root.jam	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,2 @@
+
+import builtin ;
\ No newline at end of file

Added: boost-jam/boost-build/branches/upstream/current/test/project-test1/project-test1.jam
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/project-test1/project-test1.jam	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/project-test1/project-test1.jam	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,16 @@
+import project ;
+import targets ;
+import assert ;
+import project-roots ;
+
+project.load "." ;
+
+import standalone-project ;
+
+project-roots.print ;
+
+assert.result standalone-project : project.find /teeest : "." ;
+
+NOTFILE all ;
+
+

Added: boost-jam/boost-build/branches/upstream/current/test/project-test1/readme.txt
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/project-test1/readme.txt	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/project-test1/readme.txt	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,3 @@
+
+This tests for basic project handling -- declaring subprojects, finding
+parent projects and project roots and for working project-ids.
\ No newline at end of file

Added: boost-jam/boost-build/branches/upstream/current/test/project-test1/standalone-project.jam
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/project-test1/standalone-project.jam	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/project-test1/standalone-project.jam	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,8 @@
+
+import project ;
+
+# Convert ourself into a real project.
+project.initialize $(__name__) ;
+
+# Now we can identify ourselfs.
+project /teeest ;
\ No newline at end of file

Added: boost-jam/boost-build/branches/upstream/current/test/project-test1.jam
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/project-test1.jam	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/project-test1.jam	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,12 @@
+import project ;
+import targets ;
+import assert ;
+
+project.load project-test1 ;
+import project-roots ;
+
+project-roots.print ;
+
+NOTFILE all ;
+
+

Added: boost-jam/boost-build/branches/upstream/current/test/project-test3/Jamfile
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/project-test3/Jamfile	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/project-test3/Jamfile	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,9 @@
+
+use-project /lib2 : lib2 ;
+use-project /lib3 : lib3 ;
+
+make a.exe : a.obj lib//b.obj /lib2//c.obj lib2//d.obj lib2/helper//e.obj /lib3//f.obj : yfc-link ;
+make a.obj : a.cpp : yfc-compile ; 
+
+build-project lib2 ;
+build-project lib ;
\ No newline at end of file

Added: boost-jam/boost-build/branches/upstream/current/test/project-test3/a.cpp
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/project-test3/a.cpp	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/project-test3/a.cpp	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,8 @@
+//  Copyright (c) 2003 Vladimir Prus
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  http://www.boost.org
+// 

Added: boost-jam/boost-build/branches/upstream/current/test/project-test3/lib/Jamfile
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/project-test3/lib/Jamfile	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/project-test3/lib/Jamfile	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,5 @@
+
+use-project /lib2 : ../lib2 ;
+
+make b.obj : b.cpp : yfc-compile ;
+make m.exe : b.obj /lib2//c.obj : yfc-link ;
\ No newline at end of file

Added: boost-jam/boost-build/branches/upstream/current/test/project-test3/lib/b.cpp
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/project-test3/lib/b.cpp	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/project-test3/lib/b.cpp	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,8 @@
+//  Copyright (c) 2003 Vladimir Prus
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  http://www.boost.org
+// 

Added: boost-jam/boost-build/branches/upstream/current/test/project-test3/lib2/Jamfile
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/project-test3/lib2/Jamfile	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/project-test3/lib2/Jamfile	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,7 @@
+
+project lib2 ;
+use-project /lib2/helper : helper ;
+
+make c.obj : c.cpp : yfc-compile ;
+make d.obj : d.cpp : yfc-compile ;
+make l.exe : c.obj ..//a.obj : yfc-link ;

Added: boost-jam/boost-build/branches/upstream/current/test/project-test3/lib2/c.cpp
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/project-test3/lib2/c.cpp	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/project-test3/lib2/c.cpp	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,8 @@
+//  Copyright (c) 2003 Vladimir Prus
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  http://www.boost.org
+// 

Added: boost-jam/boost-build/branches/upstream/current/test/project-test3/lib2/d.cpp
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/project-test3/lib2/d.cpp	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/project-test3/lib2/d.cpp	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,8 @@
+//  Copyright (c) 2003 Vladimir Prus
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  http://www.boost.org
+// 

Added: boost-jam/boost-build/branches/upstream/current/test/project-test3/lib2/helper/Jamfile
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/project-test3/lib2/helper/Jamfile	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/project-test3/lib2/helper/Jamfile	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,5 @@
+
+project lib2/helper ;
+
+make e.obj : e.cpp : yfc-compile ;
+

Added: boost-jam/boost-build/branches/upstream/current/test/project-test3/lib2/helper/e.cpp
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/project-test3/lib2/helper/e.cpp	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/project-test3/lib2/helper/e.cpp	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,8 @@
+//  Copyright (c) 2003 Vladimir Prus
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  http://www.boost.org
+// 

Added: boost-jam/boost-build/branches/upstream/current/test/project-test3/lib3/Jamfile
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/project-test3/lib3/Jamfile	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/project-test3/lib3/Jamfile	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,21 @@
+
+# This project-root.jam also serves the role of Jamfile
+project lib3 ;
+
+use-project /lib2/helper : ../lib2/helper ;
+
+import property ;
+
+rule mfc-compile ( target : sources * : property-set * )
+{
+    PROPERTIES on $(target) = [ 
+      property.as-path [ property.remove incidental : $(property-set) ] ] ;      
+}
+
+actions mfc-compile
+{
+    echo $(PROPERTIES) > $(<)
+    echo $(>) >> $(<)
+}
+
+make f.obj : f.cpp /lib2/helper//e.obj : mfc-compile ;

Added: boost-jam/boost-build/branches/upstream/current/test/project-test3/lib3/f.cpp
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/project-test3/lib3/f.cpp	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/project-test3/lib3/f.cpp	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,8 @@
+//  Copyright (c) 2003 Vladimir Prus
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  http://www.boost.org
+// 

Added: boost-jam/boost-build/branches/upstream/current/test/project-test3/lib3/project-root.jam
===================================================================

Added: boost-jam/boost-build/branches/upstream/current/test/project-test3/project-root.jam
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/project-test3/project-root.jam	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/project-test3/project-root.jam	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,30 @@
+
+import gcc ;
+import property ;
+
+rule yfc-compile ( target : sources * : property-set * )
+{
+    PROPERTIES on $(target) = [ 
+      property.as-path [ property.remove incidental : $(property-set) ] ] ;
+}
+
+actions yfc-compile
+{
+    echo $(PROPERTIES) > $(<)
+    echo $(>) >> $(<)
+}
+
+rule yfc-link ( target : sources * : property-set * )
+{
+    PROPERTIES on $(target) = [ 
+      property.as-path [ property.remove incidental : $(property-set) ] ] ;      
+}
+
+actions yfc-link
+{
+    echo $(PROPERTIES) > $(<)
+    echo $(>) >> $(<)
+}
+
+
+IMPORT $(__name__) : yfc-compile yfc-link : : yfc-compile yfc-link ;

Added: boost-jam/boost-build/branches/upstream/current/test/project-test3/readme.txt
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/project-test3/readme.txt	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/project-test3/readme.txt	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,3 @@
+
+This test checks that we have minimally working 'make' rule and that we can use target from
+different project with different project roots.

Added: boost-jam/boost-build/branches/upstream/current/test/project-test4/Jamfile
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/project-test4/Jamfile	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/project-test4/Jamfile	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,6 @@
+
+project test : requirements <include>everything <threading>single ;
+
+make a.exe : a.obj lib//b.obj/<optimization>speed : yfc-link ;
+make b.exe : a.obj : yfc-link : <define>MACROS ;
+make a.obj : a.cpp : yfc-compile ;

Added: boost-jam/boost-build/branches/upstream/current/test/project-test4/Jamfile3
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/project-test4/Jamfile3	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/project-test4/Jamfile3	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,5 @@
+
+make a.exe : a.obj lib//b.obj/<optimization>on a_gcc.obj : yfc-link : <toolset>gcc ;
+make a.exe : a.obj lib//b.obj/<optimization>on : yfc-link : <threading>multi ;
+make a.obj : a.cpp : yfc-compile ;
+make a_gcc.obj : a_gcc.cpp : yfc-compile ;

Added: boost-jam/boost-build/branches/upstream/current/test/project-test4/Jamfile4
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/project-test4/Jamfile4	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/project-test4/Jamfile4	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,4 @@
+
+project test : requirements <include>everything <threading>single ;
+
+build-project lib2 ;

Added: boost-jam/boost-build/branches/upstream/current/test/project-test4/Jamfile5
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/project-test4/Jamfile5	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/project-test4/Jamfile5	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,6 @@
+
+project test : requirements <include>everything <threading>single ;
+
+make a.exe : a.obj lib//b.obj/<variant>release : yfc-link ;
+make b.exe : a.obj : yfc-link : <define>MACROS ;
+make a.obj : a.cpp : yfc-compile ;

Added: boost-jam/boost-build/branches/upstream/current/test/project-test4/a.cpp
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/project-test4/a.cpp	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/project-test4/a.cpp	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,8 @@
+//  Copyright (c) 2003 Vladimir Prus
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  http://www.boost.org
+// 

Added: boost-jam/boost-build/branches/upstream/current/test/project-test4/a_gcc.cpp
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/project-test4/a_gcc.cpp	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/project-test4/a_gcc.cpp	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,8 @@
+//  Copyright (c) 2003 Vladimir Prus
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  http://www.boost.org
+// 

Added: boost-jam/boost-build/branches/upstream/current/test/project-test4/lib/Jamfile
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/project-test4/lib/Jamfile	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/project-test4/lib/Jamfile	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,2 @@
+
+make b.obj : b.cpp : yfc-compile ;

Added: boost-jam/boost-build/branches/upstream/current/test/project-test4/lib/Jamfile1
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/project-test4/lib/Jamfile1	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/project-test4/lib/Jamfile1	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,2 @@
+
+make b.obj : b.cpp : yfc-compile ;

Added: boost-jam/boost-build/branches/upstream/current/test/project-test4/lib/Jamfile2
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/project-test4/lib/Jamfile2	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/project-test4/lib/Jamfile2	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,4 @@
+
+project lib : requirements <threading>multi ;
+
+make b.obj : b.cpp : yfc-compile ;

Added: boost-jam/boost-build/branches/upstream/current/test/project-test4/lib/Jamfile3
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/project-test4/lib/Jamfile3	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/project-test4/lib/Jamfile3	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,2 @@
+
+make b.obj : b.cpp : yfc-compile : <rtti>off ;

Added: boost-jam/boost-build/branches/upstream/current/test/project-test4/lib/b.cpp
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/project-test4/lib/b.cpp	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/project-test4/lib/b.cpp	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,8 @@
+//  Copyright (c) 2003 Vladimir Prus
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  http://www.boost.org
+// 

Added: boost-jam/boost-build/branches/upstream/current/test/project-test4/lib2/Jamfile
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/project-test4/lib2/Jamfile	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/project-test4/lib2/Jamfile	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,4 @@
+
+project
+    : requirements <rtti>off
+    ;

Added: boost-jam/boost-build/branches/upstream/current/test/project-test4/lib2/Jamfile2
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/project-test4/lib2/Jamfile2	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/project-test4/lib2/Jamfile2	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,4 @@
+
+project mylib
+    : requirements <rtti>off
+    ; 

Added: boost-jam/boost-build/branches/upstream/current/test/project-test4/project-root.jam
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/project-test4/project-root.jam	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/project-test4/project-root.jam	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,30 @@
+
+import gcc ;
+import property ;
+
+rule yfc-compile ( target : sources * : property-set * )
+{
+    PROPERTIES on $(target) = [ 
+      property.as-path [ property.remove incidental : $(property-set) ] ] ;      
+}
+
+actions yfc-compile
+{
+    echo $(PROPERTIES) > $(<)
+    echo $(>) >> $(<)
+}
+
+rule yfc-link ( target : sources * : property-set * )
+{
+    PROPERTIES on $(target) = [ 
+      property.as-path [ property.remove incidental : $(property-set) ] ] ;
+}
+
+actions yfc-link
+{
+    echo $(PROPERTIES) > $(<)
+    echo $(>) >> $(<)
+}
+
+
+IMPORT $(__name__) : yfc-compile yfc-link : : yfc-compile yfc-link ;

Added: boost-jam/boost-build/branches/upstream/current/test/project-test4/readme.txt
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/project-test4/readme.txt	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/project-test4/readme.txt	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,2 @@
+
+This test checks for correct properties of generated and used targets.
\ No newline at end of file

Added: boost-jam/boost-build/branches/upstream/current/test/project_dependencies.py
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/project_dependencies.py	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/project_dependencies.py	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,47 @@
+#!/usr/bin/python
+
+# Test that we can specify a dependency property
+# in project requirements, and that it won't
+# cause every main target in the project to
+# be generated in it's own subdirectory.
+
+# The whole test is somewhat moot now. 
+
+from BoostBuild import Tester, List
+
+t = Tester()
+
+t.write("project-root.jam", "import gcc ;")
+t.write("Jamfile", "build-project src ;")
+t.write("lib/Jamfile", "lib lib1 : lib1.cpp ;")
+t.write("lib/lib1.cpp", """
+#ifdef _WIN32
+__declspec(dllexport)
+#endif
+void foo() {}\n
+""")
+t.write("src/Jamfile", """
+project
+    : requirements <library>../lib//lib1
+    ;
+    
+exe a : a.cpp ;
+exe b : b.cpp ;    
+""")
+t.write("src/a.cpp", """
+#ifdef _WIN32
+__declspec(dllimport)
+#endif
+void foo();
+int main() { foo(); return 0; }
+""")
+t.copy("src/a.cpp", "src/b.cpp")
+
+t.run_build_system()
+
+# Test that there's no "main-target-a" part.
+# t.expect_addition("src/bin/$toolset/debug/a.exe")
+# t.expect_addition("src/bin/$toolset/debug/b.exe")
+
+
+t.cleanup()


Property changes on: boost-jam/boost-build/branches/upstream/current/test/project_dependencies.py
___________________________________________________________________
Name: svn:executable
   + 

Added: boost-jam/boost-build/branches/upstream/current/test/project_root.py
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/project_root.py	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/project_root.py	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,23 @@
+#!/usr/bin/python
+
+#  Copyright (C) Vladimir Prus 2003. Permission to copy, use, modify, sell and
+#  distribute this software is granted provided this copyright notice appears in
+#  all copies. This software is provided "as is" without express or implied
+#  warranty, and with no claim as to its suitability for any purpose.
+
+#  Test that we can access project-root attributes from Jamfiles.
+from BoostBuild import Tester, List
+
+# Create a temporary working directory
+t = Tester()
+
+t.write("Jamfile", """
+local l = [ project-root get-location ] ;
+ECHO XXX $(l) ;
+""")
+
+t.write("project-root.jam", "")
+        
+t.run_build_system(stdout="XXX .\n")
+
+t.cleanup()


Property changes on: boost-jam/boost-build/branches/upstream/current/test/project_root.py
___________________________________________________________________
Name: svn:executable
   + 

Added: boost-jam/boost-build/branches/upstream/current/test/project_root_constants.py
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/project_root_constants.py	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/project_root_constants.py	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,43 @@
+#!/usr/bin/python
+
+#  Copyright (C) Vladimir Prus 2003. Permission to copy, use, modify, sell and
+#  distribute this software is granted provided this copyright notice appears in
+#  all copies. This software is provided "as is" without express or implied
+#  warranty, and with no claim as to its suitability for any purpose.
+
+from BoostBuild import Tester, List
+from string import find
+
+# Create a temporary working directory
+t = Tester()
+
+# Create the needed files
+t.write("project-root.jam", """
+constant FOO : foobar ;
+ECHO $(FOO) ;
+""")
+t.write("Jamfile", """
+""")
+
+t.run_build_system()
+t.fail_test(find(t.stdout(), "foobar") == -1)
+
+# Regression test: when absolute paths were passed to path-constant rule,
+# Boost.Build failed to recognize path as absolute and prepended current dir.
+t.write("project-root.jam", """
+import path ;
+local here = [ path.native [ path.pwd ] ] ;
+path-constant HERE : $(here) ;
+if $(HERE) != $(here) 
+{
+    ECHO "PWD           =" $(here) ;
+    ECHO "path constant =" $(HERE) ;
+    EXIT ;
+}
+""")
+t.write("Jamfile", "")
+
+t.run_build_system()
+
+
+t.cleanup()


Property changes on: boost-jam/boost-build/branches/upstream/current/test/project_root_constants.py
___________________________________________________________________
Name: svn:executable
   + 

Added: boost-jam/boost-build/branches/upstream/current/test/project_test1.py
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/project_test1.py	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/project_test1.py	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,74 @@
+#!/usr/bin/python
+
+from BoostBuild import Tester
+import os
+
+t = Tester("--build-system=project-test1", boost_build_path='', pass_toolset=0)
+
+# This test does no modifications, so run in in the invocation dir
+
+os.chdir(t.original_workdir)
+
+
+expected_output1="""Project Roots:
+
+"""
+
+expected_output2="""'%(root-dir-prefix)sdir2':
+
+  Module for project-root is 'project-root<%(root-dir-prefix)sdir2>'
+
+Projects:
+
+'/cool-library':
+
+* Parent project: (none)
+* Requirements: <include>/home/ghost/build/boost-cvs
+* Default build:
+* Source location: %(root-dir-prefix)sdir2
+* Projects to build:
+
+"""
+
+expected_output3="""'%(root-dir)s':
+
+  Module for project-root is 'project-root<%(root-dir)s>'
+
+Projects:
+
+'/boost-build-test-project-1':
+
+* Parent project: (none)
+* Requirements: <include>/home/ghost/local/include <threading>multi
+* Default build:
+* Source location: %(root-dir)s
+* Projects to build: dir dir2
+
+'/boost-build-test-project-1/dir':
+
+* Parent project: %(root-dir)s
+* Requirements: <include>/home/ghost/local/include <threading>multi
+* Default build: <variant>release
+* Source location: %(root-dir-prefix)sdir/src
+* Projects to build:
+
+"""
+
+# Test that correct project structure is created when jam is invoked
+# outside of the source tree.
+expected = (expected_output1 + expected_output2 + expected_output3) % \
+    {"root-dir": "project-test1",
+     "root-dir-prefix": "project-test1/" }
+
+t.run_build_system(stdout=expected)
+
+# Test that correct project structure is created when jam is invoked
+# at the top of the source tree.
+expected = (expected_output1 + expected_output3 + expected_output2) % \
+    {"root-dir": ".",
+     "root-dir-prefix": "" }
+
+os.chdir("project-test1")
+t.run_build_system(stdout=expected)
+
+t.cleanup()

Added: boost-jam/boost-build/branches/upstream/current/test/project_test3.py
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/project_test3.py	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/project_test3.py	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,135 @@
+#!/usr/bin/python
+
+from BoostBuild import Tester, List
+import os
+from string import strip
+
+t = Tester(translate_suffixes=0)
+
+# First check some startup
+t.set_tree("project-test3")
+os.remove("project-root.jam")
+t.run_build_system(status=1, stdout=
+"""Failed to find the project root for directory '.'.
+Did not find a project-root.jam file there or in any of its parent directories.
+Please consult the documentation at 'http://www.boost.org'.
+""")
+
+t.set_tree("project-test3")
+t.run_build_system()
+
+t.expect_addition("bin/$toolset/debug/a.obj")
+t.expect_content("bin/$toolset/debug/a.obj",
+"""$toolset/debug
+a.cpp
+""")
+
+t.expect_addition("bin/$toolset/debug/a.exe")
+t.expect_content("bin/$toolset/debug/a.exe",
+"$toolset/debug\n" +
+"bin/$toolset/debug/a.obj lib/bin/$toolset/debug/b.obj " +
+"lib2/bin/$toolset/debug/c.obj lib2/bin/$toolset/debug/d.obj " +
+"lib2/helper/bin/$toolset/debug/e.obj " +
+"lib3/bin/$toolset/debug/f.obj\n"
+)
+
+t.expect_addition("lib/bin/$toolset/debug/b.obj")
+t.expect_content("lib/bin/$toolset/debug/b.obj",
+"""$toolset/debug
+lib/b.cpp
+""")
+
+t.expect_addition("lib/bin/$toolset/debug/m.exe")
+t.expect_content("lib/bin/$toolset/debug/m.exe",
+"""$toolset/debug
+lib/bin/$toolset/debug/b.obj lib2/bin/$toolset/debug/c.obj
+""")
+
+t.expect_addition("lib2/bin/$toolset/debug/c.obj")
+t.expect_content("lib2/bin/$toolset/debug/c.obj",
+"""$toolset/debug
+lib2/c.cpp
+""")
+
+t.expect_addition("lib2/bin/$toolset/debug/d.obj")
+t.expect_content("lib2/bin/$toolset/debug/d.obj",
+"""$toolset/debug
+lib2/d.cpp
+""")
+
+t.expect_addition("lib2/bin/$toolset/debug/l.exe")
+t.expect_content("lib2/bin/$toolset/debug/l.exe",
+"""$toolset/debug
+lib2/bin/$toolset/debug/c.obj bin/$toolset/debug/a.obj
+""")
+
+t.expect_addition("lib2/helper/bin/$toolset/debug/e.obj")
+t.expect_content("lib2/helper/bin/$toolset/debug/e.obj",
+"""$toolset/debug
+lib2/helper/e.cpp
+""")
+
+t.expect_addition("lib3/bin/$toolset/debug/f.obj")
+t.expect_content("lib3/bin/$toolset/debug/f.obj",
+"""$toolset/debug
+lib3/f.cpp lib2/helper/bin/$toolset/debug/e.obj
+""")
+                 
+
+t.touch("a.cpp")
+t.run_build_system()
+t.expect_touch(["bin/$toolset/debug/a.obj",
+                "bin/$toolset/debug/a.exe",
+                "lib2/bin/$toolset/debug/l.exe"])
+
+
+t.run_build_system(extra_args="release optimization=off,speed")
+t.expect_addition(["bin/$toolset/release/a.exe", 
+                  "bin/$toolset/release/a.obj", 
+                  "bin/$toolset/release/optimization-off/a.exe", 
+                  "bin/$toolset/release/optimization-off/a.obj"])
+
+t.run_build_system(extra_args='clean')
+t.expect_removal(["bin/$toolset/debug/a.obj",
+                 "bin/$toolset/debug/a.exe",
+                 "lib/bin/$toolset/debug/b.obj",
+                 "lib/bin/$toolset/debug/m.exe",
+                 "lib2/bin/$toolset/debug/c.obj",
+                 "lib2/bin/$toolset/debug/d.obj",
+                 "lib2/bin/$toolset/debug/l.exe",
+                 "lib3/bin/$toolset/debug/f.obj",
+                  ])
+
+# Now test target ids in command line
+t.set_tree("project-test3")
+t.run_build_system("lib//b.obj")
+t.expect_addition("lib/bin/$toolset/debug/b.obj")
+t.expect_nothing_more()
+
+t.run_build_system("clean lib//b.obj")
+t.expect_removal("lib/bin/$toolset/debug/b.obj")
+t.expect_nothing_more()
+
+t.run_build_system("lib//b.obj")
+t.expect_addition("lib/bin/$toolset/debug/b.obj")
+t.expect_nothing_more()
+
+
+t.run_build_system("release lib2/helper//e.obj /lib3//f.obj")
+t.expect_addition("lib2/helper/bin/$toolset/release/e.obj")
+t.expect_addition("lib3/bin/$toolset/release/f.obj")
+t.expect_nothing_more()
+
+# Test project ids in command line work as well
+t.set_tree("project-test3")
+t.run_build_system("/lib2")
+t.expect_addition("lib2/bin/$toolset/debug/" * List("c.obj d.obj l.exe"))
+t.expect_addition("bin/$toolset/debug/a.obj")
+t.expect_nothing_more()
+
+
+t.run_build_system("lib")
+t.expect_addition("lib/bin/$toolset/debug/" * List("b.obj m.exe"))
+t.expect_nothing_more()
+
+t.cleanup()


Property changes on: boost-jam/boost-build/branches/upstream/current/test/project_test3.py
___________________________________________________________________
Name: svn:executable
   + 

Added: boost-jam/boost-build/branches/upstream/current/test/project_test4.py
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/project_test4.py	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/project_test4.py	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,63 @@
+#!/usr/bin/python
+
+from BoostBuild import Tester
+import os
+from string import strip, find
+
+t = Tester(translate_suffixes=0)
+
+
+t.set_tree("project-test4")
+
+t.run_build_system()
+
+t.expect_addition("bin/$toolset/debug/a.obj")
+t.expect_content("bin/$toolset/debug/a.obj",
+"""$toolset/debug/include-everything
+a.cpp
+""")
+
+t.expect_addition("bin/$toolset/debug/a.exe")
+t.expect_content("bin/$toolset/debug/a.exe",
+"$toolset/debug/include-everything\n" +
+"bin/$toolset/debug/a.obj lib/bin/$toolset/debug/optimization-speed/b.obj\n"
+)
+
+t.expect_addition("lib/bin/$toolset/debug/optimization-speed/b.obj")
+t.expect_content("lib/bin/$toolset/debug/optimization-speed/b.obj",
+"""$toolset/debug/include-everything/optimization-speed
+lib/b.cpp
+""")
+
+t.expect_addition("bin/$toolset/debug/b.exe")
+t.expect_content("bin/$toolset/debug/b.exe",
+"$toolset/debug/define-MACROS/include-everything\n" +
+"bin/$toolset/debug/a.obj\n"
+)
+
+
+t.copy("lib/Jamfile3", "lib/Jamfile")
+
+# Link-compatibility check for rtti is disabled...
+#t.run_build_system(status=None)
+#t.fail_test(find(t.stdout(),
+#"""warning: targets produced from b.obj are link incompatible
+#warning: with main target a.exe""") !=-0)
+
+# Test that if we specified composite property in target reference,
+# everything works OK.
+
+t.copy("lib/Jamfile1", "lib/Jamfile")
+t.copy("Jamfile5", "Jamfile")
+
+t.run_build_system()
+
+t.expect_addition("lib/bin/$toolset/release/b.obj")
+
+t.expect_content("bin/$toolset/debug/a.exe",
+"$toolset/debug/include-everything\n" +
+"bin/$toolset/debug/a.obj lib/bin/$toolset/release/b.obj\n"
+)
+
+
+t.cleanup()


Property changes on: boost-jam/boost-build/branches/upstream/current/test/project_test4.py
___________________________________________________________________
Name: svn:executable
   + 

Added: boost-jam/boost-build/branches/upstream/current/test/property_expansion.py
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/property_expansion.py	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/property_expansion.py	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,35 @@
+#!/usr/bin/python
+
+#  Copyright (C) Vladimir Prus 2003. Permission to copy, use, modify, sell and
+#  distribute this software is granted provided this copyright notice appears in
+#  all copies. This software is provided "as is" without express or implied
+#  warranty, and with no claim as to its suitability for any purpose.
+
+from BoostBuild import Tester, List
+
+# Test that free property inside 
+t = Tester()
+
+t.write("project-root.jam", "")
+t.write("Jamfile", """
+project ;
+
+variant debug-AA : debug : <define>AA ;
+
+alias all : hello ;
+exe hello : hello.cpp ;
+explicit hello ;
+""")
+t.write("hello.cpp", """
+#ifdef AA
+int main()
+{
+    return 0;
+}
+#endif
+""")
+
+t.run_build_system("debug-AA")
+
+
+t.cleanup()


Property changes on: boost-jam/boost-build/branches/upstream/current/test/property_expansion.py
___________________________________________________________________
Name: svn:executable
   + 

Added: boost-jam/boost-build/branches/upstream/current/test/railsys/libx/include/test_libx.h
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/railsys/libx/include/test_libx.h	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/railsys/libx/include/test_libx.h	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,25 @@
+//  Copyright (c) 2003 Institute of Transport, 
+//             Railway Construction and Operation, 
+//             University of Hanover, Germany
+//
+//  Use, modification and distribution are subject to the 
+//  Boost Software License, Version 1.0. (See accompanying file 
+//  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#ifdef _WIN32
+#ifdef LIBX_SOURCE
+__declspec(dllexport)
+#else
+__declspec(dllimport)
+#endif
+#endif
+class TestLibX
+{
+public:
+
+    TestLibX();
+    
+    // Needed to suppress 'unused variable' warning
+    // in some cases.
+    void do_something() {}
+};

Added: boost-jam/boost-build/branches/upstream/current/test/railsys/libx/project-root.jam
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/railsys/libx/project-root.jam	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/railsys/libx/project-root.jam	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,8 @@
+
+import toolset ; 
+
+# Tell that QT should be used. QTDIR will give installation
+# prefix. 
+toolset.using qt ;
+
+

Added: boost-jam/boost-build/branches/upstream/current/test/railsys/libx/src/Jamfile
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/railsys/libx/src/Jamfile	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/railsys/libx/src/Jamfile	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,18 @@
+#  Copyright (c) 2003 Institute of Transport, 
+#             Railway Construction and Operation, 
+#             University of Hanover, Germany
+#
+# Permission to copy, use, modify, sell and distribute this software is
+# granted provided this copyright notice appears in all copies. This
+# software is provided "as is" without express or implied warranty, and
+# with no claim as to its suitability for any purpose.
+
+project libx 
+    : requirements 
+        <include>../include
+    : usage-requirements
+        <include>../include
+    ;
+
+
+lib libx : test_libx.cpp ;

Added: boost-jam/boost-build/branches/upstream/current/test/railsys/libx/src/test_libx.cpp
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/railsys/libx/src/test_libx.cpp	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/railsys/libx/src/test_libx.cpp	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,15 @@
+//  Copyright (c) 2003 Institute of Transport, 
+//             Railway Construction and Operation, 
+//             University of Hanover, Germany
+//
+//  Use, modification and distribution are subject to the 
+//  Boost Software License, Version 1.0. (See accompanying file 
+//  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+
+#define LIBX_SOURCE
+#include <test_libx.h>
+
+TestLibX::TestLibX()
+{
+}

Added: boost-jam/boost-build/branches/upstream/current/test/railsys/program/Jamfile
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/railsys/program/Jamfile	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/railsys/program/Jamfile	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,46 @@
+# ================================================================
+#
+#  Railsys
+#  --------------
+#
+#  Copyright (c) 2002 Institute of Transport, 
+#             Railway Construction and Operation, 
+#             University of Hanover, Germany
+#
+# Permission to copy, use, modify, sell and distribute this software is
+# granted provided this copyright notice appears in all copies. This
+# software is provided "as is" without express or implied warranty, and
+# with no claim as to its suitability for any purpose.
+#
+#  02/21/02! Jürgen Hunold
+#
+#  $Id: Jamfile,v 1.5 2004/10/05 07:55:20 vladimir_prus Exp $
+#
+# ================================================================
+
+local BOOST_ROOT = [ modules.peek : BOOST_ROOT ] ;
+
+use-project /libx : ../libx/src ;
+
+project program
+    : requirements 
+        <include>$(BOOST_ROOT)
+        <threading>multi
+	<library>/qt//qt	
+        <hardcode-dll-paths>true
+        <stdlib>stlport
+        <use>/libx
+        <library>/libx//libx
+           
+ : usage-requirements 
+        <include>$(BOOST_ROOT)
+        : 
+        default-build release
+        <threading>multi
+        <library>/qt//qt
+        <hardcode-dll-paths>true
+        ;
+
+
+build-project main ;
+

Added: boost-jam/boost-build/branches/upstream/current/test/railsys/program/include/test_a.h
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/railsys/program/include/test_a.h	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/railsys/program/include/test_a.h	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,22 @@
+//  Copyright (c) 2003 Institute of Transport, 
+//             Railway Construction and Operation, 
+//             University of Hanover, Germany
+//
+//  Use, modification and distribution are subject to the 
+//  Boost Software License, Version 1.0. (See accompanying file 
+//  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+
+#include <qobject.h>
+
+class TestA : public QObject
+{
+    Q_OBJECT
+
+public:
+
+    TestA();
+    
+    // Needed to suppress 'unused variable' varning.
+    void do_something() { }
+};

Added: boost-jam/boost-build/branches/upstream/current/test/railsys/program/liba/Jamfile
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/railsys/program/liba/Jamfile	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/railsys/program/liba/Jamfile	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,14 @@
+#  Copyright (c) 2003 Institute of Transport, 
+#             Railway Construction and Operation, 
+#             University of Hanover, Germany
+#
+# Permission to copy, use, modify, sell and distribute this software is
+# granted provided this copyright notice appears in all copies. This
+# software is provided "as is" without express or implied warranty, and
+# with no claim as to its suitability for any purpose.
+
+project liba ;
+
+lib liba : test ../include/test_a.h ;
+
+obj test : test_a.cpp : <optimization>off ;
\ No newline at end of file

Added: boost-jam/boost-build/branches/upstream/current/test/railsys/program/liba/test_a.cpp
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/railsys/program/liba/test_a.cpp	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/railsys/program/liba/test_a.cpp	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,17 @@
+//  Copyright (c) 2003 Institute of Transport, 
+//             Railway Construction and Operation, 
+//             University of Hanover, Germany
+//
+//  Use, modification and distribution are subject to the 
+//  Boost Software License, Version 1.0. (See accompanying file 
+//  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include "../include/test_a.h"
+
+#include <test_libx.h>
+
+TestA::TestA()
+{
+    TestLibX aTestLibX;
+    aTestLibX.do_something();
+}

Added: boost-jam/boost-build/branches/upstream/current/test/railsys/program/main/Jamfile
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/railsys/program/main/Jamfile	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/railsys/program/main/Jamfile	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,12 @@
+#  Copyright (c) 2002 Institute of Transport, 
+#             Railway Construction and Operation, 
+#             University of Hanover, Germany
+#
+# Permission to copy, use, modify, sell and distribute this software is
+# granted provided this copyright notice appears in all copies. This
+# software is provided "as is" without express or implied warranty, and
+# with no claim as to its suitability for any purpose.
+
+project main ;
+
+exe test_a : main.cpp ../liba//liba /libx ;
\ No newline at end of file

Added: boost-jam/boost-build/branches/upstream/current/test/railsys/program/main/main.cpp
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/railsys/program/main/main.cpp	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/railsys/program/main/main.cpp	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,19 @@
+//  Copyright (c) 2002 Institute of Transport, 
+//             Railway Construction and Operation, 
+//             University of Hanover, Germany
+//
+//  Use, modification and distribution are subject to the 
+//  Boost Software License, Version 1.0. (See accompanying file 
+//  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include "../include/test_a.h"
+
+#include <test_libx.h>
+
+int main()
+{
+    TestLibX stTestLibX;
+    TestA stTestA;
+    
+    stTestLibX.do_something();
+};

Added: boost-jam/boost-build/branches/upstream/current/test/railsys/program/project-root.jam
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/railsys/program/project-root.jam	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/railsys/program/project-root.jam	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,9 @@
+
+import toolset ; 
+
+# Tell that QT should be used. QTDIR will give installation
+# prefix. 
+toolset.using qt ;
+
+# Not that good, but sufficient for testing
+toolset.using stlport : : /path/to/stlport ;

Added: boost-jam/boost-build/branches/upstream/current/test/railsys.py
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/railsys.py	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/railsys.py	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,15 @@
+#!/usr/bin/python
+
+#  Copyright (C) Vladimir Prus 2003. Permission to copy, use, modify, sell and
+#  distribute this software is granted provided this copyright notice appears in
+#  all copies. This software is provided "as is" without express or implied
+#  warranty, and with no claim as to its suitability for any purpose.
+
+from BoostBuild import Tester, List
+
+t = Tester()
+
+t.set_tree("railsys")
+t.run_build_system("--v2", subdir="program")
+
+t.cleanup()


Property changes on: boost-jam/boost-build/branches/upstream/current/test/railsys.py
___________________________________________________________________
Name: svn:executable
   + 

Added: boost-jam/boost-build/branches/upstream/current/test/readme.txt
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/readme.txt	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/readme.txt	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,3 @@
+Comprehensive tests for Boost.Build v2; requires Python. To test, execute:
+
+    python test_all.py

Added: boost-jam/boost-build/branches/upstream/current/test/recursive.jam
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/recursive.jam	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/recursive.jam	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,118 @@
+# (C) Copyright David Abrahams 2001. Permission to copy, use,
+# modify, sell and distribute this software is granted provided this
+# copyright notice appears in all copies. This software is provided
+# "as is" without express or implied warranty, and with no claim as
+# to its suitability for any purpose.
+
+##############################################################
+# Rules and actions that test Jam by invoking it recursively #
+#                                                            #
+# This is neccessary for testing anything that requires Jam  #
+# to execute build actions whose results must be checked,    #
+# and anything which exits Jam with a failure code (e.g. a   #
+# failed assertion).                                         #
+##############################################################
+
+# Creates a fake target, always built, which succeeds in building if Invoking a
+# Jamfile containing the given string succeeds. If optional-expected-output is
+# supplied, creates another fake target which succeeds in building if
+# optional-expected-output is in the Jam output.
+#
+# RETURNS: the target name of the Jam command.
+rule Jam ( command : expected-output ? )
+{
+    local jam-cmd = "$(command:G=jam_command)" ;
+    
+    NOTFILE "$(jam-cmd)" ;
+    ALWAYS "$(jam-cmd)" ;
+    DEPENDS all : "$(jam-cmd)" ;
+
+    if ($NT)
+    {
+        redirect on $(jam-cmd) = "nul" ;
+    }
+    else if $(UNIX)
+    {
+        redirect on $(jam-cmd) = "/dev/null" ;
+    }
+
+    if $(VERBOSE)
+    {
+        redirect on $(jam-cmd) = ;
+    }
+
+    invoke-Jam "$(jam-cmd)" ;
+    
+    if $(expected-output)
+    {
+        redirect on $(jam-cmd) = "scratch-output.txt" ;
+        local output-target = "$(expected-output:G=$(command))" ;
+        NOTFILE "$(output-target)" ;
+        ALWAYS "$(output-target)" ;
+        DEPENDS all : "$(output-target)" ;
+        Expect-in-output "$(output-target)" ;
+        
+        if $(VERBOSE)
+        {
+            if $(NT) { VERBOSE on $(output-target) = "type " ; }
+            else { VERBOSE on $(output-target) = "cat " ; }
+        }
+    }
+    return $(jam-cmd) ;
+}
+
+# Just like the "Jam" rule, above, but only succeeds if the Jam command /fails/.
+rule Jam-fail ( command : expected-output ? )
+{
+    local target = [ Jam $(command) : $(expected-output) ] ;
+    FAIL_EXPECTED $(target) ;
+    return $(target) ;
+}
+
+# The temporary jamfile we write is called "temp.jam". If the user has set
+# BOOST_BUILD_ROOT, it will be built there.
+gBOOST_TEST_JAMFILE = temp.jam ;
+LOCATE on gBOOST_TEST_JAMFILE ?= $(BOOST_BUILD_ROOT) ;
+
+# Runs Jam on a temporary Jamfile which contains the string in $(command:G=)
+# and redirects the results into a file whose name is given by $(redirect) on
+# command
+rule invoke-Jam ( command )
+{
+    PREFIX on $(command) = "actions unbuilt { } unbuilt all ;" ;
+    if $(NT)
+    {
+        REMOVE on $(command) = $(SystemRoot)\System32\find ;
+    }
+    REMOVE on $(command) ?= rm ;
+}
+actions invoke-Jam
+{
+    echo $(PREFIX) $(<:G=) > $(gBOOST_TEST_JAMFILE)
+    jam -sBOOST_ROOT=../../.. -sJAMFILE=$(gBOOST_TEST_JAMFILE)  $(JAMARGS) >$(redirect)
+}
+#     $(REMOVE) $(gBOOST_TEST_JAMFILE)
+
+
+# These actions expect to find the ungristed part of $(<) in scratch-output.txt
+# and return a nonzero exit code otherwise
+if $(NT)
+{
+    # Explicitly get the NT find command in case someone has another find in their path.
+    actions quietly Expect-in-output
+    {
+        $(VERBOSE)scratch-output.txt ;
+        $(SystemRoot)\System32\find /C "$(<:G=)" scratch-output.txt >nul
+    }
+}
+else
+{
+    # Not really the right actions for Unix; the argument will be interpreted as
+    # a regular expression. Is there a simpler find?
+    actions quietly Expect-in-output
+    {
+        $(VERBOSE)scratch-output.txt;
+        grep "$(<:G=)" scratch-output.txt
+    }
+}
+

Added: boost-jam/boost-build/branches/upstream/current/test/regression.py
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/regression.py	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/regression.py	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,130 @@
+#!/usr/bin/python
+
+#  Copyright (C) Vladimir Prus 2003. Permission to copy, use, modify, sell and
+#  distribute this software is granted provided this copyright notice appears in
+#  all copies. This software is provided "as is" without express or implied
+#  warranty, and with no claim as to its suitability for any purpose.
+
+#  Test for the regression testing framework.
+from BoostBuild import Tester, List
+
+# Create a temporary working directory
+t = Tester()
+
+t.write("c.cpp", "")
+
+t.write("r.cpp", """
+
+void helper();
+
+#include <iostream>
+int main(int ac, char* av[])
+{
+    helper();
+
+    for (int i = 1; i < ac; ++i)
+       std::cout << av[i] << '\\n';
+    return 0;
+} 
+""")
+
+t.write("c-f.cpp", """ 
+int 
+""")
+
+t.write("r-f.cpp", """ 
+int main()
+{
+    return 1;
+} 
+""")
+
+
+t.write("Jamfile", """ 
+import testing ;
+
+compile c.cpp ;
+compile-fail c-f.cpp ;
+run r.cpp libs//helper : foo bar ;
+run-fail r-f.cpp ;
+
+""")
+
+t.write("libs/Jamfile", """
+lib helper : helper.cpp ;
+""")
+
+t.write("libs/helper.cpp", """
+void
+#if defined(_WIN32)
+__declspec(dllexport)
+#endif
+helper() {}
+
+""")
+
+t.write("project-root.jam", "")
+
+# First test that when outcomes are expected, all .test files are created.
+t.run_build_system("hardcode-dll-paths=true", stderr=None, status=None)
+t.expect_addition("bin/c.test/$toolset/debug/c.test")
+t.expect_addition("bin/c-f.test/$toolset/debug/c-f.test")
+t.expect_addition("bin/r.test/$toolset/debug/r.test")
+t.expect_addition("bin/r-f.test/$toolset/debug/r-f.test")
+
+# Make sure args are handled.
+t.expect_content("bin/r.test/$toolset/debug/r.output",
+                 "foo\nbar\n\nEXIT STATUS: 0\n")
+
+# Test that input file is handled as well.
+t.write("r.cpp", """
+#include <iostream>
+#include <fstream>
+int main(int ac, char* av[])
+{
+    for (int i = 1; i < ac; ++i) {
+        std::ifstream ifs(av[i]);
+        std::cout << ifs.rdbuf();
+    }
+
+    return 0;
+} 
+""")
+
+t.write("dir/input.txt", "test input")
+
+t.write("Jamfile", """ 
+import testing ;
+
+compile c.cpp ;
+compile-fail c-f.cpp ;
+run r.cpp : : dir/input.txt ;
+run-fail r-f.cpp ;
+
+""")
+
+t.run_build_system("hardcode-dll-paths=true")
+t.expect_content("bin/r.test/$toolset/debug/r.output",
+                 "test input\nEXIT STATUS: 0\n")
+
+# Make sure test failures are detected. Reverse expectation and see
+# if .test files are created or not.
+t.write("Jamfile", """ 
+import testing ;
+
+compile-fail c.cpp ;
+compile c-f.cpp ;
+run-fail r.cpp : : dir/input.txt ;
+run r-f.cpp ;
+
+""")
+
+t.touch(List("c.cpp c-f.cpp r.cpp r-f.cpp"))
+
+t.run_build_system("hardcode-dll-paths=true", stderr=None, status=1)
+t.expect_removal("bin/c.test/$toolset/debug/c.test")
+t.expect_removal("bin/c-f.test/$toolset/debug/c-f.test")
+t.expect_removal("bin/r.test/$toolset/debug/r.test")
+t.expect_removal("bin/r-f.test/$toolset/debug/r-f.test")
+
+t.cleanup()


Property changes on: boost-jam/boost-build/branches/upstream/current/test/regression.py
___________________________________________________________________
Name: svn:executable
   + 

Added: boost-jam/boost-build/branches/upstream/current/test/relative_sources.py
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/relative_sources.py	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/relative_sources.py	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,14 @@
+#!/usr/bin/python
+
+# Test that we can specify sources using relative names.
+
+from BoostBuild import Tester
+t = Tester()
+
+t.write("project-root.jam", "import gcc ;")
+t.write("Jamfile", "exe a : src/a.cpp ;")
+t.write("src/a.cpp", "int main() { return 0; }\n")
+
+t.run_build_system()
+
+t.cleanup()


Property changes on: boost-jam/boost-build/branches/upstream/current/test/relative_sources.py
___________________________________________________________________
Name: svn:executable
   + 

Added: boost-jam/boost-build/branches/upstream/current/test/searched_lib.py
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/searched_lib.py	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/searched_lib.py	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,144 @@
+#!/usr/bin/python
+
+# Test usage of searched-libs: one which are found via -l
+# switch to the linker/compiler. 
+
+from BoostBuild import Tester, get_toolset
+import string
+import os
+t = Tester()
+
+# To start with, we have to prepate a library to link with
+t.write("lib/project-root.jam", "")
+t.write("lib/Jamfile", "lib libtest_lib : test_lib.cpp ;")
+t.write("lib/test_lib.cpp", """
+#ifdef _WIN32
+__declspec(dllexport)
+#endif
+void foo() {}
+""");
+
+t.run_build_system(subdir="lib")
+t.expect_addition("lib/bin/$toolset/debug/libtest_lib.dll")
+
+# Auto adjusting of suffixes does not work, since we need to
+# change dll to lib.
+# 
+if (os.name == 'nt' or os.uname()[0].lower().startswith('cygwin')) and get_toolset() != 'gcc':
+    t.copy("lib/bin/$toolset/debug/libtest_lib.lib", "lib/test_lib.lib")
+else:
+    t.copy("lib/bin/$toolset/debug/libtest_lib.dll", "lib/libtest_lib.dll")
+
+
+# Test that the simplest usage of searched library works.
+t.write('project-root.jam', '')
+t.write('Jamfile', """
+
+import path ;
+import project ;
+
+local here = [ project.attribute $(__name__) location ] ;
+here = [ path.root $(here) [ path.pwd ] ] ;
+
+exe main : main.cpp helper ;
+lib helper : helper.cpp test_lib : <dll-path>$(here)/lib ;
+lib test_lib : : <name>test_lib <search>lib ;
+""")
+t.write("main.cpp", """
+void helper();
+int main() { helper(); return 0; }
+""")
+t.write("helper.cpp", """
+void foo();
+
+void
+#if defined(_WIN32)
+__declspec(dllexport)
+#endif
+helper() { foo(); }
+""")
+t.run_build_system(stderr=None) # gcc warns about libraries which are not in -rpath.
+t.expect_addition("bin/$toolset/debug/main.exe")
+t.rm("bin/$toolset/debug/main.exe")
+
+# Now try using searched lib from static lib. Request shared version
+# of searched lib, since we don't have static one handy.
+t.write('Jamfile', """
+exe main : main.cpp helper ;
+lib helper : helper.cpp test_lib/<link>shared : <link>static ;
+lib test_lib : : <name>test_lib <search>lib ;
+""")
+t.run_build_system(stderr=None)
+t.expect_addition("bin/$toolset/debug/main.exe")
+t.expect_addition("bin/$toolset/debug/link-static/helper.lib")
+t.rm("bin/$toolset/debug/main.exe")
+
+# A regression test: <library>property referring to
+# searched-lib was mishandled. As the result, we were
+# putting target name to the command line!
+# Note that 
+#    g++ ...... <.>z
+# works nicely in some cases, sending output from compiler
+# to file 'z'.
+# This problem shows up when searched libs are in usage
+# requirements.
+
+t.write('Jamfile', 'exe main : main.cpp d/d2//a ;')
+t.write('main.cpp',"""
+void foo();
+int main() { foo(); return 0; }
+
+""")
+t.write('d/d2/Jamfile', """
+lib test_lib : : <name>test_lib <search>../../lib ;
+lib a : a.cpp : : : <library>test_lib ;
+""")
+t.write('d/d2/a.cpp', """
+#ifdef _WIN32
+__declspec(dllexport) int force_library_creation_for_a;
+#endif
+""")
+
+t.run_build_system()
+
+# A regression test. Searched targets were not associated
+# with any properties. For that reason, if the same searched
+# lib is generated with two different properties, we had an
+# error saying they are actualized to the same Jam target name.
+
+t.write("project-root.jam", "")
+
+t.write("a.cpp", "")
+
+# The 'l' library will be built in two variants:
+# 'debug' (directly requested) and 'release' (requested
+# from 'a').
+t.write("Jamfile", """
+exe a : a.cpp l/<variant>release ;
+
+lib l : : <name>l_d <variant>debug ;
+lib l : : <name>l_r <variant>release ;
+""")
+
+t.run_build_system("-n")
+
+# A regression test. Two virtual target with the same properties
+# were created for 'l' target, which caused and error to be reported
+# when actualizing targets. The final error is correct, but we should
+# not create two duplicated targets. Thanks to Andre Hentz
+# for finding this bug.
+t.write("project-root.jam", "")
+
+t.write("a.cpp", "")
+
+t.write("Jamfile", """
+project a : requirements <link-runtime>static ;
+
+static-lib a : a.cpp l ;
+lib l : : <name>l_f ;
+""")
+
+t.run_build_system("-n")
+
+
+t.cleanup()


Property changes on: boost-jam/boost-build/branches/upstream/current/test/searched_lib.py
___________________________________________________________________
Name: svn:executable
   + 

Added: boost-jam/boost-build/branches/upstream/current/test/skipping.py
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/skipping.py	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/skipping.py	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,41 @@
+#!/usr/bin/python
+
+#  Copyright (C) Vladimir Prus 2003. Permission to copy, use, modify, sell and
+#  distribute this software is granted provided this copyright notice appears in
+#  all copies. This software is provided "as is" without express or implied
+#  warranty, and with no claim as to its suitability for any purpose.
+
+#  Test that V2 does not fail gracelessy when any target is skipped.
+from BoostBuild import Tester, List
+
+# Create a temporary working directory
+t = Tester()
+t.write("a.cpp", """ 
+int main() {} 
+""")
+
+t.write("b.cpp", """ 
+int main() {} 
+""")
+
+t.write("c.cpp", """ 
+int main() {} 
+""")
+
+t.write("Jamfile", """ 
+import feature : feature ;
+
+feature foo : 1 2 : link-incompatible ;
+
+exe a : a.cpp : <foo>1 ;
+exe b : b.cpp : <foo>2 ;
+exe c : c.cpp ; 
+""")
+
+t.write("project-root.jam", """ 
+""")
+
+t.run_build_system("foo=1")
+
+t.cleanup()
+


Property changes on: boost-jam/boost-build/branches/upstream/current/test/skipping.py
___________________________________________________________________
Name: svn:executable
   + 

Added: boost-jam/boost-build/branches/upstream/current/test/stage.py
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/stage.py	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/stage.py	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,143 @@
+#!/usr/bin/python
+
+# Test staging
+
+from BoostBuild import Tester
+t = Tester()
+
+t.write("project-root.jam", "import gcc ;")
+
+t.write(
+    "Jamfile", 
+"""
+lib a : a.cpp ;
+stage dist : a a.h auxilliary/1 ;
+""")
+
+t.write(
+    "a.cpp",
+"""
+int
+#ifdef _WIN32
+__declspec(dllexport)
+#endif
+must_export_something;
+""")
+
+t.write("a.h", "")
+t.write("auxilliary/1", "")
+
+t.run_build_system()
+t.expect_addition(["dist/a.dll", "dist/a.h", "dist/1"])
+
+
+# Regression test: the following was causing the "duplicate target name"
+# error.
+t.write(
+    "Jamfile", 
+"""
+project : requirements <hardcode-dll-paths>true ;
+lib a : a.cpp ;
+stage dist : a a.h auxilliary/1 ;
+alias dist-alias : dist ;
+""")
+t.run_build_system()
+
+
+# Test the <location> property
+t.write("Jamfile", """
+lib a : a.cpp ;
+stage dist : a 
+    : <variant>debug:<location>ds <variant>release:<location>rs
+    ;
+""")
+
+t.run_build_system()
+t.expect_addition("ds/a.dll")
+
+t.run_build_system("release")
+t.expect_addition("rs/a.dll")
+
+# Test the <location> property in subprojects. 
+# Thanks to Kirill Lapshin for bug report.
+
+t.write("project-root.jam", """
+path-constant DIST : dist ;
+""")
+
+t.write("Jamfile", "build-project d ;")
+
+t.write(
+    "d/Jamfile",
+"""
+exe a : a.cpp ;
+stage dist : a : <location>$(DIST) ;
+""")
+
+t.write("d/a.cpp", "int main() { return 0;}\n")
+
+t.run_build_system()
+t.expect_addition("dist/a.exe")
+
+t.rm("dist")
+# Workaround a BIG BUG: the response file is not deleted,
+# even if application *is* deleted. We'll try to use the
+# same response file when building from subdir, with very
+# bad results.
+t.rm("d/bin")
+t.run_build_system(subdir="d")
+t.expect_addition("dist/a.exe")
+
+
+# Check that 'stage' does not incorrectly reset target suffixes.
+t.write("a.cpp", """ 
+int main() {} 
+""")
+
+t.write("project-root.jam", """ 
+import type ;
+type.register MYEXE : : EXE : main ;
+type.set-generated-target-suffix MYEXE : <optimization>off : myexe ; 
+""")
+
+# Since <optimization>off is in properties when 'a' is built, and staged,
+# it's suffix should be "myexe".
+t.write("Jamfile", """ 
+stage dist : a ;
+myexe a : a.cpp ; 
+""")
+
+t.run_build_system()
+t.expect_addition("dist/a.myexe")
+
+# Test 'stage's ability to traverse dependencies.
+t.write("a.cpp", """ 
+int main() { return 0; }
+
+""")
+
+t.write("l.cpp", """
+void
+#if defined(_WIN32)
+__declspec(dllexport)
+#endif
+foo() { }
+
+""")
+
+t.write("Jamfile", """ 
+lib l : l.cpp ;
+exe a : a.cpp l ;
+stage dist : a : <traverse-dependencies>on <include-type>EXE <include-type>LIB ; 
+""")
+
+t.write("project-root.jam", "")
+
+t.rm("dist")
+t.run_build_system()
+t.expect_addition("dist/a.exe")
+t.expect_addition("dist/l.dll")
+
+
+t.cleanup()
+


Property changes on: boost-jam/boost-build/branches/upstream/current/test/stage.py
___________________________________________________________________
Name: svn:executable
   + 

Added: boost-jam/boost-build/branches/upstream/current/test/standalone.py
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/standalone.py	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/standalone.py	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,48 @@
+#!/usr/bin/python
+
+#  Copyright (C) Vladimir Prus 2003. Permission to copy, use, modify, sell and
+#  distribute this software is granted provided this copyright notice appears in
+#  all copies. This software is provided "as is" without express or implied
+#  warranty, and with no claim as to its suitability for any purpose.
+
+
+from BoostBuild import Tester, List
+
+t = Tester()
+
+# Regression tests: standalone project were not able to refer to targets
+# declared in themselfs!
+
+t.write("a.cpp", """ 
+int main()
+{
+    return 0;
+}
+
+""")
+
+t.write("project-root.jam", """ 
+import standalone ; 
+""")
+
+t.write("standalone.jam", """ 
+import project ;
+
+project.initialize $(__name__) ;
+project standalone ;
+
+local pwd = [ PWD ] ;
+
+alias x : $(pwd)/../a.cpp ;
+alias runtime : x ;
+
+""")
+
+t.write("sub/Jamfile", """ 
+stage bin : /standalone//runtime ; 
+""")
+
+t.run_build_system(subdir="sub")
+t.expect_addition("sub/bin/a.cpp")
+t.cleanup()
+


Property changes on: boost-jam/boost-build/branches/upstream/current/test/standalone.py
___________________________________________________________________
Name: svn:executable
   + 

Added: boost-jam/boost-build/branches/upstream/current/test/startup/boost-root/boost-build.jam
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/startup/boost-root/boost-build.jam	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/startup/boost-root/boost-build.jam	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,2 @@
+# Emulate v1 behavior; with the boost-build file in the boost root directory.
+boost-build build ;

Added: boost-jam/boost-build/branches/upstream/current/test/startup/boost-root/build/boost-build.jam
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/startup/boost-root/build/boost-build.jam	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/startup/boost-root/build/boost-build.jam	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,2 @@
+# The presence of this file emulates the Boost 1.27.0 release
+include $(BOOST_ROOT)/tools/build/bootstrap.jam ;

Added: boost-jam/boost-build/branches/upstream/current/test/startup/boost-root/build/bootstrap.jam
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/startup/boost-root/build/bootstrap.jam	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/startup/boost-root/build/bootstrap.jam	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,3 @@
+ECHO build system bootstrapped ;
+DEPENDS all : nothing ;
+NOTFILE nothing ;

Added: boost-jam/boost-build/branches/upstream/current/test/startup/bootstrap-env/boost-build.jam
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/startup/bootstrap-env/boost-build.jam	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/startup/bootstrap-env/boost-build.jam	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1 @@
+boost-build ;
\ No newline at end of file

Added: boost-jam/boost-build/branches/upstream/current/test/startup/bootstrap-explicit/boost-build.jam
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/startup/bootstrap-explicit/boost-build.jam	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/startup/bootstrap-explicit/boost-build.jam	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1 @@
+boost-build ../boost-root/build ;
\ No newline at end of file

Added: boost-jam/boost-build/branches/upstream/current/test/startup/bootstrap-implicit/readme.txt
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/startup/bootstrap-implicit/readme.txt	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/startup/bootstrap-implicit/readme.txt	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1 @@
+This file is only here so that cvs update -P won't fail to create a directory
\ No newline at end of file

Added: boost-jam/boost-build/branches/upstream/current/test/startup/no-bootstrap1/boost-build.jam
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/startup/no-bootstrap1/boost-build.jam	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/startup/no-bootstrap1/boost-build.jam	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,2 @@
+# Bootstrap file not found via implicit lookup in BOOST_BUILD_PATH
+boost-build ;

Added: boost-jam/boost-build/branches/upstream/current/test/startup/no-bootstrap1/subdir/readme.txt
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/startup/no-bootstrap1/subdir/readme.txt	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/startup/no-bootstrap1/subdir/readme.txt	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1 @@
+This file is only here so cvs update -P will create the directory.
\ No newline at end of file

Added: boost-jam/boost-build/branches/upstream/current/test/startup/no-bootstrap2/boost-build.jam
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/startup/no-bootstrap2/boost-build.jam	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/startup/no-bootstrap2/boost-build.jam	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,2 @@
+# Bootstrap file not found via explicit lookup in .
+boost-build . ;
\ No newline at end of file

Added: boost-jam/boost-build/branches/upstream/current/test/startup/no-bootstrap3/boost-build.jam
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/startup/no-bootstrap3/boost-build.jam	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/startup/no-bootstrap3/boost-build.jam	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1 @@
+# Call to boost-build is intentionally missing
\ No newline at end of file

Added: boost-jam/boost-build/branches/upstream/current/test/startup_v1.py
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/startup_v1.py	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/startup_v1.py	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,94 @@
+#!/usr/bin/python
+
+from BoostBuild import Tester
+import os
+import re
+
+def expect_substring(actual,expected):
+    return actual.find(expected) != -1
+
+def match_re(actual,expected):
+    return re.match(expected,actual,re.DOTALL) != None
+
+# Test the v1 startup behavior
+t = Tester(
+    executable='jam'
+    , match=match_re
+    , boost_build_path=''
+    , pass_toolset=0
+    )
+
+t.set_tree('startup')
+
+if os.name == 'nt':
+    t.run_build_system(
+        status=1, stdout="You didn't set BOOST_ROOT", match = expect_substring)
+
+t.run_build_system(
+    extra_args = '-sBOOST_ROOT=.', status=1
+    , stdout=r'''Unable to load Boost\.Build: could not find "boost-build\.jam".*BOOST_ROOT must be set'''
+    )
+
+os.chdir('no-bootstrap1')
+
+t.run_build_system(
+    extra_args = '-sBOOST_ROOT=.', status=1
+    , stdout=r'''Unable to load Boost\.Build: could not find build system\.'''
+    + r'''.*attempted to load the build system by invoking'''
+    + r'''.*'boost-build ;'.*'''
+    + r'''but we were unable to find "bootstrap\.jam"'''
+    )
+
+# Descend to a subdirectory which /doesn't/ contain a boost-build.jam
+# file, and try again to test the crawl-up behavior.
+os.chdir('subdir')
+
+t.run_build_system(
+    extra_args = '-sBOOST_ROOT=.', status=1
+    , stdout=r'''Unable to load Boost\.Build: could not find build system\.'''
+    + r'''.*attempted to load the build system by invoking'''
+    + r'''.*'boost-build ;'.*'''
+    + r'''but we were unable to find "bootstrap\.jam"'''
+    )
+
+os.chdir('../../no-bootstrap2')
+
+t.run_build_system(
+    extra_args = '-sBOOST_ROOT=.', status=1
+    , stdout=r'''Unable to load Boost\.Build: could not find build system\.'''
+    + r'''.*attempted to load the build system by invoking'''
+    + r'''.*'boost-build \. ;'.*'''
+    + r'''but we were unable to find "bootstrap\.jam"'''
+    )
+
+os.chdir('../no-bootstrap3')
+
+t.run_build_system(
+    extra_args = '-sBOOST_ROOT=.', status=1
+    , stdout=r'''Unable to load Boost.Build
+.*boost-build.jam" was found.*
+However, it failed to call the "boost-build" rule'''
+    )
+
+# test bootstrapping based on BOOST_BUILD_PATH
+os.chdir('../bootstrap-env')
+t.run_build_system(
+    extra_args = '-sBOOST_ROOT=../boost-root -sBOOST_BUILD_PATH=../boost-root/build'
+    , stdout = 'build system bootstrapped'
+    )
+
+# test bootstrapping based on an explicit path in boost-build.jam
+os.chdir('../bootstrap-explicit')
+t.run_build_system(
+    extra_args = '-sBOOST_ROOT=../boost-root'
+    , stdout = 'build system bootstrapped'
+    )
+
+# test bootstrapping based on BOOST_ROOT
+os.chdir('../bootstrap-implicit')
+t.run_build_system(
+    extra_args = '-sBOOST_ROOT=../boost-root'
+    , stdout = 'build system bootstrapped'
+    )
+
+t.cleanup()

Added: boost-jam/boost-build/branches/upstream/current/test/startup_v2.py
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/startup_v2.py	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/startup_v2.py	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,78 @@
+#!/usr/bin/python
+
+from BoostBuild import Tester
+import os
+import re
+
+def match_re(actual,expected):
+    return re.match(expected,actual,re.DOTALL) != None
+
+# Test the v1 startup behavior
+t = Tester(
+    match= match_re
+    , boost_build_path=''
+    , pass_toolset=0
+    )
+
+t.set_tree('startup')
+
+t.run_build_system(
+    status=1, stdout=r'''Unable to load Boost\.Build: could not find "boost-build.jam"
+.*Attempted search from .* up to the root''', match = match_re)
+
+os.chdir('no-bootstrap1')
+
+t.run_build_system(
+    status=1
+    , stdout=r'''Unable to load Boost\.Build: could not find build system\.'''
+    + r'''.*attempted to load the build system by invoking'''
+    + r'''.*'boost-build ;'.*'''
+    + r'''but we were unable to find "bootstrap\.jam"'''
+    )
+
+# Descend to a subdirectory which /doesn't/ contain a boost-build.jam
+# file, and try again to test the crawl-up behavior.
+os.chdir('subdir')
+
+t.run_build_system(
+    status=1
+    , stdout=r'''Unable to load Boost\.Build: could not find build system\.'''
+    + r'''.*attempted to load the build system by invoking'''
+    + r'''.*'boost-build ;'.*'''
+    + r'''but we were unable to find "bootstrap\.jam"'''
+    )
+
+os.chdir('../../no-bootstrap2')
+
+t.run_build_system(
+    status=1
+    , stdout=r'''Unable to load Boost\.Build: could not find build system\.'''
+    + r'''.*attempted to load the build system by invoking'''
+    + r'''.*'boost-build \. ;'.*'''
+    + r'''but we were unable to find "bootstrap\.jam"'''
+    )
+
+os.chdir('../no-bootstrap3')
+
+t.run_build_system(
+    status=1
+    , stdout=r'''Unable to load Boost.Build
+.*boost-build.jam" was found.*
+However, it failed to call the "boost-build" rule'''
+    )
+
+# test bootstrapping based on BOOST_BUILD_PATH
+os.chdir('../bootstrap-env')
+t.run_build_system(
+    extra_args = '-sBOOST_BUILD_PATH=../boost-root/build'
+    , stdout = 'build system bootstrapped'
+    )
+
+# test bootstrapping based on an explicit path in boost-build.jam
+os.chdir('../bootstrap-explicit')
+t.run_build_system(
+    stdout = 'build system bootstrapped'
+    )
+
+t.cleanup()
+

Added: boost-jam/boost-build/branches/upstream/current/test/subdir1/file-to-bind
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/subdir1/file-to-bind	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/subdir1/file-to-bind	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1 @@
+# This file intentionally left blank
\ No newline at end of file

Added: boost-jam/boost-build/branches/upstream/current/test/suffix.py
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/suffix.py	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/suffix.py	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,65 @@
+#!/usr/bin/python
+
+#  Copyright (C) Vladimir Prus 2003. Permission to copy, use, modify, sell and
+#  distribute this software is granted provided this copyright notice appears in
+#  all copies. This software is provided "as is" without express or implied
+#  warranty, and with no claim as to its suitability for any purpose.
+
+from BoostBuild import Tester, List
+
+t = Tester()
+
+#  Regression test: when staging V2 used to change suffixes on targets
+#  corresponding to real files.
+t.write("Jamfile", """ 
+import type : register ;
+register A : a1 a2 a3 ;
+
+stage a : a.a3 ; 
+""")
+
+t.write("project-root.jam", "")
+t.write("a.a3", "")
+
+t.run_build_system()
+t.expect_addition("a/a.a3");
+
+# Regression test: we should be able to specify empty suffix for
+# derived target type, even if base type has non-empty suffix.
+t.write("a.cpp", "")
+
+t.write("suffixes.jam", """ 
+import type ;
+import generators ;
+import common ;
+
+type.register First : first : ;
+type.register Second : "" : First : main ;
+
+generators.register-standard $(__name__).second : CPP : Second ;
+
+rule second
+{
+    TOUCH on $(<) = [ common.file-creation-command ] ;
+}
+
+actions second
+{
+    $(TOUCH) $(<)
+}
+
+""")
+
+t.write("project-root.jam", """ 
+import suffixes ; 
+""")
+
+t.write("Jamfile", """ 
+second a : a.cpp ; 
+""")
+
+t.run_build_system()
+t.expect_addition("bin/$toolset/debug/a")
+
+
+t.cleanup()


Property changes on: boost-jam/boost-build/branches/upstream/current/test/suffix.py
___________________________________________________________________
Name: svn:executable
   + 

Added: boost-jam/boost-build/branches/upstream/current/test/svn_tree.py
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/svn_tree.py	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/svn_tree.py	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,670 @@
+#!/usr/bin/env python
+#
+#  tree.py: tools for comparing directory trees
+#
+#  Subversion is a tool for revision control.
+#  See http://subversion.tigris.org for more information.
+#
+# ====================================================================
+# Copyright (c) 2001 Sam Tobin-Hochstadt.  All rights reserved.
+#
+# This software is licensed as described in the file COPYING, which
+# you should have received as part of this distribution.  The terms
+# are also available at http://subversion.tigris.org/license-1.html.
+# If newer versions of this license are posted there, you may use a
+# newer version instead, at your option.
+#
+######################################################################
+
+# This file was modified by Vladimir Prus to store modification times in
+# tree nodes.
+
+import re
+import string
+import os.path
+import os
+import stat
+
+
+
+#========================================================================
+
+# ===>  Overview of our Datastructures  <===
+
+# The general idea here is that many, many things can be represented by
+# a tree structure:
+
+#   - a working copy's structure and contents
+#   - the output of 'svn status'
+#   - the output of 'svn checkout/update'
+#   - the output of 'svn commit'
+
+# The idea is that a test function creates a "expected" tree of some
+# kind, and is then able to compare it to an "actual" tree that comes
+# from running the Subversion client.  This is what makes a test
+# automated; if an actual and expected tree match exactly, then the test
+# has passed.  (See compare_trees() below.)
+
+# The SVNTreeNode class is the fundamental data type used to build tree
+# structures.  The class contains a method for "dropping" a new node
+# into an ever-growing tree structure. (See also create_from_path()).
+
+# We have four parsers in this file for the four use cases listed above:
+# each parser examines some kind of input and returns a tree of
+# SVNTreeNode objects.  (See build_tree_from_checkout(),
+# build_tree_from_commit(), build_tree_from_status(), and
+# build_tree_from_wc()).  These trees are the "actual" trees that result
+# from running the Subversion client.
+
+# Also necessary, of course, is a convenient way for a test to create an
+# "expected" tree.  The test *could* manually construct and link a bunch
+# of SVNTreeNodes, certainly.  But instead, all the tests are using the
+# build_generic_tree() routine instead.
+
+# build_generic_tree() takes a specially-formatted list of lists as
+# input, and returns a tree of SVNTreeNodes.  The list of lists has this
+# structure:
+
+#   [ ['/full/path/to/item', 'text contents', {prop-hash}, {att-hash}],
+#     [...],
+#     [...],
+#     ...   ]
+
+# You can see that each item in the list essentially defines an
+# SVNTreeNode.  build_generic_tree() instantiates a SVNTreeNode for each
+# item, and then drops it into a tree by parsing each item's full path.
+
+# So a typical test routine spends most of its time preparing lists of
+# this format and sending them to build_generic_tree(), rather than
+# building the "expected" trees directly.
+
+#   ### Note: in the future, we'd like to remove this extra layer of
+#   ### abstraction.  We'd like the SVNTreeNode class to be more
+#   ### directly programmer-friendly, providing a number of accessor
+#   ### routines, so that tests can construct trees directly.
+
+# The first three fields of each list-item are self-explanatory.  It's
+# the fourth field, the "attribute" hash, that needs some explanation.
+# The att-hash is used to place extra information about the node itself,
+# depending on the parsing context:
+
+#   - in the 'svn co/up' use-case, each line of output starts with two
+#     characters from the set of (A, D, G, U, C, _).  This status code
+#     is stored in a attribute named 'status'.
+
+#   - in the 'svn ci/im' use-case, each line of output starts with one
+#      of the words (Adding, Deleting, Sending).  This verb is stored in
+#      an attribute named 'verb'.
+
+#   - in the 'svn status' use-case (which is always run with the -v
+#     (--verbose) flag), each line of output contains a working revision
+#     number and a two-letter status code similar to the 'svn co/up'
+#     case.  The repository revision is also printed.  All of this
+#     information is stored in attributes named 'wc_rev', 'status', and
+#     'repos_rev', respectively.
+
+#   - in the working-copy use-case, the att-hash is ignored.
+
+
+# Finally, one last explanation: the file 'actions.py' contain a number
+# of helper routines named 'run_and_verify_FOO'.  These routines take
+# one or more "expected" trees as input, then run some svn subcommand,
+# then push the output through an appropriate parser to derive an
+# "actual" tree.  Then it runs compare_trees() and returns the result.
+# This is why most tests typically end with a call to
+# run_and_verify_FOO().
+
+
+
+
+# A node in a tree.
+#
+# If CHILDREN is None, then the node is a file.  Otherwise, CHILDREN
+# is a list of the nodes making up that directory's children.
+#
+# NAME is simply the name of the file or directory.  CONTENTS is a
+# string that contains the file's contents (if a file), PROPS are
+# properties attached to files or dirs, and ATTS is a dictionary of
+# other metadata attached to the node.
+
+class SVNTreeNode:
+
+  def __init__(self, name, children=None, contents=None, props={}, atts={}):
+    self.name = name
+    self.mtime = 0
+    self.children = children
+    self.contents = contents
+    self.props = props
+    self.atts = atts
+    self.path = name
+
+# TODO: Check to make sure contents and children are mutually exclusive
+
+  def add_child(self, newchild):
+    if self.children is None:  # if you're a file,
+      self.children = []     # become an empty dir.
+    child_already_exists = 0
+    for a in self.children:
+      if a.name == newchild.name:
+        child_already_exists = 1
+        break
+    if child_already_exists == 0:
+      self.children.append(newchild)
+      newchild.path = os.path.join (self.path, newchild.name)      
+
+    # If you already have the node,
+    else:      
+      if newchild.children is None:
+        # this is the 'end' of the chain, so copy any content here.
+        a.contents = newchild.contents
+        a.props = newchild.props
+        a.atts = newchild.atts
+        a.path = os.path.join (self.path, newchild.name)
+      else:
+        # try to add dangling children to your matching node
+        for i in newchild.children:
+          a.add_child(i)
+
+
+  def pprint(self):
+    print " * Node name:  ", self.name
+    print "    Path:      ", self.path
+    print "    Contents:  ", self.contents
+    print "    Properties:", self.props
+    print "    Attributes:", self.atts
+    ### FIXME: I'd like to be able to tell the difference between
+    ### self.children is None (file) and self.children == [] (empty
+    ### diretory), but it seems that most places that construct
+    ### SVNTreeNode objects don't even try to do that.  --xbc
+    if self.children is not None:
+      print "    Children:  ", len(self.children)
+    else:
+      print "    Children: is a file."
+
+# reserved name of the root of the tree
+
+root_node_name = "__SVN_ROOT_NODE"
+
+# Exception raised if you screw up in this module.
+
+class SVNTreeError(Exception): pass
+
+# Exception raised if two trees are unequal
+
+class SVNTreeUnequal(Exception): pass
+
+# Exception raised if one node is file and other is dir
+
+class SVNTypeMismatch(Exception): pass
+
+# Exception raised if get_child is passed a file.
+
+class SVNTreeIsNotDirectory(Exception): pass
+
+
+# Some attributes 'stack' on each other if the same node is added
+# twice to a tree.  Place all such special cases in here.
+def attribute_merge(orighash, newhash):
+  "Merge the attributes in NEWHASH into ORIGHASH."
+
+  if orighash.has_key('verb') and newhash.has_key('verb'):
+    # Special case: if a commit reports a node as "deleted", then
+    # "added", it's a replacment.
+    if orighash['verb'] == "Deleting":
+      if newhash['verb'] == "Adding":
+        orighash['verb'] = "Replacing"
+
+  # Add future stackable attributes here...
+
+  return orighash
+
+
+# helper func
+def add_elements_as_path(top_node, element_list):
+  """Add the elements in ELEMENT_LIST as if they were a single path
+  below TOP_NODE."""
+
+  # The idea of this function is to take a list like so:
+  # ['A', 'B', 'C'] and a top node, say 'Z', and generate a tree
+  # like this:
+  #
+  #             Z -> A -> B -> C
+  #
+  # where 1 -> 2 means 2 is a child of 1.
+  #
+
+  prev_node = top_node
+  for i in element_list:
+    new_node = SVNTreeNode(i, None)
+    prev_node.add_child(new_node)
+    prev_node = new_node
+
+
+# Sorting function -- sort 2 nodes by their names.
+def node_is_greater(a, b):
+  "Sort the names of two nodes."
+  # Interal use only
+  if a.name == b.name:
+    return 0
+  if a.name > b.name:
+    return 1
+  else:
+    return -1
+
+
+# Helper for compare_trees
+def compare_file_nodes(a, b):
+  """Compare two nodes' names, contents, and properties, ignoring
+  children.  Return 0 if the same, 1 otherwise."""
+  if a.name != b.name:
+    return 1
+  if a.contents != b.contents:
+    return 1
+  if a.props != b.props:
+    return 1
+  if a.atts != b.atts:
+    return 1
+
+
+# Internal utility used by most build_tree_from_foo() routines.
+#
+# (Take the output and .add_child() it to a root node.)
+
+def create_from_path(path, contents=None, props={}, atts={}):
+  """Create and return a linked list of treenodes, given a PATH
+  representing a single entry into that tree.  CONTENTS and PROPS are
+  optional arguments that will be deposited in the tail node."""
+
+  # get a list of all the names in the path
+  # each of these will be a child of the former
+  elements = path.split("/")
+  if len(elements) == 0:
+    raise SVNTreeError
+
+  root_node = SVNTreeNode(elements[0], None)
+
+  add_elements_as_path(root_node, elements[1:])
+
+  # deposit contents in the very last node.
+  node = root_node
+  while 1:
+    if node.children is None:
+      node.contents = contents
+      node.props = props
+      node.atts = atts
+      break
+    node = node.children[0]
+
+  return root_node
+
+
+# helper for handle_dir(), which is a helper for build_tree_from_wc()
+def get_props(path):
+  "Return a hash of props for PATH, using the svn client."
+
+  # It's not kosher to look inside SVN/ and try to read the internal
+  # property storage format.  Instead, we use 'svn proplist'.  After
+  # all, this is the only way the user can retrieve them, so we're
+  # respecting the black-box paradigm.
+
+  props = {}
+  output, errput = main.run_svn(1, "proplist", path, "--verbose")
+
+  for line in output:
+    name, value = line.split(' : ')
+    name = string.strip(name)
+    value = string.strip(value)
+    props[name] = value
+
+  return props
+
+
+# helper for handle_dir(), which helps build_tree_from_wc()
+def get_text(path):
+  "Return a string with the textual contents of a file at PATH."
+
+  # sanity check
+  if not os.path.isfile(path):
+    return None
+
+  fp = open(path, 'r')
+  contents = fp.read()
+  fp.close()
+  return contents
+
+
+# main recursive helper for build_tree_from_wc()
+def handle_dir(path, current_parent, load_props, ignore_svn):
+
+  # get a list of all the files
+  all_files = os.listdir(path)
+  files = []
+  dirs = []
+
+  # put dirs and files in their own lists, and remove SVN dirs
+  for f in all_files:
+    f = os.path.join(path, f)
+    if (os.path.isdir(f) and os.path.basename(f) != 'SVN'):
+      dirs.append(f)
+    elif os.path.isfile(f):
+      files.append(f)
+
+  # add each file as a child of CURRENT_PARENT
+  for f in files:
+    fcontents = get_text(f)
+    if load_props:
+      fprops = get_props(f)
+    else:
+      fprops = {}
+    c = SVNTreeNode(os.path.basename(f), None,
+                                         fcontents, fprops)
+    c.mtime = os.stat(f)[stat.ST_MTIME]
+    current_parent.add_child(c)
+
+  # for each subdir, create a node, walk its tree, add it as a child
+  for d in dirs:
+    if load_props:
+      dprops = get_props(d)
+    else:
+      dprops = {}
+    new_dir_node = SVNTreeNode(os.path.basename(d), [], None, dprops)
+    handle_dir(d, new_dir_node, load_props, ignore_svn)
+    new_dir_node.mtime = os.stat(f)[stat.ST_MTIME]
+    current_parent.add_child(new_dir_node)
+
+def get_child(node, name):
+  """If SVNTreeNode NODE contains a child named NAME, return child;
+  else, return None. If SVNTreeNode is not a directory, raise a
+  SVNTreeIsNotDirectory exception"""
+  if node.children == None:
+    raise SVNTreeIsNotDirectory
+  for n in node.children:
+    if (name == n.name):
+      return n
+  return None
+
+
+# Helper for compare_trees
+def default_singleton_handler(a, baton):
+  "Printing SVNTreeNode A's name, then raise SVNTreeUnequal."
+  print "Got singleton", a.name
+  a.pprint()
+  raise SVNTreeUnequal
+
+
+###########################################################################
+###########################################################################
+# EXPORTED ROUTINES ARE BELOW
+
+
+# Main tree comparison routine!
+
+def compare_trees(a, b,
+                  singleton_handler_a = None,
+                  a_baton = None,
+                  singleton_handler_b = None,
+                  b_baton = None):
+  """Compare SVNTreeNodes A and B, expressing differences using FUNC_A
+  and FUNC_B.  FUNC_A and FUNC_B are functions of two arguments (a
+  SVNTreeNode and a context baton), and may raise exception
+  SVNTreeUnequal.  Their return value is ignored.
+
+  If A and B are both files, then return 0 if their contents,
+  properties, and names are all the same; else raise a SVNTreeUnequal.
+  If A is a file and B is a directory, raise a SVNTypeMismatch; same
+  vice-versa.  If both are directories, then for each entry that
+  exists in both, call compare_trees on the two entries; otherwise, if
+  the entry exists only in A, invoke FUNC_A on it, and likewise for
+  B with FUNC_B."""
+
+  def display_nodes(a, b):
+    'Display two nodes, expected and actual.'
+    print "============================================================="
+    print "Expected", b.name, "and actual", a.name, "are different!"
+    print "============================================================="
+    print "EXPECTED NODE TO BE:"
+    print "============================================================="
+    b.pprint()
+    print "============================================================="
+    print "ACTUAL NODE FOUND:"
+    print "============================================================="
+    a.pprint()
+
+  # Setup singleton handlers
+  if (singleton_handler_a is None):
+    singleton_handler_a = default_singleton_handler
+  if (singleton_handler_b is None):
+    singleton_handler_b = default_singleton_handler
+
+  try:
+    # A and B are both files.
+    if ((a.children is None) and (b.children is None)):
+      if compare_file_nodes(a, b):
+        display_nodes(a, b)
+        raise main.SVNTreeUnequal
+    # One is a file, one is a directory.
+    elif (((a.children is None) and (b.children is not None))
+          or ((a.children is not None) and (b.children is None))):
+      display_nodes(a, b)
+      raise main.SVNTypeMismatch
+    # They're both directories.
+    else:
+      # First, compare the directories' two hashes.
+      if (a.props != b.props) or (a.atts != b.atts):
+        display_nodes(a, b)
+        raise main.SVNTreeUnequal
+
+      accounted_for = []
+      # For each child of A, check and see if it's in B.  If so, run
+      # compare_trees on the two children and add b's child to
+      # accounted_for.  If not, run FUNC_A on the child.  Next, for each
+      # child of B, check and see if it's in accounted_for.  If it is,
+      # do nothing. If not, run FUNC_B on it.
+      for a_child in a.children:
+        b_child = get_child(b, a_child.name)
+        if b_child:
+          accounted_for.append(b_child)
+          compare_trees(a_child, b_child,
+                        singleton_handler_a, a_baton,
+                        singleton_handler_b, b_baton)
+        else:
+          singleton_handler_a(a_child, a_baton)
+      for b_child in b.children:
+        if (b_child not in accounted_for):
+          singleton_handler_b(b_child, b_baton)
+      return 0
+  except SVNTypeMismatch:
+    print 'Unequal Types: one Node is a file, the other is a directory'
+    raise SVNTreeUnequal
+  except SVNTreeIsNotDirectory:
+    print "Error: Foolish call to get_child."
+    sys.exit(1)
+  except IndexError:
+    print "Error: unequal number of children"
+    raise SVNTreeUnequal
+  except SVNTreeUnequal:
+    if a.name == root_node_name:
+      return 1
+    else:
+      print "Unequal at node %s" % a.name
+      raise SVNTreeUnequal
+  return 0
+
+
+
+
+# Visually show a tree's structure
+
+def dump_tree(n,indent=""):
+  "Print out a nice representation of the tree's structure."
+
+  # Code partially stolen from Dave Beazley
+  if n.children is None:
+    tmp_children = []
+  else:
+    tmp_children = n.children
+
+  if n.name == root_node_name:
+    print "%s%s" % (indent, "ROOT")
+  else:
+    print "%s%s" % (indent, n.name)
+
+  indent = indent.replace("-"," ")
+  indent = indent.replace("+"," ")
+  for i in range(len(tmp_children)):
+    c = tmp_children[i]
+    if i == len(tmp_children
+                )-1:
+      dump_tree(c,indent + "  +-- ")
+    else:
+      dump_tree(c,indent + "  |-- ")
+
+
+###################################################################
+###################################################################
+# PARSERS that return trees made of SVNTreeNodes....
+
+
+###################################################################
+# Build an "expected" static tree from a list of lists
+
+
+# Create a list of lists, of the form:
+#
+#  [ [path, contents, props, atts], ... ]
+#
+#  and run it through this parser.  PATH is a string, a path to the
+#  object.  CONTENTS is either a string or None, and PROPS and ATTS are
+#  populated dictionaries or {}.  Each CONTENTS/PROPS/ATTS will be
+#  attached to the basename-node of the associated PATH.
+
+def build_generic_tree(nodelist):
+  "Given a list of lists of a specific format, return a tree."
+
+  root = SVNTreeNode(root_node_name)
+
+  for list in nodelist:
+    new_branch = create_from_path(list[0], list[1], list[2], list[3])
+    root.add_child(new_branch)
+
+  return root
+
+
+####################################################################
+# Build trees from different kinds of subcommand output.
+
+
+# Parse co/up output into a tree.
+#
+#   Tree nodes will contain no contents, and only one 'status' att.
+
+def build_tree_from_checkout(lines):
+  "Return a tree derived by parsing the output LINES from 'co' or 'up'."
+
+  root = SVNTreeNode(root_node_name)
+  rm = re.compile ('^([MAGCUD_ ][MAGCUD_ ]) (.+)')
+  
+  for line in lines:
+    match = rm.search(line)
+    if match and match.groups():
+      new_branch = create_from_path(match.group(2), None, {},
+                                    {'status' : match.group(1)})
+      root.add_child(new_branch)
+
+  return root
+
+
+# Parse ci/im output into a tree.
+#
+#   Tree nodes will contain no contents, and only one 'verb' att.
+
+def build_tree_from_commit(lines):
+  "Return a tree derived by parsing the output LINES from 'ci' or 'im'."
+
+  # Lines typically have a verb followed by whitespace then a path.
+  root = SVNTreeNode(root_node_name)
+  rm1 = re.compile ('^(\w+)\s+(.+)')
+  rm2 = re.compile ('^Transmitting')
+  
+  for line in lines:
+    match = rm2.search(line)
+    if not match:
+      match = rm1.search(line)
+      if match and match.groups():
+        new_branch = create_from_path(match.group(2), None, {},
+                                      {'verb' : match.group(1)})
+        root.add_child(new_branch)
+
+  return root
+
+
+# Parse status output into a tree.
+#
+#   Tree nodes will contain no contents, and these atts:
+#
+#          'status', 'wc_rev', 'repos_rev'
+#             ... and possibly 'locked', 'copied', IFF columns non-empty.
+# 
+
+def build_tree_from_status(lines):
+  "Return a tree derived by parsing the output LINES from 'st'."
+
+  root = SVNTreeNode(root_node_name)
+  rm = re.compile ('^.+\:.+(\d+)')
+  lastline = string.strip(lines.pop())
+  match = rm.search(lastline)
+  if match and match.groups():
+    repos_rev = match.group(1)
+  else:
+    repos_rev = '?'
+    
+  # Try http://www.wordsmith.org/anagram/anagram.cgi?anagram=ACDRMGU
+  rm = re.compile ('^([MACDRUG_ ][MACDRUG_ ])(.)(.)   .   [^0-9-]+(\d+|-)(.{23})(.+)')
+  for line in lines:
+    match = rm.search(line)
+    if match and match.groups():
+      if match.group(5) != '-': # ignore items that only exist on repos
+        atthash = {'status' : match.group(1),
+                   'wc_rev' : match.group(4),
+                   'repos_rev' : repos_rev}
+        if match.group(2) != ' ':
+          atthash['locked'] = match.group(2)
+        if match.group(3) != ' ':
+          atthash['copied'] = match.group(3)
+        new_branch = create_from_path(match.group(6), None, {}, atthash)
+
+      root.add_child(new_branch)
+
+  return root
+
+
+####################################################################
+# Build trees by looking at the working copy
+
+
+#   The reason the 'load_props' flag is off by default is because it
+#   creates a drastic slowdown -- we spawn a new 'svn proplist'
+#   process for every file and dir in the working copy!
+
+
+def build_tree_from_wc(wc_path, load_props=0, ignore_svn=1):
+    """Takes WC_PATH as the path to a working copy.  Walks the tree below
+    that path, and creates the tree based on the actual found
+    files.  If IGNORE_SVN is true, then exclude SVN dirs from the tree.
+    If LOAD_PROPS is true, the props will be added to the tree."""
+
+    root = SVNTreeNode(root_node_name, None)
+
+    # if necessary, store the root dir's props in the root node.
+    if load_props:
+      root.props = get_props(wc_path)
+
+    # Walk the tree recursively
+    handle_dir(os.path.normpath(wc_path), root, load_props, ignore_svn)
+
+    return root
+
+### End of file.
+# local variables:
+# eval: (load-file "../../../../../tools/dev/svn-dev.el")
+# end:

Added: boost-jam/boost-build/branches/upstream/current/test/symlink.py
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/symlink.py	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/symlink.py	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,31 @@
+#!/usr/bin/python
+
+# Test the 'symlink' rule
+
+from BoostBuild import Tester, List
+import os
+t = Tester()
+
+if os.name != 'posix':
+    print "The symlink tests can be run on posix only"
+    sys.exit(1)
+
+t.write("project-root.jam", "import gcc ;")
+t.write("Jamfile", """
+exe hello : hello.cpp ;
+symlink hello_release : hello/<variant>release ; 
+symlink hello_debug : hello/<variant>debug ;
+symlink links/hello_release : hello/<variant>release ; 
+""")
+t.write("hello.cpp", """
+int main()
+{
+    return 0;
+}
+""")
+
+t.run_build_system()
+t.expect_addition(List('hello_debug.exe hello_release.exe links/hello_release.exe'))
+
+
+t.cleanup()


Property changes on: boost-jam/boost-build/branches/upstream/current/test/symlink.py
___________________________________________________________________
Name: svn:executable
   + 

Added: boost-jam/boost-build/branches/upstream/current/test/tag.py
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/tag.py	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/tag.py	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,54 @@
+#!/usr/bin/python
+
+#  Copyright (C) Pedro Ferreira 2003. Permission to copy, use, modify, sell and
+#  distribute this software is granted provided this copyright notice appears in
+#  all copies. This software is provided "as is" without express or implied
+#  warranty, and with no claim as to its suitability for any purpose.
+
+from BoostBuild import Tester, List
+
+t = Tester()
+
+t.write("project-root.jam", "")
+t.write("Jamfile", """ 
+local tags = <variant>debug:<tag>_d <variant>release:<tag>_r <link>shared:<tag>s <link>static:<tag>t ;
+exe a : a.cpp : $(tags) ;
+lib b : a.cpp : $(tags) ;
+stage c : a ;
+""")
+
+t.write("a.cpp", """ 
+int main()
+{
+    return 0;
+}
+
+#ifdef _MSC_VER
+__declspec (dllexport) void x () {} 
+#endif
+""")
+
+file_list = \
+List("bin/$toolset/debug/a_ds.exe") + \
+List("bin/$toolset/debug/b_ds.dll") + \
+List("c/a_ds.exe") + \
+List("bin/$toolset/release/a_rs.exe") + \
+List("bin/$toolset/release/b_rs.dll") + \
+List("c/a_rs.exe") + \
+List("bin/$toolset/debug/link-static/a_dt.exe") + \
+List("bin/$toolset/debug/link-static/b_dt.lib") + \
+List("c/a_dt.exe") + \
+List("bin/$toolset/release/link-static/a_rt.exe") + \
+List("bin/$toolset/release/link-static/b_rt.lib") + \
+List("c/a_rt.exe")
+
+variants = "debug release link=static,shared"
+
+t.run_build_system(variants)
+t.expect_addition(file_list)
+
+t.run_build_system(variants + " clean")
+t.expect_removal(file_list)
+
+t.cleanup()
+


Property changes on: boost-jam/boost-build/branches/upstream/current/test/tag.py
___________________________________________________________________
Name: svn:executable
   + 

Added: boost-jam/boost-build/branches/upstream/current/test/template.py
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/template.py	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/template.py	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,42 @@
+#!/usr/bin/python
+
+#  Copyright (C) Vladimir Prus 2003. Permission to copy, use, modify, sell and
+#  distribute this software is granted provided this copyright notice appears in
+#  all copies. This software is provided "as is" without express or implied
+#  warranty, and with no claim as to its suitability for any purpose.
+
+#  This file is template for Boost.Build tests. It creates a simple
+#  project that builds one exe from one source, and checks that the exe
+#  is really created.
+from BoostBuild import Tester, List
+
+# Create a temporary working directory
+t = Tester()
+
+# Create the needed files
+t.write("project-root.jam", "")
+t.write("Jamfile", """
+exe hello : hello.cpp ;
+""")
+t.write("hello.cpp", """
+int main()
+{
+    return 0;
+}
+
+""")
+
+t.run_build_system()
+
+# First, create a list of three pathnames
+file_list = List("bin/$toolset/debug/") * List("hello.exe hello.obj")
+# Second, assert that those files were added as result of the last build system invocation.
+t.expect_addition(file_list)
+
+# Invoke the build system once again
+t.run_build_system("clean")
+# Check if the files added previously were removed.
+t.expect_removal(file_list)
+
+# Remove temporary directories
+t.cleanup()


Property changes on: boost-jam/boost-build/branches/upstream/current/test/template.py
___________________________________________________________________
Name: svn:executable
   + 

Added: boost-jam/boost-build/branches/upstream/current/test/test-config-example.jam
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/test-config-example.jam	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/test-config-example.jam	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,11 @@
+
+# Skeleton for test configuration. If your local configuration 
+# interferes with testing, rename this files to 'test-system.jam'
+# and tweak it. When tests are run, only this file will be loaded,
+# while site-config.jam and user-config.jam will be ignored.
+
+import toolset : using ;
+
+using gcc ;
+using msvc : : "P:/Program Files/Microsoft Visual Studio/vc98" : : vcvars32-p.bat ;
+using borland ;
\ No newline at end of file

Added: boost-jam/boost-build/branches/upstream/current/test/test.jam
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/test.jam	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/test.jam	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,15 @@
+import indirect ;
+import string ;
+import numbers ;
+import sequence ;
+import "class" ;
+import os ;
+import path ;
+import feature ;
+import property ;
+import build-request ;
+import container ;
+
+
+actions nothing { }
+nothing all ;

Added: boost-jam/boost-build/branches/upstream/current/test/test1.py
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/test1.py	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/test1.py	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,13 @@
+#!/usr/bin/python
+
+import BoostBuild
+
+t = BoostBuild.Tester()
+
+t.write("test.jam","""
+actions unbuilt { } unbuilt all ;
+ECHO "Hi" ;
+""")
+
+t.run_build_system("-ftest.jam", stdout="Hi\n")
+t.pass_test()


Property changes on: boost-jam/boost-build/branches/upstream/current/test/test1.py
___________________________________________________________________
Name: svn:executable
   + 

Added: boost-jam/boost-build/branches/upstream/current/test/test2/Jamfile
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/test2/Jamfile	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/test2/Jamfile	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,4 @@
+
+project-root ;
+
+exe foo : foo.cpp ;
\ No newline at end of file

Added: boost-jam/boost-build/branches/upstream/current/test/test2/Jamrules
===================================================================

Added: boost-jam/boost-build/branches/upstream/current/test/test2/foo.cpp
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/test2/foo.cpp	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/test2/foo.cpp	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,10 @@
+//  Copyright (c) 2003 Vladimir Prus
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  http://www.boost.org
+// 
+
+int main() { return 0; }

Added: boost-jam/boost-build/branches/upstream/current/test/test2.py
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/test2.py	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/test2.py	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,19 @@
+#!/usr/bin/python
+
+from BoostBuild import Tester, List
+from time import sleep
+
+t = Tester()
+
+t.set_tree("test2")
+t.run_build_system("-sBOOST_BUILD_PATH=" + t.original_workdir + "/..")
+
+file_list = 'bin/foo/$toolset/debug/runtime-link-dynamic/' * List("foo foo.o")
+t.expect_addition(file_list)
+
+
+t.write("foo.cpp", "int main(int, char**) { return 0; }\n")
+t.run_build_system("-d2 -sBOOST_BUILD_PATH=" + t.original_workdir + "/..")
+t.expect_touch(file_list)
+t.pass_test()
+


Property changes on: boost-jam/boost-build/branches/upstream/current/test/test2.py
___________________________________________________________________
Name: svn:executable
   + 

Added: boost-jam/boost-build/branches/upstream/current/test/test_all.py
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/test_all.py	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/test_all.py	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,145 @@
+#!/usr/bin/python
+import os, sys, string
+from BoostBuild import get_toolset
+
+# clear environment for testing
+#
+for s in (
+    'BOOST_ROOT','BOOST_BUILD_PATH','JAM_TOOLSET','BCCROOT',
+    'MSVCDir','MSVC','MSVCNT','MINGW','watcom'
+    ):
+    
+    try:
+        del os.environ[s]
+    except:
+        pass
+
+def run_tests(critical_tests, other_tests):
+    """Runs first critical tests and then other_tests.
+
+       Stops on first error, and write the name of failed test to
+       test_results.txt. Critical tests are run in the specified order,
+       other tests are run starting with the one that failed the last time.
+    """
+    last_failed = last_failed_test()
+    other_tests = reorder_tests(other_tests, last_failed)
+    all_tests = critical_tests + other_tests
+
+    invocation_dir = os.getcwd()
+
+    failures_count = 0
+    for i in all_tests:
+        print ("%-25s : " %(i)),
+        try:
+            __import__(i)
+        except SystemExit:
+            print "FAILED"
+            if failures_count == 0:
+                f = open(os.path.join(invocation_dir, 'test_results.txt'), 'w')
+                f.write(i)
+                f.close()
+            failures_count = failures_count + 1
+            # Restore the current directory, which might be changed by the
+            # test
+            os.chdir(invocation_dir)
+            continue
+        print "PASSED"
+        sys.stdout.flush()  # makes testing under emacs more entertaining.
+        
+    # Erase the file on success
+    if failures_count == 0:
+        open('test_results.txt', 'w')
+        
+
+def last_failed_test():
+    "Returns the name of last failed test or None"
+    try:
+        f = open("test_results.txt")
+        s = string.strip(f.read())
+        return s
+    except:
+        return None
+
+def reorder_tests(tests, first_test):
+    try:
+        n = tests.index(first_test)
+        return [first_test] + tests[:n] + tests[n+1:]
+    except ValueError:
+        return tests
+
+            
+critical_tests = ["unit_tests", "module_actions", "startup_v1", "startup_v2"]
+
+critical_tests += ["core_d12", "core_typecheck", "core_delete_module",
+                   "core_varnames", "core_import_module"]
+
+tests = [ "project_test1",
+          "project_test3",
+          "project_test4",
+          "generators_test",
+          "dependency_test",
+          "path_features",
+          "relative_sources",
+          "no_type",
+          "chain",
+          "default_build",
+          "use_requirements",
+          "conditionals",
+          "stage",
+          "prebuilt",
+          "project_dependencies",
+          "build_dir",
+          "searched_lib",
+          "make_rule",
+          "alias",
+          "alternatives",
+          "default_features",
+          "print",
+          "ndebug",
+          "explicit",
+          "absolute_sources",
+          "dependency_property",
+          "custom_generator",
+          "bad_dirname",
+          "c_file",
+          "inline",
+          "conditionals2",
+          "property_expansion",
+          "loop",
+          "conditionals3",
+          "tag",
+          "suffix",
+          "inherit_toolset",
+          "skipping",
+          "project_root",
+          "glob",
+          "project_root_constants",
+          "double_loading",
+          "dll_path",
+          "regression",
+          "composite",
+          "library_chain",
+          "unit_test",
+          "standalone",
+          "expansion",
+          "wrapper",
+          "duplicate",
+          "library_property",
+          #"ordered_properties",
+          ]
+
+if os.name == 'posix':
+    tests.append("symlink")
+    # On windows, library order is not important, so skip this test
+    # Besides, it fails ;-)    
+    tests.append("library_order")
+
+if string.find(get_toolset(), 'gcc') == 0:
+    tests.append("gcc_runtime")
+
+if os.environ.has_key('QTDIR'):
+    tests.append("railsys")
+else:
+    print 'skipping railsys test since QTDIR environment variable is unset'
+
+run_tests(critical_tests, tests)

Added: boost-jam/boost-build/branches/upstream/current/test/test_nt_line_length.jam
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/test_nt_line_length.jam	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/test_nt_line_length.jam	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,41 @@
+# (C) Copyright David Abrahams 2001. Permission to copy, use,
+# modify, sell and distribute this software is granted provided this
+# copyright notice appears in all copies. This software is provided
+# "as is" without express or implied warranty, and with no claim as
+# to its suitability for any purpose.
+
+# Test that the patch which allows long command-lines in actions on NT is
+# working. For reasons of backward-compatibility, this patch requires that the
+# action fits on a single command-line, and that the JAMSHELL variable on the
+# target being built is set to "%".
+if $(NT)
+{
+    #
+    # Build a really long commandline. (> 10K characters).
+    #
+    ten = 0 1 2 3 4 5 6 7 8 9 ;
+    1x7chars = 0_____ ;
+    # add a digit and multiply by 10
+    10x8chars = $(ten)$(1x7chars) ;
+    # add a digit to each of 10 strings and multiply by 10
+    100x9chars = $(ten)$(10x8chars) ;
+    # add a digit to each of 100 strings and multiply by 10
+    1000x10chars = $(ten)$(100x9chars) ;
+
+    #
+    # Cause line_length_test to be built
+    #
+    actions do_echo
+    {
+        echo $(text)
+    }
+
+    400x10chars = $(ten[1-4])$(100x9chars) ;
+
+    text on line_length_test = $(400x10chars) 40$(10x8chars[1-9]) 01234 ;
+    text on line_length_test = $(1000x10chars) $(1000x10chars) ;
+    JAMSHELL on line_length_test = % ;
+    DEPENDS all : line_length_test ;
+
+    do_echo line_length_test ;
+}

Added: boost-jam/boost-build/branches/upstream/current/test/test_system.html
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/test_system.html	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/test_system.html	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,551 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+"http://www.w3.org/TR/html4/strict.dtd">
+
+<html>
+  <head>
+    <meta name="generator" content=
+    "HTML Tidy for Linux/x86 (vers 1st April 2002), see www.w3.org">
+    <!--tidy options: -i -wrap 78 -->
+    <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+
+    <title>A testing system for Boost.Build</title>
+
+    <style type="text/css">
+        hr { color: black }
+        p.revision { text-align: right; font-style: italic }
+        pre.code { margin-left: 2em } 
+        pre.example { margin-left: 2em; border: solid black thin } 
+        pre.output { margin-left: 2em }
+        img.banner { border: 0; float: left }
+        h1 { text-align: right }
+        br.clear { clear: left }
+        div.attention { color: red }
+    </style>
+  </head>
+
+  <body>
+    <p><a href="../../../../index.htm"><img class="banner" height="86" width=
+    "277" alt="C++ Boost" src="../../../../boost.png"></a></p>
+
+    <h1>A testing system for Boost.Build<br class="clear">
+    </h1>
+    <hr>
+
+    <dl class="page-index">
+      <dt><a href="#sec-intro">Introduction for users</a></dt>
+
+      <dt><a href="#sec-developers">Introduction for developers</a></dt>
+
+      <dd>
+        <dl class="page-index">
+          <dt><a href="#sec-intro-changing">Changing the working
+          directory</a></dt>
+
+          <dt><a href="#sec-intro-examining">Examining the working directory
+          and changing it</a></dt>
+
+          <dt><a href="#sec-intro-results">Test result</a></dt>
+        </dl>
+      </dd>
+
+      <dt><a href="#sec-reference">Reference documentation</a></dt>
+
+      <dd>
+        <dl class="page-index">
+          <dt><a href="#method-__init__">Method __init__</a></dt>
+
+          <dt><a href="#method-set_tree">Method <tt>set_tree</tt></a></dt>
+
+          <dt><a href="#method-write">Method <tt>write</tt></a></dt>
+
+          <dt><a href="#method-copy">Method <tt>copy</tt></a></dt>
+
+          <dt><a href="#method-touch">Method <tt>touch</tt></a></dt>
+
+          <dt><a href="#method-run_build_system">Method
+          <tt>run_build_system</tt></a></dt>
+
+          <dt><a href="#method-read">Method <tt>read</tt></a></dt>
+
+          <dt><a href="#method-read_and_strip">Method
+          <tt>read_and_strip</tt></a></dt>
+
+          <dt><a href="#methods-expectations">Methods for declaring
+          expectations</a></dt>
+
+          <dt><a href="#methods-ignoring">Methods for ignoring
+          changes</a></dt>
+
+          <dt><a href="#methods-result">Methods for explicitly specifying
+          results</a></dt>
+
+          <dt><a href="#class-list">Helper class <tt>List</tt></a></dt>
+        </dl>
+      </dd>
+    </dl>
+    <hr>
+
+    <h2><a name="sec-intro">Introduction for users</a></h2>
+
+    <p>The testing system for Boost.Build is a small set of Python modules
+    and scripts for automatically testing user-obversable behaviour. It uses
+    components from testing systems of <a href=
+    "http://www.scons.org">Scons</a> and <a href=
+    "http://subversion.tigris.org">Subverion</a>, together with some
+    additional functionality.</p>
+
+    <p>To run the tests you'd need:</p>
+
+    <ol>
+      <li>Get the source tree of Boost.Build (located at <tt>tools/build</tt>
+      in Boost)</li>
+
+      <li>Have <a href="http://www.python.org">Python</a> installed. Version
+      2.1 is known to work.</li>
+
+      <li>Build Boost.Jam. See <a href=
+      "../../jam_src/index.html">$boost_build_root/jam_src/index.html</a> for
+      instructions.</li>
+
+      <li>Configure at least one toolset. You can edit
+      <tt>site-config.jam</tt> or <tt>user-config.jam</tt> to add new
+      toolsets. Or you can create file <tt>test-config.jam</tt> in
+      <tt>$boost_build_root/test</tt> directory. In this case,
+      <tt>site-config.jam</tt> and <tt>user-config.jam</tt> will be ignored
+      for testing.</li>
+    </ol>
+
+    <p>When all is done, you can run the tests with</p>
+<pre class="code">
+python test_all.py
+</pre>
+
+    <p>which will use the default toolset, or you can specify toolset on the
+    command line, for example:</p>
+<pre class="code">
+python test_all.py borland
+</pre>
+
+    <p>If everything's OK, you'll see a list of passed tests. Otherwise, a
+    failure will be reported.</p>
+
+    <p>It is possible to run a specific test, for example:</p>
+<pre class="code">
+python generators_test.py
+</pre>
+
+    <h2><a name="sec-developers">Introduction for developers</a></h2>
+
+    <p>It is suggested that every new functionality come together with tests,
+    and that bugfixes are accompanied by tests. There's no need to say that
+    tests are good, but two points are extremely important:</p>
+
+    <ul>
+      <li>For an interpreted language like Jam, without any static checks,
+      testing is simply the only sefeguard we can have.</li>
+
+      <li>Good tests allow to change internal design much more safely, and we
+      didn't nailed everything down yet.</li>
+    </ul>
+
+    <p>Adding a new test is simple:</p>
+
+    <ol>
+      <li>Go to <tt>$boost_build_root/test/test_all.py</tt> and add new test
+      name to the list at the end of file. Suppose the test name is
+      "hello".</li>
+
+      <li>Add a new python module, in this example "hello.py", to do actual
+      testing.</li>
+    </ol>
+
+    <p>The module, in general will perform these basic actions:</p>
+
+    <ol>
+      <li>Setting the initial working directory state</li>
+
+      <li>
+        Running the build system and checking: 
+
+        <ol>
+          <li>generated output,</li>
+
+          <li>changes made to the working directory,</li>
+
+          <li>new content of the working directory.</li>
+        </ol>
+      </li>
+
+      <li>Adding, removing or touching files, or changing their content and
+      then repeating the previous step, until satisfied.</li>
+
+      <li>Cleaning up</li>
+    </ol>
+
+    <p>The "hello.py" module might contain:</p>
+<pre class="example">
+from BoostBuild import Tester, List
+
+# Create a temporary working directory
+t = Tester()
+
+# Create the needed files
+t.write("project-root.jam", "")
+t.write("Jamfile", """
+exe hello : hello.cpp ;
+""")
+t.write("hello.cpp", """
+int main()
+{
+    return 0;
+}
+
+""")
+
+t.run_build_system()
+
+# First, create a list of three pathnames
+file_list = List("bin/$toolset/debug/") * List("hello.exe hello.obj")
+# Second, assert that those files were added as result of the last build system invocation.
+t.expect_addition(file_list)
+
+# Invoke the build system once again
+t.run_build_system("clean")
+# Check if the files added previously were removed.
+t.expect_removal(file_list)
+
+# Remove temporary directories
+t.cleanup()
+</pre>
+
+    <p>The <tt>test</tt> directory contains a file "template.py" which can be
+    used as a start for your own tests.</p>
+
+    <p>Overview of the most important methods of class
+    <tt>TestBoostBuild</tt> follows.</p>
+
+    <h3><a name="sec-intro-changing">Changing the working directory</a></h3>
+
+    <p>The class <tt>TestBoostBuild</tt> creates a temporary directory in its
+    constructor and changes to that directory. It can be modified by calling
+    these methods:</p>
+
+    <ul>
+      <li><tt>set_tree</tt> -- sets the content of the working directory to
+      be equal to the content of the specified directory. This method is
+      preferrable when directory tree for testing is large.</li>
+
+      <li><tt>write</tt> -- sets the content of file in a working directory.
+      This is optimal if you want to create a directory tree with 3-4 small
+      files.</li>
+
+      <li><tt>touch</tt> -- changes the modification times of a file</li>
+    </ul>
+
+    <h3><a name="sec-intro-examining">Examining the working directory and
+    changing it</a></h3>
+
+    <p>The method <tt>read</tt>, inherited from the <tt>TestCmd</tt> class,
+    can be used to read any file in the working directory and check its
+    content. <tt>TestBoostBuild</tt> adds another method for tracking
+    changes. Whenever build system is run (via <tt>run_build_system</tt>),
+    the state of working dir before and after running is recorded. In
+    addition, difference between the two states -- i.e. lists of files that
+    were added, removed, modified or touched -- is stored in two member
+    variables, <tt>tree_difference</tt> and
+    <tt>unexpected_difference</tt>.</p>
+
+    <p>After than, the test author may specify that some change is expected,
+    for example, by calling <tt>expect_addition("foo")</tt>. This call will
+    check if the file was indeed added, and if so, will remove its name from
+    the list of added files in <tt>unexpected_difference</tt>. Likewise, it's
+    possible to specify that some changes are not interesting, for example a
+    call <tt>ignore("*.obj")</tt> will just remove every files with ".obj"
+    extension from <tt>unexpected_difference</tt>.</p>
+
+    <p>When test has finished with expectations and ignoring, the member
+    <tt>unexpected_difference</tt> will contain the list of all changes not
+    yet accounted for. It is possible to assure that this list is empty by
+    calling <tt>expect_nothing_more</tt> member function.</p>
+
+    <h3><a name="sec-intro-results">Test result</a></h3>
+
+    <p>Any of the <tt>expect*</tt> methods below will fail the test if the
+    expectation is not met. It is also possible to perform manually arbitrary
+    test and explicitly cause the test to either pass or fail. Ordinary
+    filesystem functions can be used to work with the directory tree. Methods
+    <tt>pass_test</tt> and <tt>fail_test</tt> are used to explicitly give the
+    test outcome.</p>
+
+    <p>Typically, after test termination, the working directory is erased. To
+    debug a failed test, you should add "--preserve" option when invoking
+    test. On failure, the working directory will be copied to "failed_test"
+    directory in the current dir.</p>
+
+    <h2 id="sec-reference">Reference documentation</h2>
+
+    <p>The test system is composed of class <tt>Tester</tt>, derived form
+    <tt>TestCmd.TestCmd</tt>, and helper class <tt>List</tt>. The methods of
+    <tt>Tester</tt>, and the class <tt>List</tt> are described below.</p>
+
+    <p>The documentation frequently refer to filename. In all cases, files
+    are specified in unix style: a sequence of components, separated by "/".
+    This is true on all platforms. In some contexts, a list of files is
+    allowed. In that case any object with sequence interface is allowed.</p>
+
+    <h3><a name="method-__init__">Method <tt>__init__(self, arguments='',
+    executable='bjam')</tt></a></h3>
+
+    <p><b>Effects:</b></p>
+
+    <ol>
+      <li>Remembers the current working directory in member
+      <tt>original_workdir</tt>.</li>
+
+      <li>Determines the location of executable (<code>bjam</code> by
+      default) and build system files, assuming that the current directory is
+      <tt>tools/build/test</tt>. Formulates jam invocation command, which
+      will include explicit setting for <tt>BOOST_BUILD_PATH</tt> variable
+      and arguments passed to this methods, if any. This command will be used
+      by subsequent invocation of <a href=
+      "#method-run_build_system"><tt>run_build_system</tt></a>. Finally,
+      initializes the base class.</li>
+
+      <li>Changes current working dir to the temporary working directory
+      created by the base constructor.</li>
+    </ol>
+
+    <h3><a name="method-set_tree">Method <tt>set_tree(self,
+    tree_location)</tt></a></h3>
+
+    <p><b>Effects:</b></p>
+
+    <p>Replaces the content of the current working directory with the content
+    of directory at <tt>tree_location</tt>. If <tt>tree_location</tt> is not
+    absolute pathname, it will be treated as relative to
+    <tt>self.original_workdir</tt>. This methods also explicitly makes the
+    copied files writeable.</p>
+
+    <h3><a name="method-write">Method <tt>write(self, name,
+    content)</tt></a></h3>
+
+    <p><b>Effects:</b></p>
+
+    <p>Writes the specified content to the file given by <tt>name</tt> under
+    the temporary working directory. If the file already exists, it is
+    overwritten. Any required directories are automatically created.</p>
+
+    <h3><a name="method-copy">Method <tt>copy(self, src, dst)</tt></a></h3>
+
+    <p><b>Effects:</b></p>
+
+    <p>Equvivalent to <tt>self.write(self.read(src), dst)</tt>.</p>
+
+    <h3><a name="method-touch">Method <tt>touch(self, names)</tt></a></h3>
+
+    <p><b>Effects:</b></p>
+
+    <p>Sets the access and modification times for all files in <tt>names</tt>
+    to the current time. All the elements in <tt>names</tt> should be
+    relative paths.</p>
+
+    <h3><a name="method-run_build_system">Method <tt>run_build_system(self,
+    subdir='', extra_args='', stdout=None, stderr='', status=0,
+    **kw)</tt></a></h3>
+
+    <p><b>Effects:</b></p>
+
+    <ol>
+      <li>Stores the state of the working directory in
+      <tt>self.previous_tree</tt>.</li>
+
+      <li>Changes to <tt>subdir</tt>, if it is specified. If it is not
+      absolute path, it is relative to the working dir.</li>
+
+      <li>Invokes the <tt>bjam</tt> executable, passing <tt>extra_args</tt>
+      to it. The binary should be located under
+      <tt>&lt;test_invocation_dir&gt;/../jam_src/bin.&lt;platform&gt;</tt>.
+      This is to make sure tests use the version of jam build from CVS.</li>
+
+      <li>Compares the stdout, stderr and exit status of build system
+      invocation with values to appropriate parameters, if they are not
+      <tt>None</tt>. If any difference is found, the test fails.</li>
+
+      <li>
+        <p>Stores the new state of the working directory in
+        <tt>self.tree</tt>. Computes the difference between previous and
+        current trees and store them in variables
+        <tt>self.tree_difference</tt> and
+        <tt>self.unexpected_difference</tt>.</p>
+
+        <p>Both variables are instances of class
+        <tt>tree.Trees_different</tt>, which have four attributes:
+        <tt>added_files</tt>, <tt>removed_files</tt>, <tt>modified_files</tt>
+        and <tt>touched_files</tt>. Each is a list of strings.</p>
+      </li>
+    </ol>
+
+    <h3><a name="method-read">Method <tt>read(self, name)</tt></a></h3>
+
+    <p><b>Effects:</b></p>
+
+    <p>Read the specified file and returns it content. Raises an exception is
+    the file is absent.</p>
+
+    <h3><a name="method-read_and_strip">Method <tt>read_and_strip(self,
+    name)</tt></a></h3>
+
+    <p><b>Effects:</b></p>
+
+    <p>Read the specified file and returns it content, after removing
+    trailing whitespace from every line. Raises an exception is the file is
+    absent.</p>
+
+    <p><b>Rationale:</b></p>
+
+    <p>Althought this method is questionable, there are a lot of cases when
+    jam or shells it uses insert spaces. It seems that introducing this
+    method is much simpler than dealing with all those cases.</p>
+
+    <h3><a name="methods-expectations">Methods for declaring
+    expectations</a></h3>
+
+    <p>Accordingly to the number of changes kinds that are detected, there
+    are four methods that specify that test author expects a specific change
+    to occur. They check <tt>self.unexpected_difference</tt>, and if the
+    change is present there, it is removed. Otherwise, test fails.</p>
+
+    <p>Each method accepts a list of names. Those names use <tt>/</tt> path
+    separator on all systems. Additionaly, the test system translates
+    suffixes appropriately. For the test to be portable, suffixes should use
+    Windows convention: <tt>exe</tt> for executables, <tt>dll</tt> for
+    dynamic libraries and <tt>lib</tt> for static libraries. Lastly, the
+    string "$toolset" in file names is replaced by the name of tested
+    toolset.</p>
+
+    <p><b>Note:</b> The <tt>List</tt> helper class might be useful to create
+    lists of names.</p>
+
+    <p><b>Note:</b> The file content can be examined using
+    <tt>TestCmd.read</tt> function.</p>
+
+    <p>The members are:</p>
+
+    <ul>
+      <li>expect_addition</li>
+
+      <li>expect_removal</li>
+
+      <li>expect_modification</li>
+
+      <li>expect_nothing</li>
+    </ul>
+
+    <p>Note that <tt>expect_modification</tt> is used to check that a either
+    file content or timestamp has changed. The rationale is that some
+    compilers change content even if sources does not change, and it's easier
+    to have a method which checks for both content and time changes.</p>
+
+    <p>There's also a member <tt>expect_nothing_more</tt>, which checks that
+    all the changes are either expected or ignored, in other words that
+    <tt>unexpected_difference</tt> is empty by now.</p>
+
+    <p>Lastly, there's a method to compare file content with expected
+    content:</p>
+    <tt>expect_content(self, name, content, exact=0)</tt> 
+
+    <p>The method fails the test if the content of file identified by 'name'
+    is different from 'content'. If 'exact' is true, the file content is used
+    as-is, otherwise, two transformations are applied:</p>
+
+    <ul>
+      <li>The <tt>read_and_strip</tt> method is used to read the file, which
+      removes trailing whitespace</li>
+
+      <li>Each backslash in the file content is converted to forward
+      slash.</li>
+    </ul>
+
+    <h3><a name="methods-ignoring">Methods for ignoring changes</a></h3>
+
+    <p>There are five methods which ignore changes made to the working tree.
+    They silently remove elements from <tt>self.unexpected_difference</tt>,
+    and don't generate error if element is not found. They accept shell style
+    wildcard.</p>
+
+    <p>The following methods correspond to four kinds of changes:</p>
+
+    <ul>
+      <li>ignore_addition(self, wildcard)</li>
+
+      <li>ignore_removal(self, wildcard)</li>
+
+      <li>ignore_modification(self, wildcard)</li>
+
+      <li>ignore_touch(self, wilcard)</li>
+    </ul>
+
+    <p>The method <tt>ignore(self, wildcard)</tt> ignores all the changes
+    made to files that match a wildcard.</p>
+
+    <h3><a name="methods-result">Methods for explicitly specifying
+    results</a></h3>
+
+    <h4>Method <tt>pass_test(self, condition=1)</tt></h4>
+
+    <div class="attention">
+      At this moment, the method should not be used.
+    </div>
+
+    <h4>Method <tt>fail_test(self, condition=1)</tt></h4>
+
+    <p><b>Effects:</b> Cause the test to fail if <tt>condition</tt> is
+    true.</p>
+
+    <h3><a name="class-list">Helper class <tt>List</tt></a></h3>
+    The class has sequence interface and two additional methods. 
+
+    <h4>Method <tt>__init__(self, string)</tt></h4>
+
+    <p><b>Effects:</b> Splits the string on unescaped spaces and tabs. The
+    split components can further be retrieved using standard sequence
+    access.</p>
+
+    <h4>Method <tt>__mul__(self, other)</tt></h4>
+
+    <p><b>Effects:</b> Returns an <tt>List</tt> instance, which elements are
+    all possible concatenations of two string, first of which is from
+    <tt>self</tt>, and second of which is from <tt>other</tt>.</p>
+
+    <p>The class also defines <tt>__str__</tt> and <tt>__repr__</tt> methods.
+    Finally, there's <tt>__coerce__</tt> method which allows to convert
+    strings to instances of <tt>List</tt>.</p>
+
+    <p><b>Example:</b></p>
+<pre>
+    l = "a b" * List("c d")
+    for e in l:
+        print e        
+   
+</pre>
+
+    <p>will output</p>
+<pre>
+    ac
+    ad
+    bc
+    bd
+   
+</pre>
+    <hr>
+
+    <p class="revision">Last modified: Mar 3, 2003</p>
+
+    <p>&copy; Copyright Vladimir Prus 2002, 2003. Permission to copy, use,
+    modify, sell and distribute this document is granted provided this
+    copyright notice appears in all copies. This document is provided ``as
+    is'' without express or implied warranty, and with no claim as to its
+    suitability for any purpose.</p>
+  </body>
+</html>
+

Added: boost-jam/boost-build/branches/upstream/current/test/testing-primitives/boost-build.jam
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/testing-primitives/boost-build.jam	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/testing-primitives/boost-build.jam	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1 @@
+boost-build . ;

Added: boost-jam/boost-build/branches/upstream/current/test/testing-primitives/bootstrap.jam
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/testing-primitives/bootstrap.jam	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/testing-primitives/bootstrap.jam	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,133 @@
+# Proof-of-concept for bjam-based testing mechanism. This file should
+# work on NT, Cygwin, and Linux. No promises for other platforms.
+
+# Set a variable which says how to dump a file to stdout
+if $(NT)
+{ 
+    CATENATE = type ;
+}
+else
+{
+    CATENATE = cat ;
+}
+
+# invoke the given action rule `act' to build target from sources
+rule do-make ( target : sources * : act )
+{
+    DEPENDS $(target) : $(sources) ;
+    $(act) $(target) : $(sources) ;
+}
+
+# top-level version of do-make which causes target to be built by
+# default
+rule make ( target : sources * : act )
+{
+    DEPENDS all : $(target) ;
+    do-make $(target) : $(sources) : $(act) ;
+}
+
+# cause `target' to exist and building to succeed if invoking
+#
+#    $(act) $(target) : $(sources)
+#
+# fails, and to fail if the action succeeds.
+rule make-fail ( target : sources * : act )
+{
+    # Establish another logical target which refers to the same file,
+    # by using different grist.
+    DEPENDS all : <different-grist>$(target) ;
+    
+    # Make the new logical target depend on the target
+    DEPENDS <different-grist>$(target) : $(target) ;
+    
+    # Cause the target to be built from sources using $(act).
+    do-make $(target) : $(sources) : $(act) ;
+    
+    # Note that we expect target to fail to build
+    FAIL_EXPECTED $(target) ;
+    
+    # Build a failure marker file. Because targets are only built if
+    # all their dependents "succeed", the marker will only be
+    # generated if $(target) failed to build, as expected.
+    failure-marker <different-grist>$(target) ;
+}
+
+# Simple action rules which write text into the target. Different
+# names for different purposes.
+actions failure-marker
+{
+    echo failed as expected > $(<)
+}
+
+actions create
+{
+    echo creating > $(<)
+}
+
+# An action which will always fail, for testing expected failure rules
+actions fail-to-create
+{
+    exit 1
+}
+
+# Basic rule-action pair which builds the target by executing the
+# given commands
+rule do-run ( target : commands + )
+{
+    COMMANDS on $(target) = $(commands) ;
+    NOTFILE $(commands) ;
+}
+
+# Run commands, leaving the output behind in $(<:S=.out). Echo to
+# stdout if the command fails.
+#
+#  Detailed explanation:
+#
+#  $(COMMANDS)                          Run commands
+#       > $(<:S=.out)                   into the output file
+#       2>&1                            including stderr
+#     &&                                and if that succeeds
+#       cp -f $(<:S=.out) $(<)          copy the output file into the target
+#  ||                                   otherwise
+#     ( $(CATENATE) $(<:S=.out)         dump any output to stdout
+#       && exit 1                       and exit with an error code
+#     )
+actions do-run
+{
+    $(COMMANDS) > $(<:S=.out) 2>&1 && cp -f $(<:S=.out) $(<) || ( $(CATENATE) $(<:S=.out) && exit 1 )
+}
+
+# top-level version of do-run which causes target to be built by
+# default
+rule run ( target : commands + )
+{
+    DEPENDS all : $(target) ;
+    do-run $(target) : $(commands) ;
+}
+
+# experimental expected-failure version of run. This doesn't have
+# quite the right semantics w.r.t. output dumping (it is still only
+# dumped if the run fails), but we don't need run-fail anyway so it
+# doesn't matter too much.
+rule run-fail ( target : commands + )
+{
+    make-fail $(target) : $(commands) : do-run ;
+}
+
+# A command which will always fail to run.  There is no file called
+# nonexistent, so executing $(error) always causes an error. We can't
+# just use `exit 1' below because that will cause all command
+# processing to stop, and we want the rest of the do-run action
+# command-line to execute.
+error = $(CATENATE)" nonexistent" ;
+
+make-fail t1.txt : : create ;
+make-fail t2.txt : : fail-to-create ;
+make t3.txt : : create ;
+make t4.txt : : fail-to-create ;
+
+run t5.txt : "( echo failing t5 && $(error) )" ;
+run t6.txt : echo hi ;
+
+run-fail t7.txt : "( echo failing t7 && $(error) )" ;
+run-fail t8.txt : echo hi ;

Added: boost-jam/boost-build/branches/upstream/current/test/testing_primitives.py
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/testing_primitives.py	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/testing_primitives.py	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,33 @@
+#!/usr/bin/python
+
+from BoostBuild import Tester, List
+import os
+from string import strip
+import re
+
+def match_re(actual,expected):
+    return re.match(expected,actual,re.DOTALL) != None
+
+t = Tester(match = match_re)
+
+t.set_tree('testing-primitives')
+
+# We expect t5 and t7's output to be dumped to stdout
+t.run_build_system(stdout=r'''.*failing t5.*failing t7''')
+
+t.expect_addition('t2.txt')
+t.expect_addition('t3.txt')
+
+t.expect_addition('t5.out')
+
+t.expect_addition('t6.out')
+t.expect_addition('t6.txt')
+
+t.expect_addition('t7.out')
+t.expect_addition('t7.txt')
+
+t.expect_addition('t8.out')
+
+t.expect_nothing_more()
+t.cleanup()
+print 'tesing complete'

Added: boost-jam/boost-build/branches/upstream/current/test/tree.py
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/tree.py	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/tree.py	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,119 @@
+# Copyright (C) 2001 Vladimir Prus. Permission to copy, use, modify, sell and
+# distribute this software is granted, provided this copyright notice appears
+# in all copies and modified versions are clearly marked as such. This software
+# is provided "as is" without express or implied warranty, and with no claim as
+# to is suitability for any purpose.
+
+# This file is based in part on the content of svn_tree.py.
+
+import svn_tree;
+
+class Trees_difference:
+
+    def __init__(self):
+        self.added_files = []
+        self.removed_files = []
+        self.modified_files = []
+        self.touched_files = []
+
+    def append(self, other):
+        self.added_files.extend(other.added_files)
+        self.removed_files.extend(other.removed_files)
+        self.modified_files.extend(other.modified_files)
+        self.touched_files.extend(other.touched_files)
+     
+    def ignore_directories(self):
+        "Removes directories for list of found differences"
+
+        def not_dir(x):
+            return x[-1] != "/"
+        self.added_files = filter(not_dir, self.added_files)
+        self.removed_files = filter(not_dir, self.removed_files)
+        self.modified_files = filter(not_dir, self.modified_files)
+        self.touched_files = filter(not_dir, self.touched_files)
+
+    def pprint(self):
+        print "Added files   :", self.added_files
+        print "Removed files :", self.removed_files
+        print "Modified files:", self.modified_files
+        print "Touched files :", self.touched_files
+
+    def empty(self):
+        return (len(self.added_files) == 0 and len(self.removed_files) == 0)\
+                and len(self.modified_files) == 0 and len(self.touched_files) == 0
+
+def build_tree(dir):
+    return svn_tree.build_tree_from_wc(dir, load_props=0, ignore_svn=1)
+
+def trees_difference(a, b, current_name=""):
+    """Compare SVNTreeNodes A and B, and create Trees_difference class."""
+
+    assert a.name == b.name
+
+    result = Trees_difference()
+    try:
+        # A and B are both files.
+        if ((a.children is None) and (b.children is None)):
+            assert a.name == b.name
+            if svn_tree.compare_file_nodes(a, b):
+                result.modified_files.append(current_name)
+            elif (a.mtime != b.mtime):
+                result.touched_files.append(current_name)
+
+        # One is a file, one is a directory.
+        # this case is disabled because svn_tree doesn't distinguish
+        # empty directories from files, at least on Cygwin.
+        elif 0 and (((a.children is None) and (b.children is not None))
+            or ((a.children is not None) and (b.children is None))):
+            a.pprint()
+            b.pprint()
+            raise svn_tree.SVNTypeMismatch
+        # They're both directories.
+        else:
+            # accounted_for holds childrens present in both trees
+            accounted_for = []
+            for a_child in (a.children or []):
+                b_child = svn_tree.get_child(b, a_child.name)
+                if b_child:
+                    accounted_for.append(b_child)
+                    if current_name:
+                        result.append(trees_difference(a_child, b_child, current_name + "/" + a_child.name))
+                    else:
+                        result.append(trees_difference(a_child, b_child, a_child.name))
+                else:
+                    if current_name:
+                        result.removed_files.append(current_name + "/" + a_child.name)
+                    else:
+                        result.removed_files.append(a_child.name)
+            for b_child in (b.children or []):
+                if (b_child not in accounted_for):
+                    result.added_files.extend(traverse_tree(b_child, current_name))
+
+    except svn_tree.SVNTypeMismatch:
+        print 'Unequal Types: one Node is a file, the other is a directory'
+        raise svn_tree.SVNTreeUnequal
+    except svn_tree.SVNTreeIsNotDirectory:
+        print "Error: Foolish call to get_child."
+        sys.exit(1)
+    except IndexError:
+        print "Error: unequal number of children"
+        raise svn_tree.SVNTreeUnequal
+    return result
+
+def dump_tree(t):
+    svn_tree.dump_tree(t)
+
+def traverse_tree(t, parent_name=""):
+    """ Returns the list of all names in tree. """
+    if parent_name:
+        full_node_name = parent_name + "/" + t.name
+    else:
+        full_node_name = t.name
+
+    if (t.children is None):
+        result = [full_node_name]
+    else:
+        result = [full_node_name + "/"]
+        for i in t.children:
+            result.extend(traverse_tree(i, full_node_name))
+    return result

Added: boost-jam/boost-build/branches/upstream/current/test/unit-tests.jam
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/unit-tests.jam	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/unit-tests.jam	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,264 @@
+# (C) Copyright David Abrahams 2001. Permission to copy, use,
+# modify, sell and distribute this software is granted provided this
+# copyright notice appears in all copies. This software is provided
+# "as is" without express or implied warranty, and with no claim as
+# to its suitability for any purpose.
+
+# assert_equal a : b
+#
+# exits with an assertion failure if a != b
+rule assert_equal
+{
+    if $(<) != $(>)
+    {
+        EXIT "assertion failure: [" $(<) "] != [" $(>) "]" ;
+    }
+}
+
+rule assert_equal_sets
+{
+    if ! [ equal-sets $(<) : $(>) ]
+    {
+        EXIT "assertion failure: [" $(<) "] !=(set) [" $(>) "]" ;
+    }
+}
+
+# FAppendSuffix
+assert_equal [ FAppendSuffix yacc lex foo.bat : ] : yacc lex foo.bat ;
+assert_equal [ FAppendSuffix yacc lex foo.bat : .exe ] : yacc.exe lex.exe foo.bat ;
+assert_equal [ FAppendSuffix yacc lex foo.bat : .dll .lib ] : yacc.dll yacc.lib lex.dll lex.lib foo.bat foo.lib ;
+
+# sort
+assert_equal [ sort 7 3 5 6 2 4 ] : 2 3 4 5 6 7 ;
+
+# min
+assert_equal [ min 7 3 5 6 2 4 ] : 2 ;
+
+# difference
+assert_equal [ difference 0 1 2 3 4 5 6 7 8 9 : 2 3 5 7 ] : 0 1 4 6 8 9 ;
+
+# replace
+assert_equal [ replace 1 3 5 7 7 9 2 5 4 3 1 : 7 x ] : 1 3 5 x x 9 2 5 4 3 1 ;
+
+# select-ungristed
+assert_equal [ select-ungristed <a>b c <d>e f ] : c f ;
+
+# split-qualified-property
+assert_equal [ split-qualified-property <feature>value ]
+    : <*> <*> <feature>value ;
+    
+assert_equal [ split-qualified-property <variant><feature>value ]
+    : <*> <variant> <feature>value ;
+    
+assert_equal [ split-qualified-property <toolset><variant><feature>value ]
+    : <toolset> <variant> <feature>value ;
+
+# unique
+assert_equal [ unique 0 1 2 3 1 7 6 6 4 5 ] : 0 1 2 3 7 6 4 5 ;
+
+# get-properties
+assert_equal [ get-properties <foo> <bar> : <foo>bar <foo>baz <bar>fight <baz>niss ]
+    : <foo>bar <foo>baz <bar>fight ;
+
+# get-values
+assert_equal [ get-values <foo> : <foo>bar <foo>baz <bar>fight <baz>niss ] : bar baz ;
+
+# normalize-properties
+assert_equal [ normalize-properties <a>b <c><d>e <f><g><h>i ] :
+     <*><*><a>b <*><c><d>e <f><g><h>i ;
+
+# intersection
+assert_equal [ intersection 1 2 2 3 3 4 5 6 7 : 5 1 3 7 3 9 11 ] : 1 3 3 5 7 ;
+
+# is-subset
+assert_equal [ is-subset a b c : c a b d ] : true ;
+assert_equal [ is-subset a b z : c a b d ] : ;
+
+# split-path
+assert_equal [ split-path <a>b/c/<d>e ] : <a>b c <d>e ;
+assert_equal [ split-path <a>/<d>/<e> ] : <a> <d> <e> ;
+assert_equal [ split-path <a> ] : <a> ;
+assert_equal [ split-path x ] : x ;
+assert_equal [ split-path $(DOT) ] : $(DOT) ;
+assert_equal [ split-path a/b.c/d.e/f ] : a b.c d.e f ;
+if $(NT)
+{
+    assert_equal [ split-path x:\\y\\z\\w ] : x: y z w ;
+    assert_equal [ split-path x:\\y\\z ] : x: y z ;
+    assert_equal [ split-path x:\\y ] : x: y ;
+    assert_equal [ split-path x:\\ ] : x: ;
+    assert_equal [ split-path x: ] : x: ;
+}
+
+# distribute-feature
+assert_equal [ distribute-feature <feature>value1 ] : <feature>value1 ;
+assert_equal [ distribute-feature <feature>value1/value2 ] : <feature>value1 <feature>value2 ;
+assert_equal [ distribute-feature <feature>value1/value2/value3 ] : <feature>value1 <feature>value2 <feature>value3 ;
+
+# segregate-free-properties
+{
+    local gFREE_FEATURES = <a> <c> <e> ;
+    local x = <a>b <b>c <d>e ;
+    local y = <a>b <a>c <b>c <e>f ;
+    local free = [ segregate-free-properties x y ] ;
+    assert_equal $(free) : <a>b <a>c <e>f ;
+    assert_equal $(x) : <b>c <d>e ;
+    assert_equal $(y) : <b>c ;
+}
+
+# set-insert
+{
+    local gTEST_SET = 1 2 3 ;
+    set-insert gTEST_SET : 2 ;
+    assert_equal $(gTEST_SET) : 1 2 3 ;
+    set-insert gTEST_SET : 0 ;
+    assert_equal $(gTEST_SET) : 1 2 3 0 ;
+}
+
+# equal-sets
+assert_equal [ equal-sets 1 2 3 : 3 2 2 1 ] : true ;
+assert_equal [ equal-sets 1 2 3 3 : 3 2 2 1 ] : true ;
+assert_equal [ equal-sets 1 2 3 3 4 : 3 2 2 1 ] : ;
+
+# segregate-overrides
+{
+    local base = <a>b <c>d <e>f ;
+    local overrides = <a>b <c>c <d>e <f>g ;
+    segregate-overrides overrides : base ;
+    assert_equal $(overrides) : <c>c <d>e <f>g ;
+    assert_equal $(base) : <a>b <e>f ;
+}
+
+# select-properties
+{
+    local TOOLS = gcc msvc ;
+    
+    local gRELEVANT_FEATURES(msvc)  = <debug-symbols> <optimization> <inlining> <inline> <runtime-build> <runtime-link> <threading> <define> <undef> <include> <target-type> ;
+    local gRELEVANT_FEATURES(gcc)  = <runtime-link> <debug-symbols> <optimization> <inlining> <profiling> <define> <undef> <include> <shared-linkable> <target-type> ;
+    local gFREE_FEATURES =  <define> <undef> <include> ;
+    
+    local gBASE_PROPERTIES(msvc,debug)  = <debug-symbols>on <inlining>off <optimization>off <runtime-build>debug <threading>single ;
+    local gBASE_PROPERTIES(gcc,debug)  = <debug-symbols>on <inlining>off <optimization>off <profiling>off <shared-linkable>false ;
+    local gBASE_PROPERTIES(msvc,release)  = <debug-symbols>off <define>NDEBUG <inlining>full <optimization>speed <runtime-build>release <threading>single ;
+    local gBASE_PROPERTIES(gcc,release)  = <debug-symbols>off <define>NDEBUG <inlining>full <optimization>speed <profiling>off <shared-linkable>false ;
+    
+    local TEST_PROPERTIES = <inlining>off <define>FOO <*><release><inlining>on
+                  <debug><define>DEBUG <msvc><release><foo>bar
+                  <gcc><*><inlining>on
+                  <msvc><*><foo>baz
+                  <msvc><release><optimization>speed
+                  <msvc><*><optimization>off
+                  <*><debug><optimization>off
+                  ;
+                  
+    assert_equal_sets [ select-properties gcc debug my-target : $(TEST_PROPERTIES) ]
+        : <define>FOO <define>DEBUG <inlining>on <optimization>off ;
+
+    assert_equal_sets [ select-properties gcc release my-target : $(TEST_PROPERTIES) ]
+        : <define>FOO <inlining>on ;
+
+    assert_equal_sets [ select-properties msvc debug my-target : $(TEST_PROPERTIES) ]
+        : <define>FOO <define>DEBUG <inlining>off <optimization>off ;
+
+    assert_equal_sets [ select-properties msvc release my-target : $(TEST_PROPERTIES) ]
+        : <define>FOO <inlining>on <optimization>speed ;
+}
+
+
+# ungrist-properties
+feature TEST_FEATURE1 : a b ;
+feature TEST_FEATURE2 : c d ;
+assert_equal [ ungrist-properties <TEST_FEATURE1>a <TEST_FEATURE2>c ]
+    : TEST_FEATURE1-a TEST_FEATURE2-c ;
+
+
+# fixup-path-properties
+{
+    local RELATIVE_SUBDIR = foobar ;
+    local gPATH_FEATURES = <include> ;
+    assert_equal [ fixup-path-properties <a>b <include>.. <c>d ]
+                : <include>foobar$(SLASH).. <a>b <c>d ;
+}
+# multiply-property-sets
+assert_equal [ multiply-property-sets <b>1 <a>2/3 <c>4/5 ]
+    : <a>2/<b>1/<c>4 <a>2/<b>1/<c>5 <a>3/<b>1/<c>4 <a>3/<b>1/<c>5 ;
+
+# make-path-property-sets
+{
+    local gUNGRISTED(<a>) = a ;
+    local gUNGRISTED(<c>) = c ;
+    local gUNGRISTED(<e>) = e ;
+    local gUNGRISTED(<g>) = g ;
+    local gUNGRISTED(<i>) = i ;
+    assert_equal [ make-path-property-sets foo$(SLASH)bar : <a>b <c>d : <e>f$(SLASH)<g>h <i>j ]
+    : foo$(SLASH)bar$(SLASH)e-f$(SLASH)g-h$(SLASH)<a>b$(SLASH)<c>d$(SLASH)<e>f$(SLASH)<g>h foo$(SLASH)bar$(SLASH)i-j$(SLASH)<a>b$(SLASH)<c>d$(SLASH)<i>j ;
+    assert_equal [ make-path-property-sets foo$(SLASH)bar : <a>b <c>d : ]
+    : foo$(SLASH)bar$(SLASH)<a>b$(SLASH)<c>d ;
+}
+
+
+# split-path-at-grist
+assert_equal
+ [ split-path-at-grist <a>b$(SLASH)c$(SLASH)<d>e$(SLASH)<f>g$(SLASH)h$(SLASH)i ]
+ : <a>b$(SLASH)c <d>e <f>g$(SLASH)h$(SLASH)i ;
+assert_equal
+ [ split-path-at-grist b$(SLASH)c$(SLASH)<d>e$(SLASH)<f>g$(SLASH)h$(SLASH)i ]
+ : b$(SLASH)c <d>e <f>g$(SLASH)h$(SLASH)i ;
+if $(NT)
+{
+    assert_equal
+        [ split-path-at-grist b\\c\\<include>e:\\f\\g\\<h>i ]
+        : b\\c <include>e:\\f\\g <h>i ;
+}
+# directory-of
+assert_equal [ directory-of a$(SLASH)b c d$(SLASH)e$(SLASH)f ] : a . d$(SLASH)e ;
+
+# top-relative-tokens
+{
+    local SUBDIR_TOKENS = a b c ;
+    assert_equal [ top-relative-tokens ..$(SLASH)d$(SLASH)e ] : a b d e ;
+}
+
+# flags
+{
+    local gBUILD_PROPERTIES = <a>b <c>d <e>f ;
+    local FLAGS1 FLAGS2 FLAGS3 ;
+    flags toolset FLAGS1 <a>b/<c>d <a>b/<e>f <x>y <a>/<c> <e> : foobar ;
+    assert_equal $(FLAGS1) : foobar b d f ;
+    flags toolset FLAGS2 <a> : foobar ;
+    assert_equal $(FLAGS2) : b ;
+    flags toolset FLAGS1 <a>b/<c>d <a>b/<e>f : foobar ;
+    assert_equal $(FLAGS1) : foobar b d f foobar ;
+}
+
+# get-BUILD
+{
+    local DEFAULT_BUILD = a ;
+    local BUILD = b ;
+    assert_equal [ get-BUILD c <d>e ] : b ;
+    BUILD = ;
+    assert_equal [ get-BUILD c <d>e ] : c <d>e ;
+    assert_equal [ get-BUILD ] : a ;
+    assert_equal [ get-BUILD <d>e ] : <d>e a ;
+    BUILD = <f>g ;
+    assert_equal [ get-BUILD c <d>e ] : <f>g a ;
+}
+
+# strip-initial
+assert_equal [ strip-initial a b c : a b c d e f g ] : d e f g ;
+assert_equal [ strip-initial a b c : a b d e f g ] : a b d e f g ;
+assert_equal [ strip-initial a b c : b d e f g ] : b d e f g ;
+assert_equal [ strip-initial a b c : ] :  ;
+
+# simplify-path-tokens
+{
+    local $(gTOP)_TOKENS = .. .. .. ;
+    local gINVOCATION_SUBDIR_TOKENS = d e ;
+    assert_equal [ simplify-path-tokens a b . c .. .. d e ] : a d e ;
+    assert_equal [ simplify-path-tokens a b .. .. .. d e ] : .. d e ;
+    assert_equal [ simplify-path-tokens .. .. d e : xxx ] : .. .. d e ;
+    assert_equal [ simplify-path-tokens a b .. .. : xxx ] : xxx ;
+    $(gTOP)_TOKENS = .. .. ;
+    assert_equal [ simplify-path-tokens .. .. d e : xxx ] : xxx ; 
+    assert_equal [ simplify-path-tokens .. .. d e f g : xxx ] : f g ; 
+}
\ No newline at end of file

Added: boost-jam/boost-build/branches/upstream/current/test/unit_test.py
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/unit_test.py	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/unit_test.py	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,44 @@
+#!/usr/bin/python
+
+#  Copyright (C) Vladimir Prus 2003. Permission to copy, use, modify, sell and
+#  distribute this software is granted provided this copyright notice appears in
+#  all copies. This software is provided "as is" without express or implied
+#  warranty, and with no claim as to its suitability for any purpose.
+
+#  Test the unit_test rule
+from BoostBuild import Tester, List
+
+t = Tester()
+
+# Create the needed files
+t.write("project-root.jam", """
+using testing ;
+""")
+t.write("Jamfile", """
+lib helper : helper.cpp ;
+unit-test test : test.cpp : <library>helper ;
+""")
+t.write("test.cpp", """
+void helper();
+int main()
+{
+    helper();
+    return 0;
+}
+""")
+
+t.write("helper.cpp", """
+void
+#if defined(_WIN32)
+__declspec(dllexport)
+#endif
+helper() {}
+""")
+
+t.run_build_system("link=static")
+t.expect_addition("bin/$toolset/debug/link-static/test.passed")
+
+
+
+
+t.cleanup()


Property changes on: boost-jam/boost-build/branches/upstream/current/test/unit_test.py
___________________________________________________________________
Name: svn:executable
   + 

Added: boost-jam/boost-build/branches/upstream/current/test/unit_tests.py
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/unit_tests.py	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/unit_tests.py	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,8 @@
+#!/usr/bin/python
+
+from BoostBuild import Tester
+
+t = Tester(pass_toolset=0)
+t.run_build_system(extra_args="--debug --build-system=test")
+
+t.cleanup()


Property changes on: boost-jam/boost-build/branches/upstream/current/test/unit_tests.py
___________________________________________________________________
Name: svn:executable
   + 

Added: boost-jam/boost-build/branches/upstream/current/test/unused/Jamfile
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/unused/Jamfile	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/unused/Jamfile	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,7 @@
+
+exe a : a.cpp b c ;
+
+make-b-main-target ;
+
+# Expands to nothing, intentionally.
+alias c ;
\ No newline at end of file

Added: boost-jam/boost-build/branches/upstream/current/test/unused/a.cpp
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/unused/a.cpp	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/unused/a.cpp	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,9 @@
+// Copyright Vladimir Prus 2003.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt
+// or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+int main()
+{
+    return 0;
+}

Added: boost-jam/boost-build/branches/upstream/current/test/unused/b.cpp
===================================================================

Added: boost-jam/boost-build/branches/upstream/current/test/unused/b.x
===================================================================

Added: boost-jam/boost-build/branches/upstream/current/test/unused/project-root.jam
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/unused/project-root.jam	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/unused/project-root.jam	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,53 @@
+
+import type ;
+import generators ;
+import print ;
+import virtual-target ;
+import "class" : new ;
+import modules ;
+import targets ;
+
+
+type.register X : x ;
+
+class test-target-class : basic-target
+{
+    rule __init__ ( name : project )
+    {
+        basic-target.__init__ $(name) : $(project) ;
+    }
+        
+    rule construct ( source-targets * : property-set )
+    {
+        if [ modules.peek : GENERATE_NOTHING ]
+        {
+            return ;
+        }
+        else if [ modules.peek : GENERATE_ONLY_UNUSABLE ] 
+        {
+            return [ virtual-target.from-file b.x : $(self.project) ] 
+              ;             
+        }
+        else
+        {            
+            return [ virtual-target.from-file b.x : $(self.project) ] 
+              [ virtual-target.from-file b.cpp : $(self.project) ] 
+                ; 
+        }        
+    }
+    
+    rule compute-usage-requirements ( rproperties : targets * )
+    {
+        return [ property-set.create <define>FOO ] ;
+    }
+}
+
+rule make-b-main-target
+{
+    local project = [ CALLER_MODULE ] ;    
+    
+    targets.main-target-alternative 
+      [ new test-target-class b : $(project) ] ;
+}
+
+IMPORT $(__name__) : make-b-main-target : : make-b-main-target ;

Added: boost-jam/boost-build/branches/upstream/current/test/unused.py
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/unused.py	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/unused.py	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,32 @@
+#!/usr/bin/python
+
+# Test that unused sources are at least reported.
+
+from BoostBuild import Tester
+from string import find
+t = Tester()
+
+t.set_tree("unused")
+
+t.run_build_system()
+# The second invocation should do nothing, and produce
+# no warning. The previous invocation might have printed
+# executed actions and other things, so it's not easy
+# to check if warning was issued or not.
+t.run_build_system()
+t.fail_test(find(t.stdout(), "warning: Unused source { b.X } in main target ./a") == -1)
+
+t.run_build_system("-sGENERATE_ONLY_UNUSABLE=1")
+t.fail_test(find(t.stdout(), "warning: Unused source { b.X } in main target ./a") == -1)
+
+# Now check that even if main target generates nothing, its
+# usage requirements are still propagated to dependents.
+t.write("a.cpp","""
+#ifdef FOO
+int main() {}
+#endif
+""")
+t.run_build_system("-sGENERATE_NOTHING=1")
+
+t.cleanup()
+


Property changes on: boost-jam/boost-build/branches/upstream/current/test/unused.py
___________________________________________________________________
Name: svn:executable
   + 

Added: boost-jam/boost-build/branches/upstream/current/test/use_requirements.py
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/use_requirements.py	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/use_requirements.py	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,307 @@
+#!/usr/bin/python
+
+from BoostBuild import Tester
+t = Tester()
+
+# Test that use requirements on main target work
+t.write("project-root.jam", "import gcc ;")
+
+t.write(
+    "Jamfile",
+"""
+    lib b : b.cpp : <link>shared:<define>SHARED_B
+    : : <define>FOO <link>shared:<define>SHARED_B
+    ;
+    exe a : a.cpp b ;
+""")
+
+t.write(
+    "b.cpp",
+"""
+void
+#if defined(_WIN32) && defined(SHARED_B)
+__declspec(dllexport)
+#endif
+foo() {}\n
+""")
+
+t.write(
+    "a.cpp",
+"""
+#ifdef FOO
+void
+# if defined(_WIN32) && defined(SHARED_B)
+__declspec(dllexport)
+# endif
+foo() {}
+#endif
+
+int main() { foo(); }
+""")
+
+t.run_build_system()
+
+t.run_build_system("--clean")
+
+# Test that use requirements on main target work, when they are referred using
+# 'dependency' features.
+t.write("project-root.jam", "import gcc ;")
+
+t.write(
+    "Jamfile", 
+"""
+    lib b : b.cpp : <link>shared:<define>SHARED_B
+    : : <define>FOO <link>shared:<define>SHARED_B
+    ;
+    exe a : a.cpp : <use>b ;
+""")
+
+t.write(
+    "b.cpp",
+"""
+void
+#if defined(_WIN32) && defined(SHARED_B)
+__declspec(dllexport)
+#endif
+foo() {}
+""")
+
+t.write(
+    "a.cpp",
+"""
+#ifdef FOO
+int main() { return 0; }
+#endif
+""")
+
+t.run_build_system()
+
+t.run_build_system("--clean")
+
+
+# Test that use requirement on project work
+t.write("Jamfile", "exe a : a.cpp lib//b ;")
+
+t.write(
+    "lib/Jamfile", 
+"""
+project
+   : requirements <link>shared:<define>SHARED_B
+   : usage-requirements <define>FOO <link>shared:<define>SHARED_B
+    ;
+lib b : b.cpp ;
+""")
+
+t.write(
+    "lib/b.cpp", 
+"""
+void
+#if defined(_WIN32) && defined(SHARED_B)
+__declspec(dllexport)
+#endif
+foo() {}\n
+""")
+
+t.run_build_system()
+
+# Test that use requirements are inherited correctly
+
+t.write("Jamfile", "exe a : a.cpp lib/1//b ;")
+
+t.write(
+    "a.cpp", 
+"""
+#if defined(FOO) && defined(ZOO)
+void foo() {}
+#endif
+
+int main() { foo(); }
+""")
+
+t.write(
+    "lib/Jamfile", 
+"""
+project
+   : requirements
+   : usage-requirements <define>FOO
+    ;
+""")
+
+t.write(
+    "lib/1/Jamfile", 
+"""
+project
+   : requirements <link>shared:<define>SHARED_B
+   : usage-requirements <define>ZOO <link>shared:<define>SHARED_B 
+   ;
+lib b : b.cpp ;
+""")
+
+t.write(
+    "lib/1/b.cpp", 
+"""
+void
+#if defined(_WIN32) && defined(SHARED_B)
+__declspec(dllexport)
+#endif
+foo() {}\n
+""")
+
+t.run_build_system()
+t.run_build_system("--clean")
+
+# Test that we correctly handle dependency features
+# in use requirements on target
+
+t.write(
+    "Jamfile", 
+"""
+    lib b : b.cpp : <link>shared:<define>SHARED_B 
+    : : <define>FOO <link>shared:<define>SHARED_B
+    ;
+    
+    # Here's the test: we should correctly
+    # handle dependency feature and get
+    # use requirements from 'b'.
+    lib c : c.cpp : <link>shared:<define>SHARED_C : : <library>b ;
+    
+    # This will build only if <define>FOO
+    # was propagated from 'c'.
+    exe a : a.cpp c ;
+""")
+
+t.write(
+    "a.cpp", 
+"""
+#ifdef FOO
+void
+# if defined(_WIN32) && defined(SHARED_B)
+__declspec(dllexport)
+# endif
+foo();
+#endif
+
+int main() { foo(); }
+""")
+
+t.write(
+    "c.cpp",
+"""
+int 
+#if defined(_WIN32) && defined(SHARED_C)
+__declspec(dllexport)
+#endif
+must_export_something;
+""")
+
+t.run_build_system()
+t.run_build_system("--clean")
+
+# Test correct handling of dependency features in 
+# project requirements.
+t.write(
+    "Jamfile",
+"""
+    exe a : a.cpp lib1//c ;
+""")
+
+t.write(
+    "lib1/Jamfile",
+"""
+    project
+    : requirements <link>shared:<define>SHARED_C
+    : usage-requirements <library>../lib2//b <link>shared:<define>SHARED_C
+    ;
+    
+    lib c : c.cpp ;    
+""")
+
+t.write(
+    "lib1/c.cpp", 
+"""
+int 
+#if defined(_WIN32) && defined(SHARED_C)
+__declspec(dllexport)
+#endif
+must_export_something;
+""")
+
+t.write(
+    "lib2/Jamfile", 
+"""
+    lib b : b.cpp : <link>shared:<define>SHARED_B
+    : : <define>FOO <link>shared:<define>SHARED_B ;
+""")
+
+t.copy("b.cpp", "lib2/b.cpp")
+
+t.run_build_system()
+
+# Test that dependency feature in use requirements are built
+# with the correct properties
+t.rm(".")
+
+t.write(
+    "Jamfile", 
+""" 
+lib main : main.cpp : <use>libs//lib1 : : <library>libs//lib1 ; 
+exe hello : hello.cpp main : ;
+""")
+
+t.write(
+    "main.cpp", 
+""" 
+void
+#if defined(_WIN32) && defined(SHARED_LIB1)
+__declspec(dllimport)
+#endif
+foo();
+
+int main() { foo(); return 0; } 
+""")
+
+t.write("hello.cpp", "\n")
+
+t.write(
+    "project-root.jam",
+""" 
+import gcc ; 
+""")
+
+t.write(
+    "libs/a.cpp", 
+""" 
+void
+#if defined(_WIN32) && defined(SHARED_LIB1)
+__declspec(dllexport)
+#endif
+foo() {} 
+""")
+
+# This library should be build with the same properties as
+# 'main'. There were a bug when they were generated with 
+# empty properties, and there were ambiguity between variants.
+t.write(
+    "libs/Jamfile", 
+""" 
+lib lib1 : a_d.cpp : <variant>debug <link>shared:<define>SHARED_LIB1
+: : <link>shared:<define>SHARED_LIB1 ;
+
+lib lib1 : a.cpp : <variant>release <link>shared:<define>SHARED_LIB1
+: : <link>shared:<define>SHARED_LIB1 ; 
+""")
+
+t.write(
+    "libs/a_d.cpp", 
+""" 
+void
+#if defined(_WIN32) && defined(SHARED_LIB1)
+__declspec(dllexport)
+#endif
+foo() {} 
+""")
+
+t.run_build_system("link=static")
+t.expect_addition("libs/bin/$toolset/debug/link-static/a_d.obj")
+
+t.cleanup()


Property changes on: boost-jam/boost-build/branches/upstream/current/test/use_requirements.py
___________________________________________________________________
Name: svn:executable
   + 

Added: boost-jam/boost-build/branches/upstream/current/test/v1-testing/Jamfile
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/v1-testing/Jamfile	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/v1-testing/Jamfile	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,22 @@
+import testing ;
+
+# A number of tests which should succeed
+compile a.cpp ;
+compile-fail b.cpp ;
+link-fail a.cpp : : link-no ;
+link c.cpp : : link-yes ;
+run c.cpp : : : : run-yes ;
+run-fail c.cpp : : : <define>RESULTCODE=1 : run-no ;
+
+# some tests which should fail
+
+compile-fail a.cpp : : fail-compile-no ;
+compile b.cpp : : fail-compile-yes ;
+link a.cpp : : fail-link-yes ;
+link-fail c.cpp : : fail-link-no ;
+run-fail c.cpp : : : : fail-run-no ;
+run c.cpp : : : <define>RESULTCODE=1 : fail-run-yes ;
+
+# Make sure we still fail if a dependency of an expected-failure test
+# fails. 
+link-fail b.cpp : : fail-link-no-dependency ;
\ No newline at end of file

Added: boost-jam/boost-build/branches/upstream/current/test/v1-testing/a.cpp
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/v1-testing/a.cpp	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/v1-testing/a.cpp	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,5 @@
+// Copyright David Abrahams 2003-2004. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+void foo() {}

Added: boost-jam/boost-build/branches/upstream/current/test/v1-testing/b.cpp
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/v1-testing/b.cpp	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/v1-testing/b.cpp	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,5 @@
+// Copyright David Abrahams 2002.
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+#error this does not compile.

Added: boost-jam/boost-build/branches/upstream/current/test/v1-testing/boost-build.jam
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/v1-testing/boost-build.jam	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/v1-testing/boost-build.jam	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,2 @@
+TOOLS = gcc ;
+boost-build ../.. ;

Added: boost-jam/boost-build/branches/upstream/current/test/v1-testing/c.cpp
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/v1-testing/c.cpp	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/v1-testing/c.cpp	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,16 @@
+// Copyright David Abrahams 2002.
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+#include <iostream>
+
+#ifndef RESULTCODE
+# define RESULTCODE 0
+#endif
+
+int main()
+{
+    std::cout << "returning result: " << RESULTCODE << std::endl;
+    return RESULTCODE;
+}
+

Added: boost-jam/boost-build/branches/upstream/current/test/v1_testing/Jamfile
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/v1_testing/Jamfile	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/v1_testing/Jamfile	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,19 @@
+TOOLS = $(TOOLS[1]) ;
+project-root ;
+
+# bring in rules for testing
+import testing ;
+
+lib mylib : lib.cpp ;
+
+compile foo.cpp : : compile ;
+compile-fail foo.cpp : <define>NOCOMPILE : nocompile ;
+
+link foo.cpp <lib>mylib : : link ;
+link-fail foo.cpp  <lib>mylib : <define>NOLINK : nolink ;
+
+run foo.cpp  <lib>mylib
+  : # args
+  : # input-files
+  : <define>RUN
+  : run ;
\ No newline at end of file

Added: boost-jam/boost-build/branches/upstream/current/test/v1_testing/Jamrules
===================================================================

Added: boost-jam/boost-build/branches/upstream/current/test/v1_testing/boost-build.jam
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/v1_testing/boost-build.jam	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/v1_testing/boost-build.jam	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,2 @@
+TOOLS = gcc ;
+boost-build ../.. ;
\ No newline at end of file

Added: boost-jam/boost-build/branches/upstream/current/test/v1_testing/foo.cpp
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/v1_testing/foo.cpp	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/v1_testing/foo.cpp	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,22 @@
+// Copyright David Abrahams 2002.
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#if NOCOMPILE
+1 = 1;
+#endif 
+
+void lib();
+
+void f()
+{
+    lib();
+}
+
+#ifndef NOLINK
+int main()
+{
+}
+#endif
+

Added: boost-jam/boost-build/branches/upstream/current/test/v1_testing/lib-err.cpp
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/v1_testing/lib-err.cpp	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/v1_testing/lib-err.cpp	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,7 @@
+// Copyright David Abrahams 2002.
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+3 = 4;
+void lib() {}

Added: boost-jam/boost-build/branches/upstream/current/test/v1_testing/lib.cpp
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/v1_testing/lib.cpp	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/v1_testing/lib.cpp	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,6 @@
+// Copyright David Abrahams 2002.
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+void lib() {}

Added: boost-jam/boost-build/branches/upstream/current/test/v1_testing/project-root.jam
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/v1_testing/project-root.jam	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/v1_testing/project-root.jam	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1 @@
+# just label the project root
\ No newline at end of file

Added: boost-jam/boost-build/branches/upstream/current/test/v1_testing.py
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/v1_testing.py	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/v1_testing.py	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,83 @@
+#!/usr/bin/python
+
+from BoostBuild import Tester, List
+import os
+from string import strip
+import re
+import time
+
+def match_re(actual,expected):
+    return re.match(expected,actual,re.DOTALL) != None
+
+t = Tester(match = match_re, boost_build_path = os.path.join(os.getcwd(), ".."))
+t.set_tree('v1_testing')
+
+os.environ['TOOLS'] = 'gcc'
+os.environ['NOARSCAN'] = '1'
+
+# 1) No existing bin directories.  Both build and test ran fine. As
+# expected, the residue files were a bit different: There was no
+# path_test.success, and path_test.test contained the word "passed"
+# instead of the path to the .cpp file.  I've haven't looked yet to
+# see if the lack of the path is a problem for reporting, but
+# hopefully the information is trivially available somewhere else.
+t.run_build_system(arguments = 'test', status = 0)
+t.expect_addition(
+    ['bin/compile.test/gcc/debug/runtime-link-dynamic/compile.test'
+     , 'bin/nocompile.test/gcc/debug/runtime-link-dynamic/nocompile.test'
+     , 'bin/link.test/gcc/debug/runtime-link-dynamic/link.test'
+     , 'bin/nolink.test/gcc/debug/runtime-link-dynamic/nolink.test'
+     , 'bin/run.test/gcc/debug/runtime-link-dynamic/run.test'])
+
+
+# 2) Missing source file for the library build. path_test.test was
+# deleted, so the reporting programs would know that failure
+# occurred. The stdout messages also indicated what had
+# happened. Excellent!
+t.rename('lib.cpp', 'lib.cpp.bak')
+t.run_build_system(arguments = 'test', status = 1)
+t.expect_removal(
+    ['bin/link.test/gcc/debug/runtime-link-dynamic/link.test'
+     , 'bin/nolink.test/gcc/debug/runtime-link-dynamic/nolink.test'
+     , 'bin/run.test/gcc/debug/runtime-link-dynamic/run.test'])
+
+# 3) Missing file restored. Worked fine; path_test.test was recreated,
+# no other files were touched.
+t.rename('lib.cpp.bak', 'lib.cpp')
+t.run_build_system(arguments = 'test', status = 0)
+t.expect_addition(
+    [ 'bin/link.test/gcc/debug/runtime-link-dynamic/link.test'
+     , 'bin/nolink.test/gcc/debug/runtime-link-dynamic/nolink.test'
+     , 'bin/run.test/gcc/debug/runtime-link-dynamic/run.test'])
+     # I didn't add a test for 'no other files were touched', because
+     # it's a little complicated. There is an expect_nothing_more()
+     # function, but we actually need to spell out a lot more than
+     # what we currently have to do that.
+
+# 4) Introduced error into one of the library files, causing a library build 
+# compile to fail. path_test.test was deleted, so the reporting programs 
+# would know that failure occurred. Excellent! This is the case that has 
+# caused regression testing to report the wrong results in the past, so it 
+# was good news to see it working correctly now. We probably should figure 
+# out some other test cases just to be sure it is working for full coverage.
+t.rename('lib.cpp', 'lib.cpp.bak')
+t.rename('lib-err.cpp', 'lib.cpp')
+t.touch('lib.cpp')
+t.run_build_system(arguments = 'test', status=1)
+t.expect_removal(
+    ['bin/link.test/gcc/debug/runtime-link-dynamic/link.test'
+     , 'bin/nolink.test/gcc/debug/runtime-link-dynamic/nolink.test'
+     , 'bin/run.test/gcc/debug/runtime-link-dynamic/run.test'])
+
+# 5) Fixed the error in the library file.  The library build then worked, and 
+# path_test.exe was relinked, without first recompiling path_test.obj. Test 
+# was rerun. Exactly right behavior!
+t.rename('lib.cpp.bak', 'lib.cpp')
+t.run_build_system(arguments = 'test', status = 0)
+t.expect_addition(
+    [ 'bin/link.test/gcc/debug/runtime-link-dynamic/link.test'
+     , 'bin/nolink.test/gcc/debug/runtime-link-dynamic/nolink.test'
+     , 'bin/run.test/gcc/debug/runtime-link-dynamic/run.test'])
+
+t.cleanup()
+print 'tesing complete'

Added: boost-jam/boost-build/branches/upstream/current/test/wrapper.py
===================================================================
--- boost-jam/boost-build/branches/upstream/current/test/wrapper.py	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/test/wrapper.py	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,47 @@
+#!/usr/bin/python
+
+#  Copyright (C) Vladimir Prus 2003. Permission to copy, use, modify, sell and
+#  distribute this software is granted provided this copyright notice appears in
+#  all copies. This software is provided "as is" without express or implied
+#  warranty, and with no claim as to its suitability for any purpose.
+
+#  Test that the user can define his own rule that will call builtin main
+#  target rule and that this will work.
+
+from BoostBuild import Tester, List
+
+t = Tester()
+
+t.write("Jamfile", """ my-test : test.cpp ;
+
+
+""")
+
+t.write("test.cpp", """ 
+int main()
+{
+    return 0;
+}
+
+""")
+
+t.write("project-root.jam", """ using testing ;
+
+rule my-test ( name ? : sources + )
+{
+    {
+        name ?= test ;
+        unit-test $(name) : $(sources) ; # /site-config//cppunit /util//testMain ;
+    }   
+}
+
+IMPORT $(__name__) : my-test : : my-test ;
+
+
+""")
+
+t.run_build_system()
+t.expect_addition("bin/$toolset/debug/test.passed")
+
+t.cleanup()
+


Property changes on: boost-jam/boost-build/branches/upstream/current/test/wrapper.py
___________________________________________________________________
Name: svn:executable
   + 

Added: boost-jam/boost-build/branches/upstream/current/tools/bison.jam
===================================================================
--- boost-jam/boost-build/branches/upstream/current/tools/bison.jam	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/tools/bison.jam	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,33 @@
+#  Copyright (C) Vladimir Prus 2002. Permission to copy, use, modify, sell and
+#  distribute this software is granted provided this copyright notice appears in
+#  all copies. This software is provided "as is" without express or implied
+#  warranty, and with no claim as to its suitability for any purpose.
+
+import generators ;
+import feature ;
+import type ;
+import property ;
+
+feature.feature bison.prefix : : free ;
+type.register Y : y ;
+type.register YY : yy ;
+generators.register-standard bison.bison : Y : C H ;
+generators.register-standard bison.bison : YY : CPP HPP ;
+
+rule init ( )
+{
+}
+
+rule bison ( dst dst_header : src : properties * )
+{
+    local r = [ property.select bison.prefix : $(properties) ] ;
+    if $(r)
+    {
+        PREFIX_OPT on $(<) = -p $(r:G=) ;
+    }
+}
+
+actions bison 
+{
+    bison $(PREFIX_OPT) -d -o $(<[1]) $(>)
+}
\ No newline at end of file

Added: boost-jam/boost-build/branches/upstream/current/tools/boostbook.jam
===================================================================
--- boost-jam/boost-build/branches/upstream/current/tools/boostbook.jam	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/tools/boostbook.jam	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,418 @@
+#  Copyright (C) 2003 Doug Gregor. Permission to copy, use, modify,
+#  sell and distribute this software is granted provided this
+#  copyright notice appears in all copies. This software is provided
+#  "as is" without express or implied warranty, and with no claim as
+#  to its suitability for any purpose.
+
+#  This module defines rules to handle generation of documentation
+#  from BoostBook sources.
+
+import "class" : new ;
+import common ;
+import errors ;
+import targets ;
+import feature ;
+import generators ;
+import print ;
+import property ;
+import project ;
+import property-set ;
+import regex ;
+import scanner ;
+import sequence ;
+import make ;
+import type ;
+import modules path project ;
+import xsltproc : xslt xslt-dir ;
+
+feature.feature format : html onehtml man pdf ps docbook fo tests
+  : incidental implicit composite ;
+
+type.register DTDXML : dtdxml ;
+type.register XML : xml : : main ;
+type.register BOOSTBOOK : boostbook : XML ;
+type.register DOCBOOK : docbook : XML ; 
+type.register HTML : html ;
+type.register FO : fo : XML ;
+type.register PDF : pdf ;
+type.register PS : ps ;
+type.register XSLT : xsl : XML ;
+type.register HTMLDIR ;
+type.register MANPAGES ;
+type.register TESTS : tests ;
+
+
+# Initialize BoostBook support. The parameters are:
+#   docbook-xsl-dir: The DocBook XSL stylesheet directory. If not provided,
+#     we use DOCBOOK_XSL_DIR from the environment (if available). Otherwise,
+#     we let the XML processor load the stylesheets remotely.
+#
+#   docbook-dtd-dir: The DocBook DTD directory. If not provided, we use
+#     DOCBOOK_DTD_DIR From the environment (if available). Otherwise, we let
+#     the XML processor load the DTD remotely.
+rule init ( docbook-xsl-dir ? : docbook-dtd-dir ? )
+{
+
+  if ! $(docbook-xsl-dir)
+  {
+    docbook-xsl-dir = [ modules.peek : DOCBOOK_XSL_DIR ] ;
+  }
+
+  if ! $(docbook-dtd-dir)
+  {
+    docbook-dtd-dir = [ modules.peek : DOCBOOK_DTD_DIR ] ;
+  }
+
+  if ! $(.initialized) 
+  {
+    $(.initialized) = true ;
+    if $(docbook-xsl-dir) 
+    {
+      .docbook-xsl-dir = [ path.make $(docbook-xsl-dir) ] ;
+    }
+    if $(docbook-dtd-dir) 
+    {
+      .docbook-dtd-dir = [ path.make $(docbook-dtd-dir) ] ;
+    }
+    
+    local boost-root =  [ modules.peek : BOOST_ROOT ] ;
+    if $(boost-root)
+    {
+        boost-root = [ path.make $(boost-root) ] ;
+    }    
+    local boost-build-root = [
+        sequence.transform path.make : [ modules.peek : BOOST_BUILD_PATH ]
+    ] ; 
+    local search-dirs = [ path.join $(boost-root) tools boostbook ] 
+                        $(boost-build-root)/../../boostbook ;
+    
+    if --debug-configuration in [ modules.peek : ARGV ] 
+    {
+        ECHO "notice: Boost.Book: searching XSLS/DTD in" ;
+        ECHO "notice:" [ sequence.transform path.native : $(search-dirs) ] ;
+    }    
+    local boostbook-xsl-dir ;
+    for local dir in $(search-dirs) {
+        boostbook-xsl-dir += [ path.glob $(dir) : xsl ] ;
+    }
+    local boostbook-dtd-dir ; 
+    for local dir in $(search-dirs) {
+        boostbook-dtd-dir += [ path.glob $(dir) : dtd ] ;
+    }
+    if $(boostbook-xsl-dir)
+    {        
+        .boostbook-xsl-dir = [ path.make $(boostbook-xsl-dir[1]) ] ;
+    }
+    if $(boostbook-dtd-dir)
+    {        
+        .boostbook-dtd-dir = [ path.make $(boostbook-dtd-dir[1]) ] ;
+    }
+    
+    
+    if ! $(.boostbook-xsl-dir) || ! $(.boostbook-dtd-dir)
+    {
+        errors.warning
+          couldn't find BoostBook xsl or dtd directories; 
+        : please set \"BOOST_ROOT\" variable to the root directory of
+        your boost installation.  Searched in:
+          : $(search-dirs:J="
+") ;
+    }    
+    # Add trailing slash since some other code 
+    # uses :B modifier to add last element, and fails
+    # without trailing slash. The code really should be fixed,
+    # but not now.
+    .boostbook-xsl-dir = $(.boostbook-xsl-dir)/ ;
+    .boostbook-dtd-dir = $(.boostbook-dtd-dir)/ ;   
+    
+    # Register generators only if we've were called via "using boostbook ; "
+    generators.register-standard boostbook.dtdxml-to-boostbook : DTDXML : XML ;
+    generators.register-standard boostbook.boostbook-to-docbook : XML : DOCBOOK ;
+    generators.register-standard boostbook.boostbook-to-tests : XML : TESTS ;
+    generators.register-standard boostbook.docbook-to-onehtml : DOCBOOK : HTML ;
+    generators.register-standard boostbook.docbook-to-htmldir : DOCBOOK : HTMLDIR ;
+    generators.register-standard boostbook.docbook-to-manpages : DOCBOOK : MANPAGES ;
+    generators.register-standard boostbook.docbook-to-fo : DOCBOOK : FO ;
+    
+    # The same about Jamfile main target rules.
+    IMPORT $(__name__) : boostbook : : boostbook ;
+  }    
+}
+
+rule xsl-dir
+{
+  return $(.boostbook-xsl-dir) ;
+}
+
+rule dtd-dir
+{
+  return $(.boostbook-dtd-dir) ;
+}
+
+rule docbook-xsl-dir
+{
+  return $(.docbook-xsl-dir) ;
+}
+
+rule docbook-dtd-dir
+{
+  return $(.docbook-dtd-dir) ;
+}
+
+rule dtdxml-to-boostbook ( target : source : properties * )
+{
+  xslt $(target) : $(source) "$(.boostbook-xsl-dir)/dtd/dtd2boostbook.xsl" 
+                 : $(properties) ;
+}
+
+rule boostbook-to-docbook ( target : source : properties * )
+{
+  local native-path = [ path.native $(.boostbook-xsl-dir) ] ;
+  local stylesheet = $(native-path:B=docbook:S=.xsl) ;
+  xslt $(target) : $(source) $(stylesheet) : $(properties) ;
+}
+
+rule docbook-to-onehtml ( target : source : properties * )
+{
+  local native-path = [ path.native $(.boostbook-xsl-dir) ] ;
+  local stylesheet = $(native-path:B=html-single:S=.xsl) ;
+  xslt $(target) : $(source) $(stylesheet) : $(properties) ;
+}
+
+rule docbook-to-htmldir ( target : source : properties * )
+{
+  local native-path = [ path.native $(.boostbook-xsl-dir) ] ;
+  local stylesheet = $(native-path:B=html:S=.xsl) ;
+  xslt-dir $(target) : $(source) $(stylesheet) : $(properties) : html ;
+}
+
+rule docbook-to-manpages ( target : source : properties * )
+{
+  local native-path = [ path.native $(.boostbook-xsl-dir) ] ;
+  local stylesheet = $(native-path:B=manpages:S=.xsl) ;
+  xslt-dir $(target) : $(source) $(stylesheet) : $(properties) : man ;
+}
+
+rule docbook-to-fo ( target : source : properties * )
+{
+  local native-path = [ path.native $(.boostbook-xsl-dir) ] ;
+  local stylesheet = $(native-path:B=fo:S=.xsl) ;
+  xslt $(target) : $(source) $(stylesheet) : $(properties) ;
+}
+
+class xml-catalog-action : action
+{
+    import boostbook ;
+    import print ;
+
+    rule __init__ ( target : property-set ? : catalog-entries * )
+    {
+        action.__init__ $(target) : : generate-xml-catalog : $(property-set) ;
+    }
+    
+  rule actualize ( )
+  {
+    if ! $(self.actualized)
+    {
+      self.actualized = true ;
+      local actual = [ $(self.targets[1]).actualize ] ; 
+      local text = "<?xml version=\"1.0\"?>" ;
+
+      text += "<!DOCTYPE catalog " ;
+      text += "  PUBLIC \"-//OASIS/DTD Entity Resolution XML Catalog V1.0//EN\"" ;
+      text += "  \"http://www.oasis-open.org/committees/entity/release/1.0/catalog.dtd\">" ;
+      text += "<catalog xmlns=\"urn:oasis:names:tc:entity:xmlns:xml:catalog\">" ;
+ 
+      # BoostBook DTD catalog entry
+      local boostbook-dtd-dir = [ boostbook.dtd-dir ] ;
+
+      text += "  <rewriteURI uriStartString=\"http://www.boost.org/tools/boostbook/dtd/\" rewritePrefix=\"file://$(boostbook-dtd-dir)/\"/>" ;
+
+      local docbook-xsl-dir = [ boostbook.docbook-xsl-dir ] ;
+      if ! $(docbook-xsl-dir) 
+      {
+        ECHO "BoostBook warning: no DocBook XSL directory specified." ;
+        ECHO "  If you have the DocBook XSL stylesheets installed, please " ;
+        ECHO "  set DOCBOOK_XSL_DIR to the stylesheet directory on either " ;
+        ECHO "  the command line (via -sDOCBOOK_XSL_DIR=...) or in a " ;
+        ECHO "  Boost.Jam configuration file. The DocBook XSL stylesheets " ;
+        ECHO "  are available here: http://docbook.sourceforge.net/ " ;
+        ECHO "  Stylesheets will be downloaded on-the-fly (very slow!) " ;
+      }
+      else 
+      {
+        text += "  <rewriteURI uriStartString=\"http://docbook.sourceforge.net/release/xsl/current/\" rewritePrefix=\"file://$(docbook-xsl-dir)/\"/>" ;
+      }
+
+      local docbook-dtd-dir = [ boostbook.docbook-dtd-dir ] ;
+      if ! $(docbook-dtd-dir)
+      {
+        ECHO "BoostBook warning: no DocBook DTD directory specified." ;
+        ECHO "  If you have the DocBook DTD installed, please set " ;
+        ECHO "  DOCBOOK_DTD_DIR to the DTD directory on either " ;
+        ECHO "  the command line (via -sDOCBOOK_DTD_DIR=...) or in a " ;
+        ECHO "  Boost.Jam configuration file. The DocBook DTD is available " ;
+        ECHO "  here: http://www.oasis-open.org/docbook/xml/4.2/index.shtml" ;
+        ECHO "  The DTD will be downloaded on-the-fly (very slow!) " ;
+      }
+      else 
+      {
+        text += "  <rewriteURI uriStartString=\"http://www.oasis-open.org/docbook/xml/4.2/\" rewritePrefix=\"file://$(docbook-dtd-dir)/\"/>" ;
+      }
+
+      text += "</catalog>" ;
+
+      print.output $(actual) ;
+      print.text $(text) : true ;          
+    }
+  }
+}
+
+class boostbook-target-class : basic-target
+{
+    import feature ;
+    import virtual-target ;
+    import generators ;
+        
+    rule __init__ ( name : project : sources * : requirements * 
+                              : default-build * : catalog-entries * )
+    {
+
+        basic-target.__init__ $(name) : $(project) : $(sources) : $(requirements)
+          : $(default-build) ;
+        self.catalog-entries = $(catalog-entries) ;
+    }
+    
+  rule construct ( source-targets * : property-set )
+  {
+    local path = [ $(self.project).get location ] ;
+    local catalog = [ new file-target catalog : XML : $(self.project) ] ;
+    $(catalog).action [ new xml-catalog-action $(catalog) : $(property-set) 
+                                               : $(self.catalog-entries) ] ;
+
+    $(catalog).set-path $(path) ;
+    catalog = [ virtual-target.register $(catalog) ] ;
+    local properties = [ $(property-set).raw ] ;
+
+    local format = [ feature.get-values <format> : $(properties) ] ;
+    local targets = $(catalog) ;
+
+    local type = none ;
+    local manifest ; 
+    switch $(format) 
+    {
+      case html    : 
+      {
+        type = HTMLDIR ;
+        manifest = HTML.manifest ;
+      }
+
+      case onehtml : type = HTML ;
+ 
+      case man : 
+      {
+        type = MANPAGES ;
+        manifest = man.manifest ;
+      }
+
+      case docbook : type = DOCBOOK ;
+      case fo      : type = FO ;
+      case pdf     : type = PDF ;
+      case ps      : type = PS ;
+      case tests   : type = TESTS ;
+    }
+    
+    if $(manifest)
+    {
+      local base-target = [ generators.construct $(self.project) 
+                            : DOCBOOK : $(property-set) : $(source-targets) ] ;
+      $(base-target).depends $(catalog) ;
+
+      local target = [ generators.construct $(self.project) $(manifest)
+                       : $(type) : $(property-set) : $(base-target) ] ;
+      $(target).set-path $(format) ;
+
+      targets += $(target) ;
+    }
+    else {
+      local target = [ generators.construct $(self.project)
+                       : $(type) : $(property-set) : $(source-targets) ] ;
+
+      if ! $(target)
+      {
+        errors.error "Cannot build documentation type '$(format)'" ;
+      }
+      else 
+      {
+        $(target).depends $(catalog) ;
+        targets += $(target) ;
+      }
+    }
+
+    return $(targets) ;
+  }
+}
+
+rule boostbook ( target-name : sources * : requirements * : default-build * )
+{ 
+  local project = [ project.current ] ;
+ 
+  targets.main-target-alternative 
+    [ new boostbook-target-class $(target-name) : $(project) 
+        : [ targets.main-target-sources $(sources) : $(target-name) ] 
+        : [ targets.main-target-requirements $(requirements) : $(project) ]
+        : [ targets.main-target-default-build $(default-build) : $(project) ] 
+    ] ;
+}
+
+#############################################################################
+# Dependency scanners
+#############################################################################
+# XInclude scanner. Mostly stolen from c-scanner :)
+# Note that this assumes an "xi" prefix for XIncludes. This isn't always the
+# case for XML documents, but we'll assume it's true for anything we encounter.
+class xinclude-scanner : scanner 
+{
+    import virtual-target ;
+    import path ;
+    import scanner ;
+        
+    rule __init__ ( includes * )
+    {
+        scanner.__init__ ;
+        self.includes = $(includes) ;
+    }
+    
+  rule pattern ( )
+  {
+    return "xi:include[ ]*href=\"([^\"]*)\"" ;
+  }
+
+  rule process ( target : matches * : binding )
+  {
+    local target_path = [ NORMALIZE_PATH $(binding:D) ] ;
+
+    NOCARE $(matches) ;
+    INCLUDES $(target) : $(matches) ;
+    SEARCH on $(matches) = $(target_path) $(self.includes:G=) ;
+    
+    scanner.propagate $(__name__) : $(matches) : $(target) ;     
+  }
+}
+
+scanner.register xinclude-scanner : xsl:path ;
+type.set-scanner XML : xinclude-scanner ;
+
+#############################################################################
+# Testsuite handling
+#############################################################################
+rule boostbook-to-tests ( target : source : properties * )
+{
+  local boost_root = [ modules.peek : BOOST_ROOT ] ;
+  local native-path =
+    [ path.native [ path.join $(.boostbook-xsl-dir) testing Jamfile ] ] ;
+  local stylesheet = $(native-path:S=.xsl) ;
+  xslt $(target) : $(source) $(stylesheet) 
+                 : $(properties) <xsl:param>boost.root=$(boost_root) 
+                 ;
+}

Added: boost-jam/boost-build/branches/upstream/current/tools/borland.jam
===================================================================
--- boost-jam/boost-build/branches/upstream/current/tools/borland.jam	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/tools/borland.jam	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,208 @@
+# (C) Copyright David Abrahams 2001. 
+# (C) Copyright Vladimir Prus 2003.
+# (C) Copyright Rene Rivera 2003.
+# Permission to copy, use, modify, sell and distribute this software 
+# is granted provided this copyright notice appears in all copies. This 
+# software is provided "as is" without express or implied warranty, and 
+# with no claim as to its suitability for any purpose.
+
+#  Support for the Borland's command line compiler
+
+import property ;
+import generators ;
+import os ;
+import toolset : flags ;
+import feature : get-values ;
+import type ;
+import common ;
+
+toolset.register borland ;
+
+rule init ( version ? : command * : options * )
+{
+    local condition = [ common.check-init-parameters borland :
+        version $(version) ] ;
+    
+    local command = [ common.get-invocation-command borland : bcc32.exe 
+        : $(command) ] ;
+     
+    common.handle-options borland : $(condition) : $(command) : $(options) ;    
+    
+    if $(command)
+    {
+        command = [ common.get-absolute-tool-path $(command[-1]) ] ;
+    }   
+    root = $(command:D) ;    
+    
+    flags borland.compile STDHDRS $(condition) : $(root)/include/ ;
+    flags borland.link STDLIBPATH $(condition) : $(root)/lib ;
+    flags borland .root $(condition) : $(root)/bin/ ;    
+}
+
+
+# A borland-specific target type
+type.register BORLAND.TDS : tds ;
+
+# Declare generators
+
+generators.register-linker borland.link : OBJ SEARCHED_LIB STATIC_LIB IMPORT_LIB : EXE RSP : <toolset>borland ;
+generators.register-linker borland.link.dll : OBJ SEARCHED_LIB STATIC_LIB IMPORT_LIB : SHARED_LIB IMPORT_LIB RSP : <toolset>borland ;
+
+generators.register-composing borland.archive : OBJ : STATIC_LIB : <toolset>borland ;
+generators.register-c-compiler borland.compile.c++ : CPP : OBJ : <toolset>borland ;
+generators.register-c-compiler borland.compile.c : C : OBJ : <toolset>borland ;
+
+
+# Declare flags 
+
+flags borland.compile OPTIONS <debug-symbols>on : -v ;
+flags borland.link OPTIONS <debug-symbols>on : -v ;
+
+flags borland.compile OPTIONS <optimization>off : -Od ;
+flags borland.compile OPTIONS <optimization>speed : -O2 ;
+flags borland.compile OPTIONS <optimization>space : -O1 ;
+
+flags borland CFLAGS <inlining>off : -vi- ;
+flags borland CFLAGS <inlining>on : -vi -w-inl ;
+flags borland CFLAGS <inlining>full : -vi -w-inl ;
+
+
+# Deal with various runtime configs...
+
+# This should be not for DLL
+flags borland OPTIONS <user-interface>console : -tWC ;
+
+# -tWR sets -tW as well, so we turn it off here and then turn it 
+# on again later if we need it:
+flags borland OPTIONS <link-runtime>shared : -tWR -tWC ;
+flags borland OPTIONS <user-interface>gui : -tW ;
+
+flags borland OPTIONS <main-target-type>LIB/<link>shared : -tWD ;
+# Hmm.. not sure what's going on here.
+flags borland OPTIONS : -WM- ;
+flags borland OPTIONS <threading>multi : -tWM ;
+
+
+
+flags borland.compile OPTIONS <cxxflags> ;
+flags borland.compile DEFINES <define> ;
+flags borland.compile INCLUDES <include> ;
+
+flags borland NEED_IMPLIB <main-target-type>LIB/<link>shared : "" ;
+
+#
+# for C++ compiles the following options are turned on by default:
+#
+# -j5    stops after 5 errors
+# -g255  allow an unlimited number of warnings
+# -q     no banner
+# -c     compile to object
+# -P     C++ code regardless of file extention
+# -w     turns on all warnings
+# -Ve    zero sized empty base classes, this option is on in the IDE by default 
+#        and effects binary compatibility.
+# -Vx    zero sized empty members, this option is on in the IDE by default 
+#        and effects binary compatibility.
+# -a8    8 byte alignment, this option is on in the IDE by default 
+#        and effects binary compatibility.
+#
+
+# -U$(UNDEFS) -D$(DEFINES) $(CFLAGS) $(C++FLAGS) -I"$(HDRS)"  -I"$(STDHDRS)" -o"$(<)" "$(>)"
+
+
+actions compile.c++
+{
+    $(CONFIG_COMMAND) -j5 -g255 -q -c -P -w -Ve -Vx -a8 -b- $(OPTIONS) -D$(DEFINES) -I"$(INCLUDES)" -I"$(STDHDRS)" -o"$(<)" "$(>)"
+}
+
+# For C, we don't pass -P flag
+actions compile.c
+{
+    $(CONFIG_COMMAND) -j5 -g255 -q -c -w -Ve -Vx -a8 -b- $(OPTIONS) -D$(DEFINES) -I"$(INCLUDES)" -I"$(STDHDRS)" -o"$(<)" "$(>)"
+}
+
+
+# Declare flags and action for linking
+toolset.flags borland.link OPTIONS <debug-symbols>on : -v ;
+toolset.flags borland.link LIBRARY_PATH <library-path> ;
+toolset.flags borland.link FINDLIBS_ST <find-static-library> ;
+toolset.flags borland.link FINDLIBS_SA <find-shared-library> ;
+toolset.flags borland.link LIBRARIES <library-file> ;
+toolset.flags borland.link LIBRARIES <library> ;
+
+flags borland.link OPTIONS <linkflags> ;
+flags borland.link OPTIONS <link>shared : -tWD ;
+
+flags borland.link LIBRARY_PATH_OPTION <toolset>borland : -L : unchecked ;
+flags borland.link LIBRARY_OPTION <toolset>borland : "" : unchecked ;
+
+
+
+# bcc32 needs to have ilink32 in the path in order to invoke it, so explicitly
+# specifying $(BCC_TOOL_PATH)bcc32 doesn't help. You need to add
+# $(BCC_TOOL_PATH) to the path
+# The NEED_IMPLIB variable controls whether we need to invoke implib.
+
+flags borland.archive AROPTIONS <archiveflags> ;
+# Declare action for archives. We don't use response file
+# since it's hard to get "+-" there.
+# CONSIDER: don't know what 'together' is for...
+actions updated together piecemeal archive
+{ 
+    "$(.root)tlib" $(AROPTIONS) /u /a /C "$(<:W)" +-"$(>:W)"
+}
+
+
+if [ os.name ] = CYGWIN
+{
+    .set-path = "cmd /S /C set \"PATH=" ;
+    .old-path = ";%PATH%\" \"&&\"" ;
+
+    # Couldn't get TLIB to stop being confused about pathnames
+    # containing dashes (it seemed to treat them as option separators
+    # when passed through from bash), so we explicitly write the
+    # command into a .bat file and execute that.  TLIB is also finicky
+    # about pathname style! Forward slashes, too, are treated as
+    # options.
+    actions updated together piecemeal archive
+    { 
+        echo "\"$(.root)tlib\" $(OPTIONS) /u /a /C \"$(<:W)\" +-\"$(>:W)\"" > $(<:D)/tlib.bat
+        chmod +x $(<:D)/tlib.bat && $(<:D)/tlib.bat && rm $(<:D)/tlib.bat ;
+    }
+}
+else if [ os.name ] = NT
+{
+    .set-path = "set \"PATH=" ;
+    .old-path = ";%PATH%\"
+      " ;
+}
+else
+{
+    .set-path = "PATH=\"" ;
+    .old-path = "\":$PATH
+      export PATH
+      " ;
+}
+
+
+rule link ( targets + : sources * : properties * )
+{
+    common.response-file $(targets) : $(sources) : $(targets[2]) 
+      : $(properties) ;
+}   
+
+actions link bind LIBRARIES
+{
+    $(.set-path)$(.root:W)$(.old-path) $(CONFIG_COMMAND) -v -q $(OPTIONS) -L"$(LIBRARY_PATH:W)" -L"$(STDLIBPATH:W)" -e"$(<[1]:W)" @"$(<[2]:W)"
+}
+
+rule link.dll ( targets + : sources * : properties * )
+{
+    common.response-file $(targets) : $(sources) : $(targets[3]) : $(properties) ;    
+}
+
+actions link.dll bind LIBRARIES
+{
+    $(.set-path)$(.root:W)$(.old-path) $(CONFIG_COMMAND) -v -q $(OPTIONS) -L"$(LIBRARY_PATH:W)" -L"$(STDLIBPATH:W)" -e"$(<[1]:W)" @"$(<[3]:W)"
+    "$(.root)implib" "$(<[2]:W)" "$(<[1]:W)"
+}

Added: boost-jam/boost-build/branches/upstream/current/tools/builtin.jam
===================================================================
--- boost-jam/boost-build/branches/upstream/current/tools/builtin.jam	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/tools/builtin.jam	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,774 @@
+#  Copyright (C) Vladimir Prus 2002. Permission to copy, use, modify, sell and
+#  distribute this software is granted provided this copyright notice appears in
+#  all copies. This software is provided "as is" without express or implied
+#  warranty, and with no claim as to its suitability for any purpose.
+
+#  Defines standard features and rules.
+
+import "class" : new ;
+
+import feature : feature compose ;
+import toolset : flags ;
+import errors : error ;
+import type ;
+import scanner ;
+import generators ;
+import regex ;
+import virtual-target ;
+import os ;
+import symlink ;
+import alias ;
+import property ;
+import print ;
+import utility ;
+import project ;
+
+# This feature is used to determine which OS we're on.
+# In future, this may become <target-os> and <host-os>
+local os = [ modules.peek : OS ] ;
+feature os : $(os) : propagated link-incompatible ;
+
+feature toolset : : implicit propagated symmetric ;
+
+feature stdlib : native : propagated link-incompatible composite ;
+
+feature link : shared static : propagated ;
+feature link-runtime : shared static : propagated ;
+feature runtime-debugging : on off : propagated ;
+
+
+feature optimization : off speed space : propagated ;
+feature profiling : off on : propagated ;
+feature inlining : off on full : propagated ;
+
+feature threading : single multi : propagated ;
+feature rtti : on off : propagated ;
+feature exception-handling : on off : propagated ;
+feature debug-symbols : on off : propagated ;
+feature define : : free ;
+feature "include" : : free path ; #order-sensitive ;
+feature cflags : : free ;
+feature cxxflags : : free ;
+feature linkflags : : free ;
+feature archiveflags : : free ;
+feature version : : free ;
+
+feature.feature location-prefix : : free ;
+
+# The following features are incidental, since
+# in themself they have no effect on build products.
+# Not making them incidental will result in problems in corner
+# cases, for example:
+# 
+#    unit-test a : a.cpp : <use>b ;
+#    lib b : a.cpp b ;
+# 
+# Here, if <use> is not incidental, we'll decide we have two 
+# targets for a.obj with different properties, and will complain.
+#
+# Note that making feature incidental does not mean it's ignored. It may
+# be ignored when creating the virtual target, but the rest of build process
+# will use them.
+feature use : : free dependency incidental ;
+feature dependency : : free dependency incidental ;
+feature implicit-dependency : : free dependency incidental ;
+
+feature source : : free dependency incidental ;
+feature library : : free dependency incidental ;
+feature file : : free dependency incidental ;
+feature find-shared-library : : free ; #order-sensitive ;
+feature find-static-library : : free ; #order-sensitive ;
+feature library-path : : free path ; #order-sensitive ;
+# Internal feature.
+feature library-file : : free dependency ;
+
+feature name : : free ;
+feature tag : : free ;
+feature search : : free path ; #order-sensitive ;
+feature location : : free path ;
+
+feature dll-path : : free path ;
+feature hardcode-dll-paths : true false : incidental ;
+
+
+# This is internal feature which holds the paths of all dependency
+# dynamic libraries. On Windows, it's needed so that we can all
+# those paths to PATH, when running applications.
+# On Linux, it's needed to add proper -rpath-link command line options.
+feature xdll-path : : free path ;
+
+#provides means to specify def-file for windows dlls.
+feature def-file : : free dependency ;
+
+# This feature is used to allow specific generators to run.
+# For example, QT tools can only be invoked when QT library
+# is used. In that case, <allow>qt will be in usage requirement
+# of the library.
+feature allow : : free ;
+
+# Windows-specific features
+
+feature user-interface : console gui wince native auto ;
+
+feature variant : : implicit composite propagated symmetric ;
+
+# Declares a new variant.
+# First determines explicit properties for this variant, by
+# refining parents' explicit properties with the passed explicit
+# properties. The result is remembered and will be used if
+# this variant is used as parent.
+#
+# Second, determines the full property set for this variant by
+# adding to the explicit properties default values for all properties 
+# which neither present nor are symmetric.
+#
+# Lastly, makes appropriate value of 'variant' property expand
+# to the full property set.
+rule variant ( name           # Name of the variant
+    : parents-or-properties * # Specifies parent variants, if 
+                              # 'explicit-properties' are given,
+                              # and explicit-properties otherwise.
+    : explicit-properties *   # Explicit properties.
+    )
+{
+    local parents ;
+    if ! $(explicit-properties)
+    {
+        if $(parents-or-properties[1]:G)
+        {
+            explicit-properties = $(parents-or-properties) ;
+        }
+        else
+        {
+            parents = $(parents-or-properties) ;
+        }
+    }
+    else
+    {
+        parents = $(parents-or-properties) ;
+    }
+
+    # The problem is that we have to check for conflicts
+    # between base variants.
+    if $(parents[2])
+    {
+        error "multiple base variants are not yet supported" ;
+    }
+    
+    local inherited ;
+    # Add explicitly specified properties for parents
+    for local p in $(parents)
+    {
+        # TODO: the check may be sticter
+        if ! [ feature.is-implicit-value $(p) ]
+        {
+            error "Invalid base varaint" $(p)  ;
+        }
+        
+        inherited += $(.explicit-properties.$(p)) ;
+    }
+    property.validate $(explicit-properties) ;
+    explicit-properties = [ property.refine $(inherited) : $(explicit-properties) ] ;
+    
+    # Record explicitly specified properties for this variant
+    # We do this after inheriting parents' properties, so that
+    # they affect other variants, derived from this one.
+    .explicit-properties.$(name) = $(explicit-properties) ;
+           
+    feature.extend variant : $(name) ;
+    feature.compose <variant>$(name) : $(explicit-properties) ;    
+}
+IMPORT $(__name__) : variant : : variant ;
+
+variant debug : <optimization>off <debug-symbols>on <inlining>off <runtime-debugging>on ;
+variant release : <optimization>speed <debug-symbols>off <inlining>full 
+                  <runtime-debugging>off <define>NDEBUG ;
+variant profile : release : <profiling>on <debug-symbols>on ;
+
+class searched-lib-target : abstract-file-target
+{
+    rule __init__ ( name     
+        : project 
+        : shared ?                                
+        : real-name ?
+        : search *                 
+    )
+    {
+        abstract-file-target.__init__ $(name) : SEARCHED_LIB : $(project) ;
+        
+        self.shared = $(shared) ;
+        self.real-name = $(real-name) ;
+        self.real-name ?= $(name) ;
+        self.search = $(search) ;
+    }
+    
+    
+    rule shared ( )
+    {
+        return $(self.shared) ;
+    }
+    
+    rule real-name ( ) 
+    {
+        return $(self.real-name) ;
+    }
+    
+    rule search ( )
+    {
+        return $(self.search) ;
+    }
+        
+    rule actualize-location ( target )
+    {
+        NOTFILE $(target) ;
+    }    
+    
+    rule path ( )
+    {
+    }
+}    
+
+type.register LIB : : : main ;
+
+# register the given type on the specified OSes, or on remaining OSes
+# if os is not specified.
+local rule declare-type ( os * : type : suffixes * : base-type ? : main ? ) 
+{
+    if ! [ type.registered $(type) ]
+    {
+        if ( ! $(os) ) || [ os.name ] in $(os)
+        {
+            type.register $(type) : $(suffixes) : $(base-type) : $(main) ;
+        }
+    }
+}
+
+#
+# Common target types.
+#
+
+declare-type NT CYGWIN : OBJ : obj : : main ;
+declare-type : OBJ : o : : main ;
+
+declare-type NT CYGWIN : STATIC_LIB : lib a : LIB : main ;
+declare-type : STATIC_LIB : a : LIB : main ;
+
+declare-type : IMPORT_LIB : : STATIC_LIB : main ;
+type.set-generated-target-suffix IMPORT_LIB : : lib ;
+
+declare-type NT CYGWIN : SHARED_LIB : dll : LIB : main ;
+declare-type : SHARED_LIB : so : LIB : main ;
+
+declare-type : SEARCHED_LIB : : LIB : main ;
+
+declare-type NT CYGWIN : EXE : exe : : ;
+declare-type : EXE : : : ;
+
+declare-type : PYTHON_EXTENSION : : SHARED_LIB : main ;
+# We can't give "dll" suffix to PYTHON_EXTENSION, because
+# we would not know what "a.dll" is: python extenstion or
+# ordinary library. Therefore, we specify only suffixes
+# used for generation of targets.
+type.set-generated-target-suffix PYTHON_EXTENSION : : so ;
+type.set-generated-target-suffix PYTHON_EXTENSION : <os>NT : so ;
+type.set-generated-target-suffix PYTHON_EXTENSION : <os>CYGWIN : dll ;
+
+type.register CPP : cpp cxx cc ;
+
+import stage ;
+
+
+class c-scanner : scanner 
+{
+    import regex virtual-target path scanner ;    
+    
+    rule __init__ ( includes * )
+    {
+        scanner.__init__ ;
+    
+        self.includes = $(includes) ;
+    }    
+
+    rule pattern ( )
+    {
+        return "#[ \t]*include[ ]*(<(.*)>|\"(.*)\")" ;
+    }
+
+    rule process ( target : matches * : binding )
+    {
+        local angle = [ regex.transform $(matches) : "<(.*)>" ] ;
+        local quoted = [ regex.transform $(matches) : "\"(.*)\"" ] ;
+
+        # CONSIDER: the new scoping rule seem to defeat "on target" variables.
+        local g = [ on $(target) return $(HDRGRIST) ] ;  
+        local b = [ NORMALIZE_PATH $(binding:D) ] ;
+
+        # Attach binding of including file to included targets.
+        # When target is directly created from virtual target
+        # this extra information is unnecessary. But in other
+        # cases, it allows to distinguish between two headers of the 
+        # same name included from different places.      
+        # We don't need this extra information for angle includes,
+        # since they should not depend on including file (we can't
+        # get literal "." in include path).
+        local g2 = $(g)"#"$(b) ;
+       
+        angle = $(angle:G=$(g)) ;
+        quoted = $(quoted:G=$(g2)) ;
+        
+        local all = $(angle) $(quoted) ;
+
+        INCLUDES $(target) : $(all) ;
+        NOCARE $(all) ;
+        SEARCH on $(angle) = $(self.includes:G=) ;
+        SEARCH on $(quoted) = $(b) $(self.includes:G=) ;
+        
+        # Just propagate current scanner to includes, in a hope
+        # that includes do not change scanners. 
+        scanner.propagate $(__name__) : $(angle) $(quoted) : $(target) ;
+    }        
+}
+
+scanner.register c-scanner : include ;
+
+type.set-scanner CPP : c-scanner ;
+
+
+type.register H : h ;
+type.register HPP : hpp : H ;
+type.register C : c ;
+
+class lib-target-class : basic-target
+{
+    import generators : construct : generators.construct ;    
+    import type ;
+    import path ;
+    
+    rule __init__ ( name : project 
+        : sources * : requirements * : default-build * : usage-requirements * )
+    {    
+        basic-target.__init__ $(name) : $(project) 
+          : $(sources) : $(requirements) : $(default-build) : $(usage-requirements) ;        
+    }
+                
+    rule construct ( source-targets * : property-set )
+    {        
+        local properties = [ $(property-set).raw ] ;
+        # Determine the needed target type
+        local actual-type ;
+        if <search> in $(properties:G) || <name> in $(properties:G)
+        {
+            actual-type = SEARCHED_LIB ;
+        }
+        else if <file> in $(properties:G)
+        {
+            # The generator for 
+            actual-type = LIB ;
+        }        
+        else if <link>shared in $(properties)
+        {
+            actual-type = SHARED_LIB ;
+        }
+        else 
+        {
+            actual-type = STATIC_LIB ;
+        }
+        property-set = [ $(property-set).add-raw <main-target-type>LIB ] ;
+        # Construct the target.
+        return [ generators.construct $(self.project) $(self.name) : $(actual-type) 
+                : $(property-set) : $(source-targets) : LIB ] ;        
+    }            
+    
+    rule compute-usage-requirements ( subvariant )
+    {
+        local rproperties = [ $(subvariant).build-properties ] ;
+        local created-targets = [ $(subvariant).created-targets ] ;  
+        local result = [ basic-target.compute-usage-requirements $(subvariant) ] ;
+        
+        # For lib targets with <search>, add the value of <search> as <library-path>
+        # usage requirement.
+        local search = [ $(rproperties).get <search> ] ;
+        if $(search)
+        {
+            result = [ $(result).add [ 
+              property-set.create $(search:G=<library-path>) ] ] ;            
+        }
+        
+        # Add appropricate <xdll-path> usage requirements.
+        local raw = [ $(rproperties).raw ] ;
+        if <link>shared in $(raw)
+        {
+            local paths ;
+            local pwd = [ path.pwd ] ;
+            for local t in $(created-targets)
+            {
+                if [ type.is-derived [ $(t).type ] SHARED_LIB ] 
+                {
+                    paths += [ path.root [ path.make [ $(t).path ] ] $(pwd) ] ;
+                }                                
+            }       
+            if $(paths)
+            {
+                result = [ $(result).add 
+                  [ property-set.create $(paths:G=<xdll-path>) ] ] ;
+            }                                    
+        }
+        
+        # Pass <xdll-path> features that we've got from sources.
+        local u = [ $(subvariant).sources-usage-requirements ] ;
+        local values = [ $(u).get <xdll-path> ] ;
+        result = [ $(result).add-raw $(values:G=<xdll-path>) ] ;
+        
+        # For libraries that we've failed to consume, we need to 
+        # pass <library-path> usage requirements, if any.
+        # We look at all generated target, and if they are created in different
+        # subvariant, we add usage requirements.
+        for local t in [ $(subvariant).created-targets ]
+        {
+            local s = [ $(t).creating-subvariant ] ;
+            if $(s) != $(subvariant)
+            {
+                result = [ $(result).add [ $(s).usage-requirements ] ] ;
+            }            
+        }
+                                        
+        return $(result) ;
+    }            
+}
+
+rule lib ( names + : sources * : requirements * : default-build * 
+    : usage-requirements * )
+{
+    local project = [ project.current ] ;
+    
+    # This is a circular module dependency, so it must be imported here
+    import targets ;
+
+    local result ;
+    if ! $(sources) && ! $(requirements) 
+      && ! $(default-build) && ! $(usage-requirements)
+    {
+        for local name in $(names)
+        {    
+            result += [ 
+            targets.main-target-alternative
+              [ new lib-target-class $(name) : $(project) 
+                : 
+                : [ targets.main-target-requirements $(requirements) <name>$(name)  :
+                    $(project) ] 
+                : [ targets.main-target-default-build $(default-build) : $(project) ]
+                : [ targets.main-target-usage-requirements $(usage-requirements) : $(project) ]
+             ] ] ;        
+        }        
+    }
+    else
+    {
+        if $(names[2])
+        {
+            errors.user-error "When several names are given to the 'lib' rule" :
+              "it's not allows to specify sources or requirements. " ;
+        }
+                
+        local name = $(names[1]) ;
+        result = [ targets.main-target-alternative
+          [ new lib-target-class $(name) : $(project) 
+            : [ targets.main-target-sources $(sources) : $(name) ] 
+            : [ targets.main-target-requirements $(requirements) : $(project) ] 
+            : [ targets.main-target-default-build $(default-build) : $(project) ]
+            : [ targets.main-target-usage-requirements $(usage-requirements) : $(project) ]
+         ] ] ;
+    }    
+    return $(result) ;
+}
+IMPORT $(__name__) : lib : : lib ;
+
+
+class exe-target-class : typed-target
+{
+    import type ;
+    
+    rule __init__ ( name : project
+        : sources * : requirements * : default-build * : usage-requirements * )
+    {    
+        typed-target.__init__ $(name) : $(project) : EXE 
+          : $(sources) : $(requirements) : $(default-build) : $(usage-requirements) ;        
+    }
+                
+    rule compute-usage-requirements ( subvariant )
+    {
+        local result = [ typed-target.compute-usage-requirements $(subvariant) ] ;
+        local p = [ $(subvariant).build-properties ] ;
+        
+        local xdll-paths = [ $(p).get <xdll-path> ] ;
+        if $(xdll-paths)
+        {
+            result = [  $(result).add-raw $(xdll-paths:G=<xdll-path>) ] ;
+        }                            
+        
+        return $(result) ;
+    }
+    
+    rule check-for-unused-sources ( result * : sources * )
+    {
+        # For exes, we typically don't consume ignore DLL on windows.
+        # We also handle searched libraries via special properties
+        # on actions, so should not check for search libraries.
+        # As the result, we don't check for unused LIB sources
+        # at all.
+                
+        local sources-to-check ;
+        for local s in $(sources)
+        {
+            if ! [ type.is-derived [ $(s).type ] LIB ]
+            {
+                sources-to-check += $(s) ;
+            }            
+        }
+        basic-target.check-for-unused-sources $(result) : $(sources-to-check) ;
+    }
+}
+
+rule exe ( name : sources * : requirements * : default-build * 
+    : usage-requirements * )
+{
+    local project = [ project.current ] ;
+        
+    # This is a circular module dependency, so it must be imported here
+    import targets ;
+    targets.main-target-alternative
+      [ new exe-target-class $(name) : $(project) 
+        : [ targets.main-target-sources $(sources) : $(name) ] 
+        : [ targets.main-target-requirements $(requirements) : $(project) ] 
+        : [ targets.main-target-default-build $(default-build) : $(project) ]
+        : [ targets.main-target-usage-requirements $(usage-requirements) : $(project) ]
+      ] ;
+}
+IMPORT $(__name__) : exe : : exe ;
+
+
+
+class searched-lib-generator : generator
+{
+    rule __init__ ( )
+    {
+        # The requirements cause the generators to be tried *only* when we're building
+        # lib target and there's 'search' feature. This seems ugly --- all we want
+        # is make sure searched-lib-generator is not invoced deep in transformation
+        # search.
+        generator.__init__ searched-lib-generator : : SEARCHED_LIB ;
+    }
+    
+    rule run ( project name ? : property-set : sources * : multiple ? )
+    {
+        if $(name)
+        {
+            # If name is empty, it means we're called not from top-level.
+            # In this case, we just fail immediately, because searched-lib-generator
+            # cannot be used to produce intermediate targets.
+            
+            local properties = [ $(property-set).raw ] ;        
+            local shared ;
+            if <link>shared in $(properties)
+            {
+                shared = true ;
+            }        
+            
+            local t = [ new searched-lib-target $(name) : $(project) : $(shared)
+                            : [ feature.get-values <name> : $(properties) ]
+                            : [ feature.get-values <search> : $(properties) ]
+                      ] ;
+            # attach an action and properties to the target
+            a = [ new null-action $(t) : $(property-set) ] ;
+            $(t).action $(a) ;
+            # We return sources for a simple reason. If there's
+            #    lib png : z : <name>png ; 
+            # the 'z' target should be returned, so that apps linking to
+            # 'png' will link to 'z', too.
+            return [ virtual-target.register $(t) ] $(sources) ;
+        }
+    }
+}
+
+generators.register [ new searched-lib-generator ] ;
+
+class prebuilt-lib-generator : generator
+{
+    rule __init__ ( * : * )
+    {
+        generator.__init__ $(1) : $(2) : $(3) : $(4) : $(5) : $(6) : $(7) : $(8) : $(9) ;
+    }
+
+    rule run ( project name ? : property-set : sources * : multiple ? )
+    {
+        local f = [ $(property-set).get <file> ] ;
+        return $(f) $(sources) ;
+    }    
+}
+
+generators.register 
+  [ new prebuilt-lib-generator builtin.prebuilt : : LIB : <file> ] ;
+
+    
+
+
+
+class compile-action : action 
+{
+    import sequence ;
+    
+    rule __init__ ( targets + : sources * : action-name : properties * )
+    {
+        action.__init__ $(targets) : $(sources) : $(action-name) : $(properties) ;
+    }
+    
+    
+    # For all virtual targets for the same dependency graph as self, 
+    # i.e. which belong to the same main target, add their directories
+    # to include path.
+    rule adjust-properties ( properties * )
+    {        
+        local s = [ $(self.targets[1]).creating-subvariant ] ;
+        return $(properties) [ $(s).implicit-includes "include" : H ] ;
+    }    
+}
+
+class C-compiling-generator : generator
+{
+    rule __init__ ( id : source-types + : target-types + :
+        requirements * : optional-properties * )
+    {
+        generator.__init__ $(id) : $(source-types) : $(target-types) :
+          $(requirements) : $(optional-properties) ;
+    }
+        
+    rule action-class ( )
+    {
+        return compile-action ;
+    }
+}
+
+rule register-c-compiler ( id : source-types + : target-types + :
+                            requirements * : optional-properties * )
+{
+    local g = [ new C-compiling-generator $(id) : $(source-types) 
+                : $(target-types) : $(requirements) : $(optional-properties) ] ;
+    generators.register $(g) ;
+}
+
+# FIXME: this is ugly, should find a better way (we'd want client code to
+# register all generators as "generator.some-rule", not with "some-module.some-rule".)
+IMPORT $(__name__) : register-c-compiler : : generators.register-c-compiler ;
+
+class linking-generator : generator
+{
+    import property-set ;
+    import type ;
+    import path ;
+    import project ;
+    
+    rule __init__ ( id 
+        composing ? : # Specify if generator is composing. The generator will be
+        # composing if non-empty string is passed, or parameter is
+        # not given. To make generator non-composing, pass empty
+        # string ("")
+        source-types + : target-types + : 
+        requirements * )
+    {
+        composing ?= true ;
+        generator.__init__ $(id) $(composing) : $(source-types) : $(target-types) :
+          $(requirements) ;
+    }
+        
+    rule run ( project name ? : property-set : sources + :  multiple ? )
+    {   
+        sources += [ $(property-set).get <library>  ] ;        
+        
+        if [ $(property-set).get <hardcode-dll-paths> ] = true
+         && [ type.is-derived $(self.target-types[1]) EXE ] 
+        {
+            local xdll-path = [ $(property-set).get <xdll-path> ] ;
+            # It's possible that we have libraries in sources which did not came
+            # from 'lib' target. For example, libraries which are specified
+            # just as filenames as sources. We don't have xdll-path properties
+            # for such target, but still need to add proper dll-path properties.
+            for local s in $(sources)
+            {
+                if [ type.is-derived [ $(s).type ] SHARED_LIB ] && ! [ $(s).action ] 
+                {
+                    # Unfortunately, we don't have a good way to find the path
+                    # to a file, so use this nasty approach.
+                    local p = [ $(s).project ] ;
+                    local location = [ path.root [ $(s).name ]
+                      [ $(p).get source-location ] ] ;
+                    xdll-path += [ path.parent $(location) ] ;
+                }                
+            }
+                          
+            if $(xdll-path)
+            {
+                property-set = [ $(property-set).add-raw $(xdll-path:G=<dll-path>) ] ;
+            }            
+
+        }
+                        
+        local result = [ generator.run $(project) $(name) : $(property-set)
+          : $(sources) : $(multiple) ] ;
+        
+        return $(result) ;
+    }
+    
+    rule generated-targets ( sources + : property-set : project name ? )
+    {
+        local sources2 ;     # sources to pass to inherited rule
+        local properties2 ;  # properties to pass to inherited rule
+        local libraries ;    # sources which are libraries
+        
+        # Searched libraries are not passed as argument to linker
+        # but via some option. So, we pass them to the action
+        # via property. 
+        properties2 = [ $(property-set).raw ] ;
+        local fsa ;
+        local fst ;
+        for local s in $(sources)
+        {
+            if [ type.is-derived [ $(s).type ] LIB ] &&
+               [ class.is-a $(s) : searched-lib-target ]
+            {
+                local name = [ $(s).real-name ] ;
+                if [ $(s).shared ] 
+                {                    
+                    fsa +=  $(name) ;
+                }
+                else
+                {
+                    fst += $(name) ;
+                }                         
+            }
+            else
+            {
+                sources2 += $(s) ;
+            }
+        }
+        properties2 += <find-shared-library>$(fsa:J=&&) 
+                       <find-static-library>$(fst:J=&&) ;
+                
+        local spawn = [ generator.generated-targets $(sources2)
+          : [ property-set.create $(properties2) ] : $(project) $(name) ] ;
+        
+        return $(spawn) ;
+    }
+}                             
+
+rule register-linker ( id composing ? : source-types + : target-types + :
+                            requirements * )
+{
+    local g = [ new linking-generator $(id) $(composing) : $(source-types) 
+                : $(target-types) : $(requirements) ] ;
+    generators.register $(g) ;
+}
+
+IMPORT $(__name__) : register-linker : : generators.register-linker ;
+
+declare-type : RSP : rsp ;
+
+

Added: boost-jam/boost-build/branches/upstream/current/tools/common.jam
===================================================================
--- boost-jam/boost-build/branches/upstream/current/tools/common.jam	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/tools/common.jam	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,480 @@
+#  Copyright (C) Vladimir Prus 2002. Permission to copy, use, modify, sell and
+#  distribute this software is granted provided this copyright notice appears in
+#  all copies. This software is provided "as is" without express or implied
+#  warranty, and with no claim as to its suitability for any purpose.
+
+#  Provides actions common to all toolsets, for as making directoies and
+#  removing files.
+
+import os ;
+import modules ;
+import utility ;
+import print ;
+import type ;
+import feature ;
+import errors ;
+import path ;
+import sequence ;
+import toolset ;
+
+
+# The rule checks toolset parameters. Each trailing parameter 
+# should be a pair of parameter name and parameter value.
+# The rule will check that each parameter either has value in
+# each invocation, or has no value in each invocation. Also,
+# the rule will check that the combination of all parameter values is
+# unique in all invocations.
+#
+# Each parameter name corresponds to subfeature. This rule will declare subfeature
+# the first time non-empty parameter value is passed, and will extend it with
+# all the values.
+#
+# The return value from this rule is a condition to be used for flags settings.
+rule check-init-parameters ( toolset : * )
+{
+    local sig = $(toolset) ;
+    local condition = <toolset>$(toolset) ;
+    for local index in 2 3 4 5 6 7 8 9
+    {
+        local name = $($(index)[1]) ;
+        local value = $($(index)[2]) ;
+                
+        if $(value)-is-specified 
+        {
+            condition = $(condition)-$(value) ;
+            if $(.had-unspecified-value.$(toolset).$(name))
+            {
+                errors.user-error
+                "$(toolset) initialization: parameter '$(name)' inconsistent" :
+                "no value was specified in earlier initialization" :
+                "an explicit value is specified now" ;
+            }
+            # The below logic is for intel compiler. It calls this rule
+            # with 'intel-linux' and 'intel-win' as toolset, so we need to
+            # get the base part of toolset name.
+            # We can't pass 'intel' as toolset, because it that case it will
+            # be impossible to register versionles intel-linux and
+            # intel-win of specific version.
+            local t = $(toolset) ;
+            local m = [ MATCH ([^-]*)- : $(toolset) ] ;
+            if $(m)
+            {
+                t = $(m[1]) ;
+            }                                    
+            if ! $(.had-value.$(toolset).$(name)) 
+            {
+                if ! $(.declared-subfeature.$(t).$(name))
+                {
+                    feature.subfeature toolset $(t) : $(name) : : propagated ;
+                    .declared-subfeature.$(t).$(name) = true ;
+                }                
+                .had-value.$(toolset).$(name) = true ;
+            }
+            feature.extend-subfeature toolset $(t) : $(name) : $(value) ;
+        }
+        else
+        {
+            if $(.had-value.$(toolset).$(name))             
+            {
+                errors.user-error                
+                "$(toolset) initialization: parameter '$(name)' inconsistent" :
+                "an explicit value was specified in an earlier initialization" :
+                "no value is specified now" ;           
+            }
+            .had-unspecified-value.$(toolset).$(name) = true ;
+        }
+        sig = $(sig)$(value:E="")- ;
+    }
+    if $(sig) in $(.all-signatures)
+    {
+        local message = 
+          "duplicate initialization of $(toolset) with the following parameters: " ;
+        for local index in 2 3 4 5 6 7 8 9
+        {
+            local p = $($(index)) ;
+            if $(p)
+            {
+                message += "$(p[1]) = $(p[2]:E=<unspecified>)" ;
+            }            
+        }
+        message += "previous initialization at $(.init-loc.$(sig))" ;
+        errors.user-error $(message[1]) : $(message[2]) : $(message[3]) : $(message[4])
+        : $(message[5]) : $(message[6]) : $(message[7]) : $(message[8]) ;
+    }                
+    .all-signatures += $(sig) ;
+    .init-loc.$(sig) = [ errors.nearest-user-location ] ;
+    
+    return $(condition) ;
+}
+
+# A helper rule to get the command to invoke some tool. The rule is either passed
+# a user provided command, it which case it checks it for correctness, or it tries
+# to find the tool using it's name, the PATH, and additional path.
+# This rule returns the command to be used when invoking the tool. If we can't
+# find the tool, a warning is issued.
+# If 'path-last' is specified, path is checked after 'additional-paths'.
+rule get-invocation-command ( 
+    toolset : tool : user-provided-command * : additional-paths * : path-last ? )
+{
+    local command ;
+    if ! $(user-provided-command)
+    {
+        command = [ common.find-tool $(tool) : $(additional-paths) : $(path-last) ] ;
+        if ! $(command)
+        {
+            ECHO "warning: toolset $(toolset) initialization: can't find tool $(tool)" ;
+            ECHO "warning: initialized from" [ errors.nearest-user-location ] ;
+        }        
+    }
+    else
+    {
+        command = [ common.check-tool $(user-provided-command) ] ;        
+        if ! $(command)
+        {
+            ECHO "warning: toolset $(toolset) initialization: " ;
+            ECHO "warning: can't find user-provided command '$(user-provided-command:J= )'" ;
+            ECHO "warning: initialized from" [ errors.nearest-user-location ] ;
+            # It's possible, in theory, that user-provided command is OK, but we're
+            # not smart enough to understand that. 
+            command = $(user-provided-command) ;
+        }        
+    }
+    if ! $(command)
+    {        
+        command = $(user-provided-command) ;
+    }    
+    return $(command) ;
+}
+
+# Given an invocation command,
+# return the absolute path to the command. This works even if commnad
+# has not path element and is present in PATH.
+rule get-absolute-tool-path ( command )
+{
+    if $(command:D)
+    {
+        return $(command:D) ;
+    }
+    else
+    {
+        local m = [ GLOB [ modules.peek : PATH Path path ] : $(command) $(command).exe ] ;
+        return $(m[1]:D) ;
+    }    
+}
+
+
+
+# Attempts to find tool (binary) named 'name' in PATH and in 'additiona-paths'.
+# If found in path, returns 'name'.
+# If found in additional paths, returns full name. If there are several possibilities,
+# returns them all.
+# Otherwise, returns empty string.
+# If 'path-last' is specified, path is checked after 'additional-paths'.
+rule find-tool ( name : additional-paths * : path-last ? )
+{
+    local path = [ path.programs-path ] ;
+    local match = [ path.glob $(path) : $(name) $(name).exe ] ;
+    local additional-match = [ path.glob $(additional-paths) : $(name) $(name).exe ] ;              
+
+    local result ;
+    if $(path-last)
+    {
+        result = $(additional-match) ;
+        if ! $(result) && $(match)
+        {
+            result = $(name) ;
+        }
+    }
+    else
+    {
+        if $(match)
+        {
+            result = $(name) ;
+        }
+        else
+        {
+            result = $(additional-match) ;
+        }
+    }
+    if $(result)
+    {        
+        return [ path.native $(result[1]) ] ;
+    }    
+}
+
+# Checks if 'command' can be found either in path
+# or is a full name to an existing file.
+rule check-tool-aux ( command )
+{
+    if $(command:D)
+    {
+        if [ path.exists $(command) ]
+        {
+            return $(command) ;
+        }        
+    }
+    else
+    {
+        if [ GLOB [ modules.peek : PATH Path path ] : $(command) ]
+        {
+            return $(command) ;
+        }        
+    }        
+}
+
+
+# Checks that a tool can be invoked by 'command'. 
+# If command is not an absolute path, checks if it can be found in 'path'.
+# If comand is absolute path, check that it exists. Returns 'command'
+# if ok and empty string otherwise.
+rule check-tool ( xcommand + )
+{
+    if   [ check-tool-aux $(xcommand[1]) ] 
+      || [ check-tool-aux $(xcommand[-1]) ]
+    {
+        return $(xcommand) ;
+    }
+}
+
+# Handle common options for toolset, specifically sets the following
+# flag variables:
+# - CONFIG_COMMAND to 'command'
+# - OPTIONS for compile.c to the value of <cflags> in options
+# - OPTIONS for compile.c++ to the value of <cxxflags> in options
+# - OPTIOns for compile to the value of <compileflags> in options
+# - OPTIONs for link to the value of <linkflags> in options
+rule handle-options ( toolset : condition * : command ? : options * )
+{
+    # The last parameter ('true') says it's OK to set flags for another
+    # module,   
+    toolset.flags $(toolset) CONFIG_COMMAND $(condition) : $(command) : unchecked ;
+    toolset.flags $(toolset).compile OPTIONS $(condition) :
+      [ feature.get-values <compileflags> : $(options) ] : unchecked ;
+    toolset.flags $(toolset).compile.c OPTIONS $(condition) :
+      [ feature.get-values <cflags> : $(options) ] : unchecked ;
+    toolset.flags $(toolset).compile.c++ OPTIONS $(condition) :
+      [ feature.get-values <cxxflags> : $(options) ] : unchecked ;
+    toolset.flags $(toolset).link OPTIONS $(condition) :
+      [ feature.get-values <linkflags> : $(options) ] : unchecked ;        
+}
+
+
+# returns the location of the "program files" directory on a windows
+# platform
+rule get-program-files-dir ( )
+{
+    local ProgramFiles = [ modules.peek : ProgramFiles ] ;
+    if $(ProgramFiles)
+    {
+        ProgramFiles = "$(ProgramFiles:J= )" ;
+    }
+    else
+    {
+        ProgramFiles = "c:\\Program Files" ;
+    }
+    return $(ProgramFiles) ;
+}
+
+if [ os.name ] = NT
+{
+    RM = del /f ;
+    CP = copy ;
+}
+else
+{
+    RM = rm -f ;
+    CP = cp ;
+}
+
+nl = "
+" ;
+
+# Returns the command needed to set shell variable on the
+# current platform.
+rule variable-setting-command ( variable value )
+{
+    if [ modules.peek : NT ]
+    {
+        return "set $(variable)=$(value)$(nl)" ;
+    }
+    else
+    {
+        return "$(variable)=$(value)" ;
+    }
+}
+
+# Returns the command needed to set shell variable on the
+# current platform. Each element of values is expected to be a path,
+# elements are joined with os-specific characer which delimits paths in
+# environment variables.
+rule path-variable-setting-command ( variable : values * : exported ? )
+{   
+    local result ;
+    if [ modules.peek : NT ]
+    {
+        result = set $(variable)=$(values:J=";")$(nl) ;                
+    }
+    else
+    {
+        # We can't put ":" directly in :J modifier.
+        local sep = ":" ;
+        if $(exported)
+        {                       
+            result = $(variable)=$(values:J=$(sep));export $(variable) ;
+        }
+        else
+        {
+            result = $(variable)=$(values:J=$(sep)) ;    
+        }                
+    }
+    return $(result:J=" ") ;
+}
+
+
+# Return a command which can create a file. If 'r' is result of invocation,
+# then 
+#   r foobar
+# will create foobar with unspecified content. What happens if file already 
+# exists is unspecified.
+rule file-creation-command ( )
+{
+    if [ modules.peek : NT ]
+    {
+        return "echo. > " ;
+    }
+    else
+    {
+        return "touch " ;
+    }
+}
+
+        
+rule MkDir
+{
+    # If dir exists, don't update it
+    # Do this even for $(DOT).
+
+    NOUPDATE $(<) ;
+
+    if $(<) != $(DOT) && ! $($(<)-mkdir)
+    {
+        local s ;
+
+        # Cheesy gate to prevent multiple invocations on same dir
+        # MkDir1 has the actions
+        # Arrange for jam dirs
+
+        $(<)-mkdir = true ;
+        MkDir1 $(<) ;
+        Depends dirs : $(<) ;
+
+        # Recursively make parent directories.
+        # $(<:P) = $(<)'s parent, & we recurse until root
+
+        s = $(<:P) ;
+
+        if $(NT)
+        {
+            switch $(s)
+            {
+                case *:   : s = ;
+                case *:\\ : s = ;
+            }
+        }
+        
+        if $(s) && $(s) != $(<)
+        {
+            Depends $(<) : $(s) ;
+            MkDir $(s) ;
+        }
+        else if $(s)
+        {
+            NOTFILE $(s) ;
+        }
+    }
+}
+
+actions MkDir1
+{
+    mkdir "$(<)"
+}
+
+actions piecemeal together existing Clean
+{
+    $(RM) "$(>)"
+}
+
+rule copy 
+{    
+}
+
+
+actions copy
+{
+    $(CP) "$(>)" "$(<)"
+}
+
+# Cause creation of response file, containing the sources in 'sources'
+# All the targets in 'targets' will depend on response file, and response
+# file will be created before the targets are built.
+rule response-file ( targets + : sources * : the-response-file : properties * )
+{
+    # Manufacture a fake target for response file.
+    # If response file is in targets, we're in trouble.
+    # The actions for response file are already generated, and bjam thinks it's 
+    # created. So setting dependency on response file will not help to create
+    # it before other targets. So, we need another target.
+    
+    local g = [ utility.ungrist $(the-response-file:G) ] ;
+    local rsp = $(the-response-file:G=$(g)-rsp) ;
+    LOCATE on $(rsp) = [ on $(the-response-file) return $(LOCATE) ] ;    
+    DEPENDS $(targets) : $(rsp) ;
+    # Cause RSP to be recreated if sources are out-of-date.
+    DEPENDS $(rsp) : $(sources) ;
+        
+    # Add libraries from <library> property to the list of sources.
+    local libraries ;
+    for local p in $(properties)
+    {
+        if $(p:G) = <library-file> && 
+          ! [ type.is-derived [ $(p:G=).type ] SHARED_LIB ] 
+        {
+            libraries += $(p:G=) ;
+        }          
+    }
+    # Get real jam targets
+    local xlibraries ;
+    for local l in $(libraries)
+    {
+        xlibraries += [ $(l).actualize ] ;
+    }
+    
+    sources += $(xlibraries) ; 
+       
+    response-file-1 $(rsp) : $(sources[1]) ;
+    if $(sources[2-])
+    {
+        response-file-2 $(rsp) : $(sources[2-]) ;
+    }
+    
+    print.output $(rsp) ;
+    print.text [ utility.apply-default-suffix .lib :
+        [ on $(targets[1])
+          return "$(LIBRARY_OPTION)$(FINDLIBS_ST)"
+            "$(LIBRARY_OPTION)$(FINDLIBS_SA)"
+        ] ] ;    
+}
+
+# response-file generation is broken up into two phases, the first of
+# which overwrites any existing file and the second of which appends
+# to the file, piecemeal, so that no command-line is too long.
+actions quietly response-file-1
+{
+    echo "$(>)" > "$(<)"
+}
+
+actions quietly piecemeal response-file-2
+{
+    echo "$(>)" >> "$(<)"
+}
+

Added: boost-jam/boost-build/branches/upstream/current/tools/como-linux.jam
===================================================================
--- boost-jam/boost-build/branches/upstream/current/tools/como-linux.jam	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/tools/como-linux.jam	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,98 @@
+# modify, sell and distribute this software is granted provided this
+# copyright notice appears in all copies. This software is provided
+# "as is" without express or implied warranty, and with no claim as
+# to its suitability for any purpose.
+
+# The following #// line will be used by the regression test table generation
+# program as the column heading for HTML tables. Must not include version number.
+#//<a href="http://www.comeaucomputing.com/">Comeau<br>C++</a>
+
+import toolset ;
+import feature ;
+import toolset : flags ;
+import common ;
+
+import unix ;  
+import como ;
+feature.extend-subfeature toolset como : platform : linux ;
+
+toolset.inherit-generators como-linux 
+     <toolset>como <toolset-como:platform>linux : unix ;
+toolset.inherit-flags como-linux : unix ;
+toolset.inherit-rules como-linux : gcc ;
+
+generators.register-c-compiler como-linux.compile.c++ : CPP : OBJ 
+  : <toolset>como <toolset-como:platform>linux ;
+generators.register-c-compiler como-linux.compile.c : C : OBJ
+  : <toolset>como <toolset-como:platform>linux ;
+
+rule init ( version ? : command * : options * )
+{
+    local condition = [ common.check-init-parameters como-linux
+        : version $(version) ] ;
+    
+    command = [ common.get-invocation-command como-linux : como 
+        : $(command) ] ;
+    
+    common.handle-options como-linux : $(condition) : $(command) : $(options) ;
+}
+
+flags como-linux C++FLAGS <exception-handling>off : --no_exceptions ;
+flags como-linux C++FLAGS <exception-handling>on : --exceptions ;
+
+flags como-linux CFLAGS <inlining>off : --no_inlining ;
+flags como-linux CFLAGS <inlining>on <inlining>full : --inlining ;
+
+flags como-linux CFLAGS <optimization>off : -O0 ;
+flags como-linux CFLAGS <optimization>speed : -O3 ;
+flags como-linux CFLAGS <optimization>space : -Os ;
+
+flags como-linux CFLAGS <debug-symbols>on : -g ;
+flags como-linux LINKFLAGS <debug-symbols>on : -g ;
+
+flags como-linux FINDLIBS : m ;
+flags como-linux FINDLIBS : rt ;
+
+flags como-linux CFLAGS <cflags> ;
+flags como-linux C++FLAGS <cxxflags> ;
+flags como-linux DEFINES <define> ;
+flags como-linux UNDEFS <undef> ;
+flags como-linux HDRS <include> ;
+flags como-linux STDHDRS <sysinclude> ;
+flags como-linux LINKFLAGS <linkflags> ;
+flags como-linux ARFLAGS <arflags> ;
+
+flags como-linux.link LIBRARIES <library-file> ;
+flags como-linux.link LINKPATH <library-path> ;
+flags como-linux.link FINDLIBS-ST <find-static-library> ;
+flags como-linux.link FINDLIBS-SA <find-shared-library> ;
+
+flags como-linux.link RPATH <dll-path> ;
+flags como-linux.link RPATH_LINK <xdll-path> ;
+
+
+actions link bind LIBRARIES
+{
+    $(CONFIG_COMMAND) $(LINKFLAGS) -o "$(<[1])" "$(>)" -L"$(LINKPATH)" -Wl,-R$(SPACE)-Wl,"$(RPATH)" -Wl,-rpath-link$(SPACE)-Wl,"$(RPATH_LINK)"  "$(LIBRARIES)"  "$(LIBRARIES)" -l$(FINDLIBS-SA) -l$(FINDLIBS-ST) 2>&1
+}
+
+actions link.dll bind LIBRARIES
+{
+    $(CONFIG_COMMAND) $(LINKFLAGS) -shared -o "$(<[1])" "$(>)" -L"$(LINKPATH)" -Wl,-R$(SPACE)-Wl,"$(RPATH)" -Wl,-rpath-link$(SPACE)-Wl,"$(RPATH_LINK)" "$(LIBRARIES)"  "$(LIBRARIES)" -l$(FINDLIBS-SA) -l$(FINDLIBS-ST) 2>&1
+}
+
+actions compile.c
+{
+    $(CONFIG_COMMAND) -c --c99 --long_long -U$(UNDEFS) -D$(DEFINES) $(CFLAGS) -I"$(HDRS)" -I"$(STDHDRS)" -o "$(<)" "$(>)" 2>&1
+}
+
+actions compile.c++
+{
+    $(CONFIG_COMMAND) -tused -c --long_long -U$(UNDEFS) -D$(DEFINES) $(CFLAGS) $(C++FLAGS) -I"$(HDRS)" -I"$(STDHDRS)"  -o "$(<)" "$(>)" 2>&1
+}
+
+actions archive
+{
+    ar rcu $(<) $(>)
+}
+

Added: boost-jam/boost-build/branches/upstream/current/tools/como-win.jam
===================================================================
--- boost-jam/boost-build/branches/upstream/current/tools/como-win.jam	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/tools/como-win.jam	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,122 @@
+# (C) Copyright David Abrahams 2001.
+# (C) Copyright MetaCommunications, Inc. 2004.
+
+# Distributed under the Boost Software License, Version 1.0. (See
+# accompanying file LICENSE_1_0.txt or copy at
+# http://www.boost.org/LICENSE_1_0.txt)
+
+# The following #// line will be used by the regression test table generation
+# program as the column heading for HTML tables. Must not include version number.
+#//<a href="http://www.comeaucomputing.com/">Comeau<br>C++</a>
+
+import common ;
+import como ;
+import feature ;
+import generators ;
+import toolset : flags ;
+
+feature.extend-subfeature toolset como : platform : win ;
+
+# Initializes the Comeau toolset for windows.
+# The command is the command which invokes the compiler.
+# You should either set environment variable COMO_XXX_INCLUDE where
+# XXX is the used backed (as described in documentation), or pass
+# that as part of command, e.g:
+# 
+#   using como-win : 4.3 : "set COMO_BCC_INCLUDE=C:/include &&" como.exe ;
+rule init ( version ? : command * : options * )
+{
+    local condition = [  common.check-init-parameters como-win
+        : version $(version) ] ;
+    
+    command = [ common.get-invocation-command como-win : como.exe :
+        $(command) ] ;    
+    
+    common.handle-options como-win : $(condition) : $(command) : $(options) ;
+}
+
+generators.register-c-compiler como-win.compile.c++ : CPP : OBJ 
+  : <toolset>como <toolset-como:platform>win ;
+generators.register-c-compiler como-win.compile.c : C : OBJ
+  : <toolset>como <toolset-como:platform>win ;
+
+generators.register-linker como-win.link 
+  : OBJ SEARCHED_LIB STATIC_LIB IMPORT_LIB 
+  : EXE RSP 
+  : <toolset>como <toolset-como:platform>win ;  
+# Note that status of shared libraries support is not clear, so we don't
+# define the link.dll generator.
+generators.register-composing como-winc.archive 
+  : OBJ : STATIC_LIB RSP
+  : <toolset>como <toolset-como:platform>win ;  
+
+flags como-win C++FLAGS <exception-handling>off : --no_exceptions ;
+flags como-win C++FLAGS <exception-handling>on : --exceptions ;
+
+flags como-win CFLAGS <inlining>off : --no_inlining ;
+flags como-win CFLAGS <inlining>on <inlining>full : --inlining ;
+
+# The following seems to be VC-specific options. At least,
+# when I uncomment then, Comeau with bcc as backend reports
+# that bcc32 invocation.
+#
+#flags como-win CFLAGS <debug-symbols>on : /Zi ;
+#flags como-win CFLAGS <optimization>off : /Od ;
+
+flags como-win CFLAGS <cflags> ;
+flags como-win CFLAGS : -D_WIN32 ; # make sure that we get the Boost Win32 platform config header.
+flags como-win CFLAGS <threading>multi : -D_MT ; # make sure that our config knows that threading is on.
+flags como-win C++FLAGS <cxxflags> ;
+flags como-win DEFINES <define> ;
+flags como-win UNDEFS <undef> ;
+flags como-win HDRS <include> ;
+flags como-win SYSHDRS <sysinclude> ;
+flags como-win LINKFLAGS <linkflags> ;
+flags como-win ARFLAGS <arflags> ;
+flags como-win NO_WARN <no-warn> ;
+
+#flags como-win STDHDRS : $(COMO_INCLUDE_PATH) ;
+#flags como-win STDLIB_PATH : $(COMO_STDLIB_PATH)$(SLASH) ;
+
+flags como-win LIBPATH <library-path> ;
+flags como-win LIBRARIES <library-file> ;
+flags como-win FINDLIBS <find-shared-library> ;
+flags como-win FINDLIBS <find-static-library> ;
+
+#### Link ####
+
+rule link ( targets + : sources * : properties * )
+{
+    common.response-file $(targets) : $(sources) : $(targets[2]) 
+      : $(properties) ;
+}
+
+# for como, we repeat all libraries so that dependencies are always resolved
+actions link bind LIBRARIES
+{
+    $(CONFIG_COMMAND) --no_version --no_prelink_verbose $(LINKFLAGS) -o "$(<[1]:S=)" @"$(<[2])" "$(LIBRARIES)" "$(FINDLIBS:S=.lib)"
+}
+
+actions compile.c
+{
+    $(CONFIG_COMMAND) -c --c99 -e5 --no_version --display_error_number --diag_suppress=9,21,161,748,940,962 -U$(UNDEFS) -D$(DEFINES) $(WARN) $(CFLAGS) -I"$(HDRS)" -I"$(STDHDRS)" -I"$(SYSHDRS)" -o "$(<:D=)" "$(>)"
+}
+
+actions compile.c++
+{
+    $(CONFIG_COMMAND) -c -e5 --no_version --no_prelink_verbose --display_error_number --long_long --diag_suppress=9,21,161,748,940,962 -D__STL_LONG_LONG -U$(UNDEFS) -D$(DEFINES) $(WARN) $(CFLAGS) $(C++FLAGS) -I"$(HDRS)" -I"$(STDHDRS)" -I"$(SYSHDRS)" -o "$(<)" "$(>)"
+}
+
+#### Archive ####
+
+rule archive ( targets + : sources * : properties * )    
+{
+    common.response-file $(targets) : $(sources) : $(targets[2]) : $(properties) ;             
+}
+
+actions updated together piecemeal archive
+{
+    $(CONFIG_COMMAND) --no_version --no_prelink_verbose --prelink_object @"$(>)"
+    lib $(ARFLAGS) /nologo /out:"$(<:S=.lib)" @"$(>)"
+}
+

Added: boost-jam/boost-build/branches/upstream/current/tools/como.jam
===================================================================
--- boost-jam/boost-build/branches/upstream/current/tools/como.jam	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/tools/como.jam	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,30 @@
+# Copyright Vladimir Prus 2004.
+# Distributed under the Boost Software License, Version 1.0.
+# (See accompanying file LICENSE_1_0.txt
+# or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+# This is a generic 'intel' toolset. Depending on the current
+# system, it forwards either to 'intel-linux' or 'intel-win'
+# modules.
+
+import feature ;
+import os ;
+import toolset ;
+
+feature.extend toolset : como ;
+feature.subfeature toolset como : platform : : propagated link-incompatible ;
+
+rule init ( * : * )
+{
+    if [ os.name ] = LINUX
+    {
+        toolset.using como-linux : 
+          $(1) : $(2) : $(3) : $(4) : $(5) : $(6) : $(7) : $(8) : $(9) ;
+    }
+    else
+    {
+        toolset.using como-win :
+          $(1) : $(2) : $(3) : $(4) : $(5) : $(6) : $(7) : $(8) : $(9) ;
+
+    }        
+}

Added: boost-jam/boost-build/branches/upstream/current/tools/cw.jam
===================================================================
--- boost-jam/boost-build/branches/upstream/current/tools/cw.jam	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/tools/cw.jam	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,234 @@
+# Copyright (C) Reece H Dunn 2004
+# Distributed under the Boost Software License, Version 1.0.
+# (See accompanying file LICENSE_1_0.txt or copy at
+# http://www.boost.org/LICENSE_1_0.txt)
+
+# based on the msvc.jam toolset
+
+import property ;
+import generators ;
+import os ;
+import type ;
+import toolset : flags ;
+import errors : error ;
+import feature : feature get-values ;
+import path ;
+import sequence : unique ;
+import common ;
+
+if [ MATCH (--debug-configuration) : [ modules.peek : ARGV ] ]
+{
+   .debug-configuration = true ;
+}
+
+feature.extend toolset : cw ;
+
+rule init ( version ? : command * : options * )
+{
+   # TODO: fix the $(command[1]) = $(compiler) issue
+    
+    setup = [ get-values <setup> : $(options) ] ;
+    setup    ?= cwenv.bat ;
+    compiler = [ get-values <compiler> : $(options) ] ;
+    compiler ?= mwcc ;
+    linker = [ get-values <linker> : $(options) ] ;
+    linker   ?= mwld ;
+
+    local condition = [ common.check-init-parameters cw :
+        version $(version) ] ;
+
+    command = [ common.get-invocation-command cw : mwcc.exe : $(command) :
+      [ default-paths $(version) ] ] ;
+    
+    common.handle-options cw : $(condition) : $(command) : $(options) ;
+
+    if $(command)
+    {
+        command = [ common.get-absolute-tool-path $(command[-1]) ] ;
+    }
+    local root = $(command) ;
+
+    setup = $(root)\\$(setup) ;
+
+   # map the batch file in setup so it can be executed
+
+   setup = "call \""$(setup)"\" > nul " ;
+
+   if [ os.name ] = NT
+   {
+      setup = $(setup)"
+" ;
+   }
+   else
+   {
+      setup = "cmd /S /C "$(setup)" \"&&\" " ;
+   }
+
+   # bind the setup command to the tool so it can be executed before the
+   # command
+
+   local prefix = $(setup) ;
+
+   flags cw.compile .CC $(condition) : $(prefix)$(compiler) ;
+   flags cw.link .LD $(condition) : $(prefix)$(linker) ;
+   flags cw.archive .LD $(condition) : $(prefix)$(linker) ;
+}
+
+rule default-paths ( version ? ) # FIXME
+{
+   local possible-paths ;
+   local ProgramFiles = [ common.get-program-files-dir ] ;
+
+   # TODO: add support for cw8 and cw9 detection
+
+   local version-6-path = $(ProgramFiles)"\\Metrowerks\\CodeWarrior" ;
+   possible-paths += $(version-6-path) ;
+
+   # perform post-processing
+
+   possible-paths
+      = $(possible-paths)"\\Other Metrowerks Tools\\Command Line Tools" ;
+
+   possible-paths += [ modules.peek : PATH Path path ] ;
+
+   return $(possible-paths) ;
+}
+
+## declare generators
+
+generators.register-c-compiler cw.compile.c++ : CPP : OBJ : <toolset>cw ;
+generators.register-c-compiler cw.compile.c : C : OBJ : <toolset>cw ;
+
+generators.register-linker cw.link
+   : OBJ SEARCHED_LIB STATIC_LIB IMPORT_LIB
+   : EXE RSP
+   : <toolset>cw
+   ;
+generators.register-linker cw.link.dll
+   : OBJ SEARCHED_LIB STATIC_LIB IMPORT_LIB
+   : SHARED_LIB IMPORT_LIB RSP
+   : <toolset>cw
+   ;
+
+generators.register-composing cw.archive
+   : OBJ
+   : STATIC_LIB RSP
+   : <toolset>cw
+   ;
+
+## compilation phase
+
+flags cw WHATEVER <toolset-cw:version> ;
+
+flags cw.compile CFLAGS <debug-symbols>on : -g ;
+flags cw.compile CFLAGS <optimization>off : -O0 ;
+flags cw.compile CFLAGS <optimization>speed : -O4,p ;
+flags cw.compile CFLAGS <optimization>space : -O4,s ;
+flags cw.compile CFLAGS <inlining>off : -inline off ;
+flags cw.compile CFLAGS <inlining>on : -inline on ;
+flags cw.compile CFLAGS <inlining>full : -inline all ;
+flags cw.compile CFLAGS <exception-handling>off : -Cpp_exceptions off ;
+flags cw.compile CFLAGS <rtti>off : -RTTI off ;
+
+flags cw.compile USER_CFLAGS <cflags> : ;
+flags cw.compile.c++ USER_CFLAGS <cxxflags> : ;
+
+flags cw.compile DEFINES <define> ;
+flags cw.compile UNDEFS <undef> ;
+flags cw.compile INCLUDES <include> ;
+
+actions compile.c
+{
+   $(.CC) -c -cwd include -lang c -U$(UNDEFS) -D$(DEFINES) $(CFLAGS) $(USER_CFLAGS) -I- -I"$(INCLUDES)" -o "$(<)" "$(>)"
+}
+actions compile.c++
+{
+   $(.CC) -c -cwd include -lang c++ -U$(UNDEFS) -D$(DEFINES) $(CFLAGS) $(USER_CFLAGS) -I- -I"$(INCLUDES)" -o "$(<)" "$(>)"
+}
+
+## linking phase
+
+flags cw.link DEF_FILE <def-file> ;
+
+flags cw LINKFLAGS <debug-symbols>on : -g ;
+flags cw LINKFLAGS <user-interface>console : -subsystem console ;
+flags cw LINKFLAGS <user-interface>gui : -subsystem windows ;
+flags cw LINKFLAGS <user-interface>wince : -subsystem wince ;
+flags cw LINKFLAGS <user-interface>native : -subsystem native ;
+flags cw LINKFLAGS <user-interface>auto : -subsystem auto ;
+
+flags cw LINKFLAGS <main-target-type>LIB/<link>static : -library ;
+flags cw LINKFLAGS <main-target-type>LIB/<link>shared : -shared ;
+
+toolset.flags cw.link USER_LINKFLAGS <linkflags> ;
+toolset.flags cw.link LINKPATH <library-path> ;
+
+if [ os.name ] in NT
+{
+   rule link ( targets + : sources * : properties * )
+   {
+      common.response-file $(targets) : $(sources) : $(targets[2])
+         : $(properties) ;
+   }
+
+   rule link.dll ( targets + : sources * : properties * )
+   {
+      common.response-file $(targets) : $(sources) : $(targets[3])
+         : $(properties) ;
+      DEPENDS $(<) : [ on $(<) return $(DEF_FILE) ] ;
+   }
+
+   rule archive ( targets + : sources * : properties * )
+   {
+      common.response-file $(targets) : $(sources) : $(targets[2])
+         : $(properties) ;
+   }
+
+   actions archive
+   {
+      if exist "$(<[1])" DEL "$(<[1])"
+      $(.LD) -library -o "$(<[1])" @"$(<[2])"
+   }
+}
+else # cygwin
+{
+   rule link ( targets + : sources * : properties * )
+   {
+      common.response-file $(targets) : $(sources) : $(targets[2])
+         : $(properties) ;
+   }
+
+   rule link.dll ( targets + : sources + : properties * )
+   {
+      common.response-file $(targets) : $(sources) : $(targets[3])
+         : $(properties) ;
+      .cygpath = "cygpath -d " ;
+      DEPENDS $(<) : [ on $(<) return $(DEF_FILE) ] ;
+   }
+
+   rule archive ( targets + : sources * : properties * )
+   {
+      common.response-file $(targets) : $(sources) : $(targets[2])
+         : $(properties) ;
+   }
+
+   actions archive
+   {
+      _bbv2_out_="$(<)"
+      if test -f "$_bbv2_out_" ; then
+         _bbv2_existing_="$(<:W)"
+      fi
+      $(.LD) -library -o "$(<:W)" $_bbv2_existing_ @"$(>:W)"
+   }
+}
+
+actions link bind DEF_FILE
+{
+   $(.LD) -o "$(<[1]:W)" -L"$(LINKPATH)" $(LINKFLAGS) $(USER_LINKFLAGS) @"$(<[2]:W)"
+}
+
+actions link.dll bind DEF_FILE
+{
+   $(.LD) -o "$(<[1]:W)" -implib "$(<[2]:W)" -L"$(LINKPATH)" $(LINKFLAGS) -f "$(DEF_FILE)" $(USER_LINKFLAGS) @"$(<[3]:W)"
+}
+

Added: boost-jam/boost-build/branches/upstream/current/tools/darwin.jam
===================================================================
--- boost-jam/boost-build/branches/upstream/current/tools/darwin.jam	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/tools/darwin.jam	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,68 @@
+#  Copyright (C) Christopher Currie 2003. Permission to copy, use,
+#  modify, sell and distribute this software is granted provided this
+#  copyright notice appears in all copies. This software is provided
+# "as is" without express or implied warranty, and with no claim as to
+#  its suitability for any purpose.
+
+#  Please see http://article.gmane.org/gmane.comp.lib.boost.build/3389/
+#  for explanation why it's a separate toolset.
+
+import feature : feature ;
+import toolset : flags ;
+import type ;
+import common ;
+
+toolset.register darwin ;
+import gcc ;
+toolset.inherit-generators darwin : gcc ;
+toolset.inherit-rules darwin : gcc ;
+toolset.inherit-flags darwin : gcc ;
+
+# No additional initialization should be necessary
+rule init ( version ? : command * : options * )
+{
+    local condition = [ common.check-init-parameters darwin : version $(version) ] ;    
+    local command = [ common.get-invocation-command darwin : g++ : $(command) ] ;
+    
+    common.handle-options darwin : $(condition) : $(command) : $(options) ;
+    
+    gcc.init-link-flags darwin darwin $(condition) ;
+}
+
+# Darwin has a different shared library suffix
+type.set-generated-target-suffix SHARED_LIB : <toolset>darwin : dylib ;
+# we need to be able to tell the type of .dylib files
+type.register-suffixes dylib : SHARED_LIB ;
+
+feature framework : : free ;
+
+flags darwin.compile OPTIONS <link>shared : -dynamic ;
+flags darwin.compile OPTIONS : -Wno-long-double -no-cpp-precomp  ;
+flags darwin.compile.c++ OPTIONS : -fcoalesce-templates ;
+
+flags darwin.link FRAMEWORK <framework> ;
+
+# This is flag is useful for debugging the link step
+# uncomment to see what libtool is doing under the hood
+# flags darwin.link.dll OPTIONS : -Wl,-v ;
+
+actions link bind LIBRARIES
+{
+    $(CONFIG_COMMAND) $(ST_OPTIONS) -L"$(LINKPATH)" -o "$(<)" "$(>)" "$(LIBRARIES)" -l$(FINDLIBS-SA) -l$(FINDLIBS-ST) -framework$(_)$(FRAMEWORK) $(OPTIONS)   
+}
+
+rule link.dll
+{
+    _ on $(<) = " " ;
+}
+
+actions link.dll bind LIBRARIES
+{
+    $(CONFIG_COMMAND) -dynamiclib -L"$(LINKPATH)" -o "$(<)" "$(>)" "$(LIBRARIES)" -l$(FINDLIBS-SA) -l$(FINDLIBS-ST) -framework$(_)$(FRAMEWORK) $(OPTIONS) 
+}
+
+actions piecemeal archive
+{
+    ar -c -r -s $(ARFLAGS) "$(<:T)" "$(>:T)"
+}
+

Added: boost-jam/boost-build/branches/upstream/current/tools/doxygen.jam
===================================================================
--- boost-jam/boost-build/branches/upstream/current/tools/doxygen.jam	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/tools/doxygen.jam	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,178 @@
+#  Copyright (C) 2003 Doug Gregor. Permission to copy, use, modify,
+#  sell and distribute this software is granted provided this
+#  copyright notice appears in all copies. This software is provided
+#  "as is" without express or implied warranty, and with no claim as
+#  to its suitability for any purpose.
+
+#  This module defines rules to handle generation of BoostBook XML
+#  from Doxygen XML output. 
+
+import "class" : new ;
+import targets ;
+import feature ;
+import property ;
+import generators ;
+import boostbook ;
+import type ;
+import path ;
+import print ;
+import regex ;
+import stage ;
+import project ;
+
+feature.feature doxygen:param : : free ;
+feature.feature prefix : : free ;
+feature.feature reftitle : : free ;
+
+type.register DOXYFILE : doxyfile ; # Doxygen input file
+type.register DOXYGEN_XML_MULTIFILE : : XML ; # Doxygen XML multi-file output
+type.register DOXYGEN_XML : doxygen : XML : main ; # Doxygen XML output
+
+# Initialize the Doxygen module. Parameters are:
+#   name: the name of the 'doxygen' executable. If not specified, the name
+#         'doxygen' will be used
+rule init ( name ? )
+{
+  if ! $(.initialized)
+  {
+    .initialized = true ;
+      
+    if $(name)
+    {
+      .doxygen = $(name) ; 
+    }   
+    
+    generators.register-composing doxygen.headers-to-doxyfile : H HPP : DOXYFILE ; 
+    generators.register-standard doxygen.run : DOXYFILE : DOXYGEN_XML_MULTIFILE ;
+    generators.register-standard doxygen.xml-to-boostbook : DOXYGEN_XML : BOOSTBOOK ;
+    
+    if ! [ boostbook.xsl-dir ]
+    {
+        ECHO "warning: Doxygen initialization: Boost.Build stylesheets not found " ;
+        ECHO "warning: Generation of single XML file won't be possible. " ;
+    }
+    else
+    {          
+        generators.register-standard doxygen.collect : DOXYGEN_XML_MULTIFILE : DOXYGEN_XML ;
+    }
+            
+    IMPORT $(__name__) : doxygen : : doxygen ;
+  }
+}
+
+rule name ( )
+{
+  return $(.doxygen) ;
+}
+
+# Runs Doxygen on the given Doxygen configuration file (the source) to
+# generate Doxygen XML (in multiple files). The output is dumped
+# according to the settings in the Doxygen configuration file, not
+# according to the target! Because of this, we essentially "touch" the
+# target file, in effect making it look like we've really written
+# something useful to it. Anyone that uses this action must deal with
+# this behavior.  
+actions doxygen-action 
+{
+  "$(NAME:E=doxygen)" $(>) ;
+  echo "Stamped" > "$(<)"
+}
+
+# Generates a doxygen configuration file (doxyfile) given a set of C++
+# sources anda property list that may contain <doxygen:param>
+# features.
+rule headers-to-doxyfile ( target : sources * : properties * )
+{
+  local text "# Generated by Boost.Build version 2" ;
+
+  # Translate <doxygen:param> into command line flags.  
+  for local param in [ feature.get-values <doxygen:param> : $(properties) ]
+  {
+    local namevalue = [ regex.match ([^=]*)=(.*) : $(param) ] ;
+    text += "$(namevalue[1]) = $(namevalue[2])" ;
+  }
+ 
+  local headers = "" ;
+  for local source in $(sources:G=)
+  {
+    headers = "$(headers) $(source)" ;
+  }
+
+  text += "GENERATE_HTML = NO" ;
+  text += "GENERATE_LATEX = NO" ;
+  text += "GENERATE_XML = YES" ;
+  text += "INPUT = $(headers) " ;
+  print.output $(target) plain ;
+  print.text $(text) : true ;
+}
+
+# Run Doxygen. See doxygen-action for a description of the strange
+# properties of this rule
+rule run ( target : source : properties * )
+{
+  doxygen-action $(target) : $(source) ;  
+  NAME on $(target) = $(.doxygen) ;
+}
+
+# Collect the set of Doxygen XML files into a single XML source file
+# that can be handled by an XSLT processor. The source is completely
+# ignored (see doxygen-action), because this action picks up the
+# Doxygen XML index file xml/index.xml. This is because we can't teach
+# Doxygen to act like a NORMAL program and take a "-o output.xml"
+# argument (grrrr). The target of the collection will be a single
+# Doxygen XML file.
+rule collect ( target : source : properties * )
+{
+  local collect-xsl-dir = [ path.native 
+	                    [ path.join [ boostbook.xsl-dir ] doxygen collect ] 
+                          ] ;
+  local collect-path = [ path.join [ path.pwd ] xml ] ;
+  local real-source = [ path.native xml/index.xml ] ;
+  NOTFILE $(real-source) ;
+  xslt $(target) : $(real-source) $(collect-xsl-dir:S=.xsl) 
+                 : <xsl:param>doxygen.xml.path=$(collect-path)
+                 ;
+}
+
+# Translate Doxygen XML into BoostBook
+rule xml-to-boostbook ( target : source : properties * )
+{
+  local xsl-dir = [ boostbook.xsl-dir ] ;
+  local d2b-xsl = [ path.native 
+	              [ path.join [ boostbook.xsl-dir ] doxygen 
+	                doxygen2boostbook.xsl ] ] ;
+
+  local xslt-properties = $(properties) ;
+  for local prefix in [ feature.get-values <prefix> : $(properties) ]
+  {
+    xslt-properties += "<xsl:param>boost.doxygen.header.prefix=$(prefix)" ;
+  }
+  for local title in [ feature.get-values <reftitle> : $(properties) ]
+  {
+    xslt-properties += "<xsl:param>boost.doxygen.reftitle=\"$(title)\"" ;
+  }
+
+  xslt $(target) : $(source) $(d2b-xsl) : $(xslt-properties) ;
+}
+
+# User-level rule to generate BoostBook XML from a set of headers via Doxygen. 
+rule doxygen ( target-name : sources * : requirements * : default-build * )
+{
+  local project = [ project.current ] ;
+
+  local doxyfile = [ 
+    new typed-target $(target-name) : $(project) : BOOSTBOOK
+        : [ targets.main-target-sources $(sources) : $(target-name) ] 
+        : [ targets.main-target-requirements $(requirements) : $(project) ] 
+        : [ targets.main-target-default-build $(default-build) : $(project) ]
+    ] ;
+
+  targets.main-target-alternative $(doxyfile) ;
+
+  targets.main-target-alternative
+    [ new stage-target-class $(target-name:S=.xml) : $(project) 
+      : [ $(doxyfile).name ]
+      : [ targets.main-target-requirements $(requirements) <location>. : $(project) ] 
+      : [ targets.main-target-default-build $(default-build) : $(project) ] 
+    ] ;
+}
\ No newline at end of file

Added: boost-jam/boost-build/branches/upstream/current/tools/fop.jam
===================================================================
--- boost-jam/boost-build/branches/upstream/current/tools/fop.jam	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/tools/fop.jam	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,40 @@
+#  Copyright (C) 2003 Doug Gregor. Permission to copy, use, modify,
+#  sell and distribute this software is granted provided this
+#  copyright notice appears in all copies. This software is provided
+#  "as is" without express or implied warranty, and with no claim as
+#  to its suitability for any purpose.
+
+#  This module defines rules to handle generation of PDF and PostScript files
+#  from XSL Formatting Objects via Apache FOP
+
+import generators ;
+
+generators.register-standard fop.fo-to-print : FO : PDF ;
+generators.register-standard fop.fo-to-print : FO : PS ;
+
+rule init ( fop-dir ? : java-home ? )
+{
+  if ! $(fop-dir)
+  {
+    fop-dir = [ modules.peek : FOP_DIR ] ;
+  }
+
+  if ! $(.initialized)
+  {
+    .initialized = true ;
+    .fop-dir = $(fop-dir) ;
+    .java-home = $(java-home) ;
+  }
+}
+
+rule fo-to-print ( target : source : properties * )
+{
+  JAVA_HOME on $(target) = $(.java-home) ;
+  FOP_DIR on $(target) = $(.fop-dir) ;
+  fop $(target) : $(source) ;
+}
+
+actions fop
+{
+  JAVA_HOME=$(JAVA_HOME) $(FOP_DIR)/fop.sh $(>) $(<)
+}
\ No newline at end of file

Added: boost-jam/boost-build/branches/upstream/current/tools/gcc.jam
===================================================================
--- boost-jam/boost-build/branches/upstream/current/tools/gcc.jam	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/tools/gcc.jam	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,335 @@
+#  Copyright (c) 2001 David Abrahams.
+#  Copyright (c) 2002-2003 Rene Rivera.
+#  Copyright (c) 2002-2003 Vladimir Prus.
+#
+#  Use, modification and distribution is subject to the Boost Software
+#  License Version 1.0. (See accompanying file LICENSE_1_0.txt or
+#  http://www.boost.org/LICENSE_1_0.txt)
+
+import toolset : flags ;
+import property ;
+import generators ;
+import os ;
+import type ;
+import feature ;
+import "class" : new ;
+import set ;
+import common ;
+import errors ;
+
+feature.extend toolset : gcc ;
+
+import unix ;
+toolset.inherit-generators gcc : unix : unix.link unix.link.dll ;
+toolset.inherit-flags gcc : unix ;
+toolset.inherit-rules gcc : unix ;
+
+
+
+# Make the "o" suffix used for gcc toolset on all
+# platforms
+type.set-generated-target-suffix OBJ : <toolset>gcc : o ;
+type.set-generated-target-suffix STATIC_LIB : <toolset>gcc : a ;
+
+
+# Initializes the gcc toolset for the given version.
+# If necessary, command may be used to specify where the compiler
+# is located.
+# The parameter 'options' is a space-delimited list of options, each
+# one being specified as <option-name>option-value. Valid option names
+# are: cxxflags, linkflags and linker-type. Accepted values for linker-type
+# are gnu and sun, gnu being the default.
+# Example:
+#   using gcc : 3.4 : : <cxxflags>foo <linkflags>bar <linker-type>sun ;
+rule init ( version ? : command * : options * )
+{
+    local condition = [ common.check-init-parameters gcc : version $(version) ] ;
+    
+    local command = [ common.get-invocation-command gcc : g++ : $(command) ] ;
+
+    common.handle-options gcc : $(condition) : $(command) : $(options) ;
+    
+    local linker = [ feature.get-values <linker-type> : $(options) ] ;
+    if ! $(linker) {
+        linker = gnu ;
+    }
+    init-link-flags gcc $(linker) $(condition) ;
+}
+
+if [ os.name ] = NT
+{
+    # This causes single-line command invocation to not go through
+    # .bat files, thus avoiding command-line length limitations
+    JAMSHELL = % ;  
+}
+
+generators.register-c-compiler gcc.compile.c++ : CPP : OBJ : <toolset>gcc ;
+generators.register-c-compiler gcc.compile.c : C : OBJ : <toolset>gcc ;
+
+
+# Declare flags and action for compilation
+flags gcc.compile OPTIONS <optimization>off : -O0 ;
+flags gcc.compile OPTIONS <optimization>speed : -O3 ;
+flags gcc.compile OPTIONS <optimization>space : -Os ;
+
+flags gcc.compile OPTIONS <inlining>off : -fno-inline ;
+flags gcc.compile OPTIONS <inlining>on : -Wno-inline ;
+flags gcc.compile OPTIONS <inlining>full : -finline-functions -Wno-inline ;
+
+flags gcc.compile OPTIONS <debug-symbols>on : -g ;
+flags gcc.compile OPTIONS <profiling>on : -pg ;
+# On cygwin and mingw, gcc generates position independent code by default,
+# and warns if -fPIC is specified. This might not be the right way
+# of checking if we're using cygwin. For example, it's possible 
+# to run cygwin gcc from NT shell, or using crosscompiling.
+# But we'll solve that problem when it's time. In that case
+# we'll just add another parameter to 'init' and move this login
+# inside 'init'.
+if [ os.name ] != CYGWIN && [ os.name ] != NT
+{        
+    flags gcc.compile OPTIONS <link>shared/<main-target-type>LIB : -fPIC ;
+}    
+if [ os.name ] != NT
+{
+    HAVE_SONAME = "" ;
+}
+
+
+
+flags gcc.compile OPTIONS <cflags> ;
+flags gcc.compile.c++ OPTIONS <cxxflags> ;
+flags gcc.compile DEFINES <define> ;
+flags gcc.compile INCLUDES <include> ;
+
+rule compile.c++
+{
+    # Some extensions are compiled as C++ by default. For others, we need
+    # to pass -x c++.
+    # We could always pass -x c++ but distcc does not work with it.
+    if ! $(>:S) in .cc .cp .cxx .cpp .c++ .C
+    {
+        LANG on $(<) = "-x c++" ;
+    }    
+}
+
+
+actions compile.c++
+{
+    "$(CONFIG_COMMAND)" $(LANG) -Wall -ftemplate-depth-100 $(OPTIONS) -D$(DEFINES) -I"$(INCLUDES)" -c -o "$(<)" "$(>)" 
+}
+
+rule compile.c
+{
+    # If we use the name g++ then default file suffix -> language mapping
+    # does not work. So have to pass -x option. Maybe, we can work around this
+    # by allowing the user to specify both C and C++ compiler names.
+    #if $(>:S) != .c
+    #{
+        LANG on $(<) = "-x c" ;
+    #}    
+}
+
+
+actions compile.c
+{
+    "$(CONFIG_COMMAND)" $(LANG) -Wall $(OPTIONS) -D$(DEFINES) -I"$(INCLUDES)" -c -o "$(<)" "$(>)" 
+}
+
+# The class which check that we don't try to use
+# the <link-runtime>static property while creating or using shared library,
+# since it's not supported by gcc/libc.
+class gcc-linking-generator : unix-linking-generator
+{
+    rule generated-targets ( sources + : property-set : project name ? )
+    {
+        if <link-runtime>static in [ $(property-set).raw ] 
+        {
+            local m ;
+            if [ id ] = "gcc.link.dll"
+            {
+                m = "on gcc, DLL can't be build with <link-runtime>static" ;
+            }         
+            if ! $(m) {                
+                for local s in $(sources)
+                {
+                    local type = [ $(s).type ] ;
+                    if $(type) &&  [ type.is-derived $(type) SHARED_LIB ] 
+                    {
+                        m = "on gcc, using DLLS together with the <link-runtime>static options is not possible " ;
+                    }                
+                }                
+            }
+            if $(m)
+            {
+                errors.user-error $(m) :
+                  "it's suggested to use <link-runtime>static together with the <link>static" ;
+            }
+            
+        }
+                        
+        return [ unix-linking-generator.generated-targets 
+            $(sources) : $(property-set) : $(project) $(name) ] ;
+    }    
+}
+
+generators.register [ new gcc-linking-generator gcc.link : LIB OBJ : EXE 
+    : <toolset>gcc ] ;
+
+generators.register [ new gcc-linking-generator gcc.link.dll : LIB OBJ : SHARED_LIB 
+    : <toolset>gcc ] ;
+
+generators.override gcc.prebuilt : builtin.prebuilt ;
+
+
+
+# Declare flags for linking
+# First, the common flags
+flags gcc.link OPTIONS <debug-symbols>on : -g ;
+flags gcc.link OPTIONS <profiling>on : -pg ;
+flags gcc.link OPTIONS <linkflags> ;
+flags gcc.link LINKPATH <library-path> ;
+flags gcc.link FINDLIBS-ST <find-static-library> ;
+flags gcc.link FINDLIBS-SA <find-shared-library> ;
+flags gcc.link LIBRARIES <library-file> ;
+
+# For <link-runtime>static we made sure there are no dynamic libraries 
+# in the link
+flags gcc.link OPTIONS <link-runtime>static : -static ;
+
+# Now, the vendor specific flags
+# The parameter linker can be either gnu or sun
+rule init-link-flags ( toolset linker condition )
+{
+    switch $(linker)
+    {
+    case gnu :
+        {
+        # Strip the binary when no debugging is needed.
+        # We use --strip-all flag as opposed to -s since icc
+        # (intel's compiler) is generally option-compatible with
+        # and inherits from gcc toolset, but does not support -s
+        flags $(toolset).link OPTIONS $(condition)/<debug-symbols>off : -Wl,--strip-all 
+          : unchecked ;
+        flags $(toolset).link RPATH $(condition) : <dll-path> : unchecked ;
+        flags $(toolset).link RPATH_LINK $(condition) : <xdll-path> : unchecked ;
+        }
+    case darwin :
+        {
+        # we can't pass -s to ld unless we also pass -static
+        # so we removed -s completly from OPTIONS and add it
+        # to ST_OPTIONS            
+        flags $(toolset).link ST_OPTIONS $(condition)/<debug-symbols>off : -s 
+           : unchecked ;  
+        flags $(toolset).link RPATH $(condition) : <dll-path> : unchecked ;
+        flags $(toolset).link RPATH_LINK $(condition) : <xdll-path> : unchecked ;
+        }
+
+    case sun :
+        {
+        flags $(toolset).link OPTIONS $(condition)/<debug-symbols>off : -Wl,-s 
+            : unchecked ;
+        flags $(toolset).link RPATH $(condition) : <dll-path> : unchecked ;
+        # Solaris linker does not have a separate -rpath-link, but
+        # allows to use -L for the same purpose.
+        flags $(toolset).link LINKPATH $(condition) : <xdll-path> : unchecked ;
+
+        # This permits shared libraries with non-PIC code on Solaris
+        # VP, 2004/09/07: Now that we have -fPIC hardcode in link.dll,
+        # the following is not needed. Whether -fPIC should be hardcoded,
+        # is a separate question.
+        # AH, 2004/10/16: it is still necessary because some tests link
+        # against static libraries that were compiled without PIC.
+        flags $(toolset).link OPTIONS $(condition)/<link>shared : -mimpure-text 
+          : unchecked ;
+        }
+    case * :
+        {
+            errors.user-error
+            "$(toolset) initialization: invalid linker '$(linker)'" :
+            "The value '$(linker)' specified for <linker> is not recognized." :
+            "Possible values are 'sun', 'gnu'" ;
+        }
+    }
+}
+
+# Declare actions for linking
+rule link ( targets * : sources * : properties * )
+{
+    SPACE on $(targets) = " " ;    
+}
+
+actions link bind LIBRARIES
+{
+    "$(CONFIG_COMMAND)" -L"$(LINKPATH)" -Wl,-R$(SPACE)-Wl,"$(RPATH)" -Wl,-rpath-link$(SPACE)-Wl,"$(RPATH_LINK)" -o "$(<)" "$(>)" "$(LIBRARIES)" -l$(FINDLIBS-ST) -l$(FINDLIBS-SA) $(OPTIONS) 
+}
+
+# Declare action for creating static libraries
+# The 'r' letter means to replace files in the archive
+# The 'u' letter means only outdated files in the archive
+#   should be replaced.
+# The 'c' letter means suppresses warning in case the archive
+#   does not exists yet. That warning is produced only on
+#   some platforms, for whatever reasons.
+actions piecemeal archive 
+{
+    ar ruc "$(<)" "$(>)"
+}
+
+
+rule link.dll ( targets * : sources * : properties * )
+{
+    SPACE on $(targets) = " " ;    
+}
+
+# Differ from 'link' above only by -shared.
+actions link.dll bind LIBRARIES
+{
+    "$(CONFIG_COMMAND)" -L"$(LINKPATH)" -Wl,-R$(SPACE)-Wl,"$(RPATH)" -o "$(<)" $(HAVE_SONAME)-Wl,-h$(SPACE)-Wl,$(<[1]:D=) -shared "$(>)"  "$(LIBRARIES)" -l$(FINDLIBS-ST) -l$(FINDLIBS-SA) $(OPTIONS)  
+}
+
+# Set up threading support. It's somewhat contrived, so perform it at the end,
+# to avoid cluttering other code.
+
+if [ os.on-windows ] 
+{
+    flags gcc OPTIONS <threading>multi : -mthreads ;
+}
+else if [ modules.peek : UNIX ] 
+{
+    switch [ modules.peek : JAMUNAME ]
+    {
+    case SunOS* :
+        {
+        flags gcc OPTIONS <threading>multi : -pthreads ;
+        flags gcc FINDLIBS-SA <threading>multi : rt ;
+        }
+    case BeOS :
+        {
+        # BeOS has no threading options, don't set anything here.
+        }
+    case *BSD :
+        {
+        flags gcc OPTIONS <threading>multi : -pthread ;
+        # there is no -lrt on BSD
+        }
+    case DragonFly :
+        {
+        flags gcc OPTIONS <threading>multi : -pthread ;
+        # there is no -lrt on BSD - DragonFly is a FreeBSD variant,
+        # which anoyingly doesn't say it's a *BSD.
+        }
+    case IRIX :
+        {
+        # gcc on IRIX does not support multi-threading, don't set anything here.
+        }
+    case HP_UX :
+        {
+        # gcc on HP-UX does not support multi-threading, don't set anything here
+        }
+    case * :
+        {
+        flags gcc OPTIONS <threading>multi : -pthread ;
+        flags gcc FINDLIBS-SA <threading>multi : rt ;
+        }
+    }
+}

Added: boost-jam/boost-build/branches/upstream/current/tools/gettext.jam
===================================================================
--- boost-jam/boost-build/branches/upstream/current/tools/gettext.jam	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/tools/gettext.jam	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,222 @@
+#  Copyright (C) Vladimir Prus 2003. Permission to copy, use, modify, sell and
+#  distribute this software is granted provided this copyright notice appears in
+#  all copies. This software is provided "as is" without express or implied
+#  warranty, and with no claim as to its suitability for any purpose.
+
+#  This module support GNU gettext internationalization utilities.
+# 
+#  It provides two main target rules: 'gettext.catalog', used for
+#  creating machine-readable catalogs from translations files, and
+#  'gettext.update', used for update translation files from modified
+#  sources.
+# 
+#  To add i18n support to your application you should follow these
+#  steps.
+#  
+#  - Decide on a file name which will contain translations and
+#  what main target name will be used to update it. For example::
+#    
+#    gettext.update update-russian : russian.po a.cpp my_app ;
+# 
+#  - Create the initial translation file by running::
+#
+#    bjam update-russian
+#
+#  - Edit russian.po. For example, you might change fields like LastTranslator.
+#  
+#  - Create a main target for final message catalog::
+#
+#    gettext.catalog russian : russian.po ;
+#
+#  The machine-readable catalog will be updated whenever you update 
+#  "russian.po". The "russian.po" file will be updated only on explicit
+#  request. When you're ready to update translations, you should
+#  
+#  - Run::
+# 
+#    bjam update-russian
+#
+#  - Edit "russian.po" in appropriate editor.
+#   
+#  The next bjam run will convert "russian.po" into machine-readable form.
+#
+#  By default, translations are marked by 'i18n' call. The 'gettext.keyword'
+#  feature can be used to alter this.
+  
+
+import targets ;
+import property-set ;
+import virtual-target ;
+import "class" : new ;
+import project ;
+import type ;
+import generators ;
+import errors ;
+import feature : feature ;
+import toolset : flags ;
+import regex ;
+
+.path = "" ;
+
+# Initializes the gettext module.
+rule init ( path ? # Path where all tools are located. If not specified,
+                   # they should be in PATH.          
+          )
+{
+    if $(.initialized) && $(.path) != $(path)
+    {
+        errors.error "Attempt to reconfigure with different path" ;
+    }
+    .initialized = true ;
+    if $(path)
+    {        
+        .path = $(path)/ ;
+    }    
+}
+
+# Creates a main target 'name', which, when updated, will cause
+# file 'existing-translation' to be updated with translations
+# extracted from 'sources'. It's possible to specify main target
+# in sources --- it which case all target from dependency graph
+# of those main targets will be scanned, provided they are of
+# appropricate type. The 'gettext.types' feature can be used to
+# control the types.
+# 
+# The target will be updated only if explicitly requested on the
+# command line.
+rule update ( name : existing-translation sources + : requirements * )
+{
+    local project = [ project.current ] ;
+    
+    targets.main-target-alternative
+      [ new update-translations-class $(name) : $(project) : 
+        $(existing-translation) $(sources)
+        : [ targets.main-target-requirements $(requirements) : $(project) ]        
+      ] ;
+    $(project).mark-target-as-explicit $(name) ;
+}
+
+
+# The human editable source, containing translation.
+type.register gettext.PO : po ; 
+# The machine readable message catalog.
+type.register gettext.catalog : mo : : main ;
+# Intermediate type produce by extracting translations from
+# sources.
+type.register gettext.POT : pot ; 
+
+# Identifies the keyword that should be used when scanning sources.
+# Default: i18n
+feature gettext.keyword : : free ;
+# Contains space-separated list of sources types which should be scanned. 
+# Default: "C CPP"
+feature gettext.types : : free ;
+
+generators.register-standard gettext.compile : gettext.PO : gettext.catalog ;
+
+class update-translations-class : basic-target
+{
+    import regex : split ;
+   
+    rule __init__ ( name : project : sources * : requirements )
+    {
+        basic-target.__init__ $(name) : $(project) : $(sources) : $(requirements) 
+          : $(default-build) ;
+    }
+            
+    rule construct ( source-targets * : property-set )
+    {
+        local types = [ $(property-set).get <gettext.types> ] ;
+        types ?= "C CPP" ;
+        types = [ regex.split $(types) " " ] ;
+        property-set = [ property-set.empty ] ;
+
+        if ! $(.constructed)
+        {            
+            # First deterime the list of sources that must be scanned to 
+            # messages.
+            local all-sources ;
+            for local s in $(source-targets[2-])
+            {
+                all-sources += [ virtual-target.traverse $(s) : : include-sources ] ;
+            }
+            local right-sources ;
+            for local s in $(all-sources)
+            {
+                if [ $(s).type ] in $(types)
+                {
+                    right-sources += $(s) ;
+                }                
+            }
+            
+            if $(right-sources)
+            {                                                                                        
+                local new-messages = [ new file-target $(self.name) : gettext.POT : $(self.project) ] ;
+                local extract = 
+                  [ new action $(new-messages) : $(right-sources) : gettext.extract ] ;
+                $(new-messages).action $(extract) ;
+                
+                local r = [ new notfile-target $(self.name) : $(self.project) ] ;
+                local a = [ new action $(r) : $(source-targets[1]) $(new-messages) 
+                  : gettext.update-po-dispatch ] ;
+                $(r).action $(a) ;
+                .constructed = [ virtual-target.register $(r) ] ;
+            }
+            else
+            {
+                errors.error "No source could be scanned by gettext tools" ;
+            }            
+        }
+        return $(.constructed) ;                
+    }        
+}
+
+flags gettext.extract KEYWORD <gettext.keyword> ;
+actions extract
+{
+    $(.path)xgettext -k$(KEYWORD:E=i18n) -o $(<) $(>)
+}
+
+# Does realy updating of po file. The tricky part is that
+# we're actually updating one of the sources:
+# $(<) is the NOTFILE target we're updating
+# $(>[1]) is the PO file to be really updated.
+# $(>[2]) is the PO file created from sources.
+#
+# When file to be updated does not exist (during the
+# first run), we need to copy the file created from sources.
+# In all other cases, we need to update the file.
+rule update-po-dispatch
+{    
+    NOCARE $(>[1]) ;
+    gettext.create-po $(<) : $(>) ;
+    gettext.update-po $(<) : $(>) ;
+    _ on $(<) = " " ;    
+    ok on $(<) = "" ;
+    EXISTING_PO on $(<) = $(>[1]) ;
+}
+
+# Due to fancy interaction of existing and updated, this rule
+# can be called with with one source, in which case we copy
+# the lonely source into EXISTING_PO, or with two sources,
+# in which case the action body expands to nothing.
+# I'd really like to have "missing" action modifier.
+actions quietly existing updated create-po bind EXISTING_PO
+{
+    cp$(_)"$(>[1])"$(_)"$(EXISTING_PO)"$($(>[2]:E=ok))    
+}
+
+actions updated update-po bind EXISTING_PO
+{
+    $(.path)msgmerge$(_)-U$(_)"$(EXISTING_PO)"$(_)"$(>[1])"
+}
+
+actions gettext.compile 
+{
+    $(.path)msgfmt -o $(<) $(>)   
+}
+
+IMPORT $(__name__) : update : : gettext.update ;
+
+
+                  
\ No newline at end of file

Added: boost-jam/boost-build/branches/upstream/current/tools/intel-linux.jam
===================================================================
--- boost-jam/boost-build/branches/upstream/current/tools/intel-linux.jam	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/tools/intel-linux.jam	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,65 @@
+#  Copyright (c) 2003 Michael Stevens
+#
+#  Use, modification and distribution is subject to the Boost Software
+#  License Version 1.0. (See accompanying file LICENSE_1_0.txt or
+#  http://www.boost.org/LICENSE_1_0.txt)
+
+import toolset ;
+import feature ;
+import toolset : flags ;
+
+import intel ;
+import gcc ;
+import common ;
+import errors ;
+
+feature.extend-subfeature toolset intel : platform : linux ;
+
+toolset.inherit-generators intel-linux 
+     <toolset>intel <toolset-intel:platform>linux : gcc ;
+toolset.inherit-rules intel-linux : gcc ;
+toolset.inherit-flags intel-linux : gcc 
+        : <inlining>off <inlining>on <inlining>full <optimization>space ;
+
+# Initializes the intel-linux toolset
+#   version in mandatory
+#   name (default icc) is used to invoke the specified intellinux complier
+#   compile and link options allow you to specify addition command line options for each version
+rule init ( version ? :  command * : options * )
+{
+    local condition = [ common.check-init-parameters intel-linux
+        : version $(version) ] ;
+    
+    command = [ common.get-invocation-command intel-linux : icc 
+        : $(command) : /opt/intel_cc_80/bin ] ;
+                
+    common.handle-options intel-linux : $(condition) : $(command) : $(options) ;
+
+    gcc.init-link-flags intel-linux gnu $(condition) ;
+
+}
+
+flags intel-linux.compile OPTIONS <inlining>off : "-Ob0" ;
+flags intel-linux.compile OPTIONS <inlining>on : "-Ob1" ;
+flags intel-linux.compile OPTIONS <inlining>full : "-Ob2" ;
+flags intel-linux.compile OPTIONS <optimization>space : "-O1" ; # no specific space optimization flag in icc
+actions compile.c++
+{
+    "$(CONFIG_COMMAND)" -c -xc++ $(OPTIONS) -D$(DEFINES) -I"$(INCLUDES)" -c -o "$(<)" "$(>)"
+}
+
+actions compile.c
+{
+    "$(CONFIG_COMMAND)" -c -xc $(OPTIONS) -D$(DEFINES) -I"$(INCLUDES)" -c -o "$(<)" "$(>)"
+}
+
+actions link bind LIBRARIES
+{
+    "$(CONFIG_COMMAND)" -L"$(LINKPATH)" -Wl,-R$(SPACE)-Wl,"$(RPATH)" -Wl,-rpath-link$(SPACE)-Wl,"$(RPATH_LINK)" -o "$(<)" "$(>)" "$(LIBRARIES)" -l$(FINDLIBS-SA) -l$(FINDLIBS-ST) $(OPTIONS)
+}
+
+# Differ from 'link' above only by -shared.
+actions link.dll bind LIBRARIES
+{
+    "$(CONFIG_COMMAND)" -L"$(LINKPATH)" -Wl,-R$(SPACE)-Wl,"$(RPATH)" -o "$(<)" -Wl,-h$(SPACE)-Wl,$(<[1]:D=) -shared "$(>)"  "$(LIBRARIES)" -l$(FINDLIBS-SA) -l$(FINDLIBS-ST) $(OPTIONS)
+}

Added: boost-jam/boost-build/branches/upstream/current/tools/intel-win.jam
===================================================================
--- boost-jam/boost-build/branches/upstream/current/tools/intel-win.jam	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/tools/intel-win.jam	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,127 @@
+# Copyright Vladimir Prus 2004.
+# Distributed under the Boost Software License, Version 1.0.
+# (See accompanying file LICENSE_1_0.txt
+# or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+import toolset ;
+import feature ;
+import toolset : flags ;
+import os ;
+
+# This is needed because the rule we import here depend on 'common'
+# That's nasty.
+import common ;
+
+import intel ;
+
+feature.extend-subfeature toolset intel : platform : win ;
+
+import msvc ;
+toolset.inherit-generators intel-win <toolset>intel <toolset-intel:platform>win : msvc ;
+toolset.inherit-flags intel-win : msvc ;
+toolset.inherit-rules intel-win : msvc ;
+
+# Initializes the intel toolset for windows
+rule init ( version ? :     # the compiler version
+            command * :     # the command to invoke the compiler itself
+            options *       # Additional option: <compatibility>
+                            # either 'vc6', 'vc7', 'vc7.1'
+                            # or 'native'(default).
+          )
+{           
+    local compatibility = 
+      [ feature.get-values <compatibility> : $(options) ] ;
+    local condition = [  common.check-init-parameters intel-win
+        : version $(version) : compatibility $(compatibility) ] ;
+    
+    command = [ common.get-invocation-command intel-win : icc.exe :
+        $(command) ] ;    
+    
+    common.handle-options intel-win : $(condition) : $(command) : $(options) ;
+
+    local root = [ common.get-absolute-tool-path $(command[-1]) ] ;)
+    
+    local setup ;
+    setup = $(root:D)/iclvars.bat ;
+    setup = "call \""$(setup)"\" > nul " ;
+        
+    if [ os.name ] = NT
+    {
+        setup = $(setup)"
+" ;
+    }
+    else
+    {
+        setup = "cmd /S /C "$(setup)" \"&&\" " ;
+    }
+    
+    
+    flags intel-win.compile .CC $(condition) : $(setup)icl ; 
+    flags intel-win.link .LD $(condition) : $(setup)xilink ; 
+    flags intel-win.archive .LD $(condition) : $(setup)xilink ;       
+    
+    local m = [ MATCH (.).* : $(version) ] ;
+    local major = $(m[1]) ;
+
+    local C++FLAGS ;
+    # Reduce the number of spurious error messages
+    C++FLAGS += /Qwn5 /Qwd985 ;
+
+    # Enable ADL
+    C++FLAGS += -Qoption,c,--arg_dep_lookup ; #"c" works for C++, too
+
+    if $(major) > 5
+    {
+        C++FLAGS += /Zc:forScope ;  # Add support for correct for loop scoping
+    }
+
+    # Add options recognized only by intel7
+    if $(major) >= 7
+    {
+        C++FLAGS += /Qansi_alias ;
+    }
+    
+    if $(compatibility) = vc6
+    {
+        C++FLAGS += 
+          # Emulate VC6
+          /Qvc6
+      
+          # no wchar_t support in vc6 dinkum library.  Furthermore, in vc6
+          # compatibility-mode, wchar_t is not a distinct type from unsigned
+          # short
+          -DBOOST_NO_INTRINSIC_WCHAR_T
+          ; 
+    }
+    else
+    {
+        if $(major) > 5
+        {
+            # Add support for wchar_t
+            C++FLAGS += /Zc:wchar_t
+              # Tell the dinkumware library about it.
+              -D_NATIVE_WCHAR_T_DEFINED
+              ;
+        }
+    }        
+    if $(compatibility) && $(compatibility) != native
+    {        
+        C++FLAGS += /Q$(base-vc) ;
+    }
+    else        
+    {
+        C++FLAGS += 
+          -Qoption,cpp,--arg_dep_lookup
+          -Qoption,cpp,--const_string_literals
+          -Qoption,cpp,--new_for_init
+          -Qoption,cpp,--no_implicit_typename
+          -Qoption,cpp,--no_friend_injection
+          -Qoption,cpp,--no_microsoft_bugs
+          ;
+    }
+    
+    flags intel-win CFLAGS $(condition) : $(C++FLAGS) ;
+    
+}
+
+flags intel-win.link LIBRARY_OPTION <toolset>intel : "" ;

Added: boost-jam/boost-build/branches/upstream/current/tools/intel.jam
===================================================================
--- boost-jam/boost-build/branches/upstream/current/tools/intel.jam	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/tools/intel.jam	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,30 @@
+# Copyright Vladimir Prus 2004.
+# Distributed under the Boost Software License, Version 1.0.
+# (See accompanying file LICENSE_1_0.txt
+# or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+# This is a generic 'intel' toolset. Depending on the current
+# system, it forwards either to 'intel-linux' or 'intel-win'
+# modules.
+
+import feature ;
+import os ;
+import toolset ;
+
+feature.extend toolset : intel ;
+feature.subfeature toolset intel : platform : : propagated link-incompatible ;
+
+rule init ( * : * )
+{
+    if [ os.name ] = LINUX
+    {
+        toolset.using intel-linux : 
+          $(1) : $(2) : $(3) : $(4) : $(5) : $(6) : $(7) : $(8) : $(9) ;
+    }
+    else
+    {
+        toolset.using intel-win :
+          $(1) : $(2) : $(3) : $(4) : $(5) : $(6) : $(7) : $(8) : $(9) ;
+
+    }        
+}

Added: boost-jam/boost-build/branches/upstream/current/tools/kylix.jam
===================================================================
--- boost-jam/boost-build/branches/upstream/current/tools/kylix.jam	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/tools/kylix.jam	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,22 @@
+#  Copyright (C) Vladimir Prus 2002. Permission to copy, use, modify, sell and
+#  distribute this software is granted provided this copyright notice appears in
+#  all copies. This software is provided "as is" without express or implied
+#  warranty, and with no claim as to its suitability for any purpose.
+
+#  Support for the Borland's Kylix command line compiler
+
+import toolset ;
+
+toolset.register kylix ;
+
+toolset.inherit kylix : borland ;
+
+COMPILER_NAME = bc++ ;
+LINKER_NAME = bc++ ;
+
+actions link bind LIBRARIES
+{
+    $(LINKER_NAME) $(OPTIONS) -q -L$(LINKPATH) -e$(<[1]) $(>) $(LIBRARIES) lib$(FINDLIBS-ST).a lib$(FINDLIBS-SA).so
+}
+
+

Added: boost-jam/boost-build/branches/upstream/current/tools/lex.jam
===================================================================
--- boost-jam/boost-build/branches/upstream/current/tools/lex.jam	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/tools/lex.jam	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,34 @@
+#  Copyright (C) Vladimir Prus 2002. Permission to copy, use, modify, sell and
+#  distribute this software is granted provided this copyright notice appears in
+#  all copies. This software is provided "as is" without express or implied
+#  warranty, and with no claim as to its suitability for any purpose.
+
+import type ;
+import generators ;
+import feature ;
+import property ;
+
+
+feature.feature flex.prefix : : free ;
+type.register LEX : l ;
+type.register LEX++ : ll ;
+generators.register-standard lex.lex : LEX : C ;
+generators.register-standard lex.lex : LEX++ : CPP ;
+
+rule init ( )
+{
+}
+
+rule lex ( target : source : properties * )
+{   
+    local r = [ property.select flex.prefix : $(properties) ] ;
+    if $(r)
+    {
+        PREFIX on $(<) = $(r:G=) ;
+    }
+}
+
+actions lex 
+{
+    flex -P$(PREFIX) -o$(<) $(>)    
+}
\ No newline at end of file

Added: boost-jam/boost-build/branches/upstream/current/tools/make.jam
===================================================================
--- boost-jam/boost-build/branches/upstream/current/tools/make.jam	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/tools/make.jam	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,70 @@
+#  Copyright (C) Vladimir Prus 2002. Permission to copy, use, modify, sell and
+#  distribute this software is granted provided this copyright notice appears in
+#  all copies. This software is provided "as is" without express or implied
+#  warranty, and with no claim as to its suitability for any purpose.
+
+#  This module defines the 'make' main target rule.
+
+import targets ;
+import "class" : new ;
+import property ;
+import errors : error ;
+import type : type ;
+import regex ;
+import property-set ;
+import project ;
+
+class make-target-class : basic-target
+{
+    import type regex virtual-target ;    
+    import "class" : new ;
+    
+    rule __init__ ( name : project : sources * : requirements * 
+        : make-rule + : default-build * )
+    {     
+        basic-target.__init__ $(name) : $(project) : $(sources) : $(requirements) 
+          : $(default-build) ;
+       
+        self.make-rule = $(make-rule) ;    
+    }
+        
+    rule construct ( source-targets * : property-set )
+    {
+        local t = [ new file-target $(self.name:S=) : [ type.type $(self.name) ]
+                    : $(self.project) ] ;
+        $(t).suffix [ regex.match .(.*) : $(self.name:S) ] ;
+        local a = [ new action $(t) : $(source-targets) : $(self.make-rule) 
+                    : $(property-set) ] ;
+        $(t).action $(a) ;
+        return [ virtual-target.register $(t) ] ;
+    }   
+}
+
+# Declares the 'make' main target.
+rule make ( target-name : sources * : generating-rule + : requirements * 
+            : caller ? )
+{
+    caller ?= [ project.current ] ;
+    caller-module = [ $(caller).project-module ] ;
+    local rules = [ RULENAMES $(caller-module) ] ;
+    if $(generating-rule[1]) in $(rules)
+    {
+        # This is local rule, make it global
+        local n = $(caller-module).$(generating-rule[1]) ;
+        IMPORT $(caller-module) : $(generating-rule[1]) : : $(n) ;
+        generating-rule = $(n) $(generating-rule[2-]) ;
+    }
+    
+   targets.main-target-alternative
+     [ new make-target-class $(target-name) : $(caller)
+       : [ targets.main-target-sources $(sources) : $(target-name) ] 
+       : [ targets.main-target-requirements $(requirements) : $(caller) ] 
+       : $(generating-rule) 
+       : [ targets.main-target-default-build : $(caller) ] 
+     ] ;
+         
+}
+
+IMPORT $(__name__) : make : : make ;
+
+

Added: boost-jam/boost-build/branches/upstream/current/tools/msvc.jam
===================================================================
--- boost-jam/boost-build/branches/upstream/current/tools/msvc.jam	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/tools/msvc.jam	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,361 @@
+# Copyright David Abrahams 2003. Permission to copy, use,
+# modify, sell and distribute this software is granted provided this
+# copyright notice appears in all copies. This software is provided
+# "as is" without express or implied warranty, and with no claim as
+# to its suitability for any purpose.
+import property ;
+import generators ;
+import os ;
+import type ;
+import toolset : flags ;
+import errors : error ;
+import feature : feature get-values ;
+import path ;
+import sequence : unique ;
+import common ;
+
+import rc ;
+
+if [ MATCH (--debug-configuration) : [ modules.peek : ARGV ] ]
+{
+    .debug-configuration = true ;
+}
+
+feature.extend toolset : msvc ;
+
+feature.subfeature toolset msvc : vendor
+  : intel
+  : propagated optional
+  # intel and msvc supposedly have link-compatible objects... remains
+  # to be seen, though ;-)
+  ;
+
+RM =  [ modules.peek common : RM ] ;
+
+# Initialize the toolset for a specific version. As the result, path to
+# compiler and, possible, program names are set up, and will be used when
+# that version of compiler is requested. For example, you might have::
+#
+#    using msvc : 6.5 : X:/some_dir ;
+#    using msvc : 7.0 : Y:/some_dir ;
+#    using msvc : : Z:/some_dir
+#
+# If you have "msvc-6.5" in build request, the version from X: drive will be used,
+# and if you put only "msvc", then drive "Z:" will be used. Note that it's not possible
+# the specify that by default, version 7.0 must be used --- you should use 'using'
+# without version number for that effect. 
+#    
+# version -- 
+# path -- 
+#
+# When invoking tools, we'll first run vcvars32.bat from the configured path and
+# then cl/link, without path.   
+#
+# Note: for free VC7.1 tools, we don't correctly find vcvars32.bar when user
+# explicitly provides a path.
+rule init ( 
+  version ? # the msvc version which is being configured. When omitted
+            # the tools invoked when no explicit version is given will be configured.
+    : command * 
+   # the command to invoke the compiler. If not specified:
+   #       - if version is given, default location for that version will be searched
+   # 
+   #       - if version is not given, default locations for 7.1, 7.0 and 6.* will 
+   #              be searched    
+   # 
+   #       - if compiler is not found in default locations, PATH will be searched.    
+    : options * 
+   # options can include <setup>, <compiler>, <linker> and <resource-compiler>
+)
+{    
+    # setup will be used iff a path has been specified.  If setup is
+    # not specified, vcvars32.bat will be used instead.
+    setup = [ get-values <setup> : $(options) ] ;
+    setup ?= vcvars32.bat ;    
+    compiler = [ get-values <compiler> : $(options) ] ;
+    compiler ?= cl ;
+    linker = [ get-values <linker> : $(options) ] ;
+    linker ?= link ;
+    resource-compiler = [ get-values <resource-compiler> : $(options) ] ;
+    resource-compiler ?= rc ;
+    
+    local condition = [ common.check-init-parameters msvc : 
+        version $(version) ] ;
+
+    # If version is specified, we try to search first in default paths,
+    # and only then in PATH.
+    command = [ common.get-invocation-command msvc : cl.exe : $(command)
+      : [ default-paths $(version) ] : $(version) ] ;
+    
+    common.handle-options msvc : $(condition) : $(command) : $(options) ;
+        
+    if $(command)
+    {        
+        command = [ common.get-absolute-tool-path $(command[-1]) ] ;
+    }
+    local root = $(command:D) ;
+                  
+    setup = $(root)\\bin\\$(setup) ;
+    
+    # CONSIDER: What's the point of 'call'. Can we invoke the script directly?
+    setup = "call \""$(setup)"\" > nul " ;
+    
+    if [ os.name ] = NT
+    {
+        setup = $(setup)"
+" ;
+    }
+    else
+    {
+        setup = "cmd /S /C "$(setup)" \"&&\" " ;
+    }
+
+    # prefix with setup, or quoted path if any
+    local prefix = $(setup) ;
+    
+    flags msvc.compile .CC $(condition) : $(prefix)$(compiler) ;
+    flags msvc.compile .RC $(condition) : $(prefix)$(resource-compiler) ;
+    flags msvc.link .LD $(condition) : $(prefix)$(linker) ;
+    flags msvc.archive .LD $(condition) : $(prefix)$(linker) ;
+    
+    if ! $(version) 
+    {
+        # Even if version is not explicitly specified, try to detect the version
+        # from the path.
+        if [ MATCH "(Microsoft Visual Studio 8)" : $(command) ]
+        {
+            version = 8.0 ;
+        }                 
+        else if [ MATCH "(\\.NET 2003\\VC7)" : $(command) ] ||
+                [ MATCH "(Microsoft Visual C\\+\\+ Toolkit 2003)" : $(command) ]
+        {
+            version = 7.1 ;
+        }
+        else if [ MATCH "(.NET\\VC7)" : $(command) ]
+        {
+            version = 7.0 ;
+        }
+        else
+        {
+            version = 6.0 ;
+        }                
+    }
+                
+    # The following options work only for 7* versions. It means
+    # that if the user has not specified a version he gets 6.0 compatible
+    # behavious (i.e. a bit buggy)
+    if [ MATCH ^(7\..*) : $(version) ] 
+    {
+        flags msvc.compile CFLAGS $(condition) : /Zc:forScope /Zc:wchar_t ;
+    }
+    
+    # 8.0 deprecates some of the options
+    if [ MATCH ^(8) : $(version) ]
+    {
+        flags msvc.compile CFLAGS $(condition)/<optimization>speed : /O2 ;
+        flags msvc.compile CFLAGS $(condition)/<optimization>space : /O1 ;
+    }
+    else
+    {        
+        flags msvc.compile CFLAGS $(condition)/<optimization>speed : /Ogity /O2 /Gs ;
+        flags msvc.compile CFLAGS $(condition)/<optimization>space : /Ogisy /O1 /Gs ;        
+    }        
+}
+
+rule default-paths ( version ? )
+{
+    local possible-paths ;
+    
+    local ProgramFiles = [ modules.peek : ProgramFiles ] ;
+    if $(ProgramFiles)
+    {
+        ProgramFiles = "$(ProgramFiles:J= )" ;
+    }
+    else
+    {
+        ProgramFiles = "c:\\Program Files" ;
+    }
+
+    local version-6-path = $(ProgramFiles)"\\Microsoft Visual Studio\\VC98" ;
+    local version-7-path = $(ProgramFiles)"\\Microsoft Visual Studio .NET\\VC7" ;
+    local version-7.0-path = $(version-7-path) ;
+    local version-7.1-path = $(ProgramFiles)"\\Microsoft Visual Studio .NET 2003\\VC7" ;
+    local version-8.0-path = $(ProgramFiles)"\\Microsoft Visual Studio 8" ;
+    
+    local VS71COMNTOOLS = [ modules.peek : VS71COMNTOOLS ] ;
+    if $(VS71COMNTOOLS)
+    {
+        # VS71COMNTOOLS is set by VS .NET 2003 to <VSDIR>\Common7\Tools
+        version-7.1-path = [ path.make "$(VS71COMNTOOLS:J= )" ] ;
+        version-7.1-path = [ path.parent $(version-7.1-path) ] ;
+        version-7.1-path = [ path.parent $(version-7.1-path) ] ;
+        version-7.1-path = [ path.join $(version-7.1-path) "VC7" ] ;
+        version-7.1-path = [ path.native $(version-7.1-path) ] ;
+    }
+        
+    local VCToolkitInstallDir = [ modules.peek : VCToolkitInstallDir ] ;
+    if $(VCToolkitInstallDir)
+    {
+        version-7.1-path = [ path.make "$(VCToolkitInstallDir:J= )" ] ;
+    }
+    
+    if $(version)
+    {
+        local v = [ MATCH ^(6|[^6].*) : $(version) ] ;
+        possible-paths += $(version-$(v)-path) ;
+    }
+    else
+    {
+        possible-paths += $(version-7.1-path) $(version-7.0-path) $(version-6-path) ;
+    }
+    # The vccars32.bat is actually in "bin" directory.
+    # (except for free VC7.1 tools)
+    possible-paths = $(possible-paths)\\bin $(possible-paths) ;
+
+    return $(possible-paths) ;
+}
+
+
+# Declare generators
+
+# is it possible to combine these?
+# make the generators non-composing, so that they don't convert each source
+# into separate rsp file.
+generators.register-linker msvc.link : OBJ SEARCHED_LIB STATIC_LIB IMPORT_LIB : EXE RSP : <toolset>msvc ;
+generators.register-linker msvc.link.dll : OBJ SEARCHED_LIB STATIC_LIB IMPORT_LIB : SHARED_LIB IMPORT_LIB RSP : <toolset>msvc ;
+
+generators.register-composing msvc.archive : OBJ : STATIC_LIB RSP : <toolset>msvc ;
+generators.register-c-compiler msvc.compile.c++ : CPP : OBJ : <toolset>msvc ;
+generators.register-c-compiler msvc.compile.c : C : OBJ : <toolset>msvc ;
+generators.register-standard msvc.compile.rc : RC : OBJ(%_res) : <toolset>msvc ;
+generators.override msvc.compile.rc : rc.resource-compile ;
+
+#
+# Declare flags and action for compilation
+#
+feature.feature debug-store : object database : propagated ;
+flags msvc.compile CFLAGS <debug-symbols>on/<debug-store>object : /Z7 ;
+flags msvc.compile CFLAGS <debug-symbols>on/<debug-store>database : /Zi ;
+flags msvc.compile CFLAGS <optimization>off : /Od ;
+flags msvc.compile CFLAGS <inlining>off : /Ob0 ;
+flags msvc.compile CFLAGS <inlining>on : /Ob1 ;
+flags msvc.compile CFLAGS <inlining>full : /Ob2 ;
+flags msvc.compile CFLAGS <exception-handling>on : /EHsc ;
+flags msvc.compile CFLAGS <rtti>on : /GR ;
+flags msvc.compile CFLAGS <runtime-debugging>off/<link-runtime>shared : /MD ;
+flags msvc.compile CFLAGS <runtime-debugging>on/<link-runtime>shared : /MDd ;
+
+flags msvc.compile CFLAGS <runtime-debugging>off/<link-runtime>static/<threading>single : /ML ;
+flags msvc.compile CFLAGS <runtime-debugging>on/<link-runtime>static/<threading>single : /MLd ;
+flags msvc.compile CFLAGS <runtime-debugging>off/<link-runtime>static/<threading>multi : /MT ;
+flags msvc.compile CFLAGS <runtime-debugging>on/<link-runtime>static/<threading>multi : /MTd ;
+flags msvc.compile CFLAGS <base-target-type>CPP : /EHsc ;
+
+flags msvc.compile USER_CFLAGS <cflags> : ;
+flags msvc.compile.c++ USER_CFLAGS <cxxflags> : ;
+
+flags msvc.compile PDB_CFLAG <debug-symbols>on/<debug-store>database : /Fd ;  # not used yet
+
+flags msvc.compile DEFINES <define> ;
+flags msvc.compile UNDEFS <undef> ;
+flags msvc.compile INCLUDES <include> ;
+
+flags msvc WHATEVER <toolset-msvc:version> ;
+
+# The actions differ only by explicit selection of input language
+actions compile.c
+{
+    $(.CC) /Zm800 -nologo -TC -U$(UNDEFS) -D$(DEFINES) $(CFLAGS) $(USER_CFLAGS) -I"$(INCLUDES)" -c -Fo"$(<:W)" "$(>:W)"
+}
+actions compile.c++
+{
+    $(.CC) /Zm800 -nologo -TP -U$(UNDEFS) -D$(DEFINES) $(CFLAGS) $(USER_CFLAGS) -I"$(INCLUDES)" -c -Fo"$(<:W)" "$(>:W)"
+}
+
+actions compile.rc
+{
+    $(.RC) -l 0x409 -U$(UNDEFS) -D$(DEFINES) -I"$(INCLUDES)" -fo "$(<:W)" "$(>:W)"
+}
+
+# Declare flags and action for linking
+flags msvc.link PDB_LINKFLAG <debug-symbols>on/<debug-store>database : /PDB: ; # not used yet
+flags msvc.link LINKFLAGS <debug-symbols>on : /DEBUG ;
+flags msvc.link DEF_FILE <def-file> ;
+# The linker disables the default optimizations when using /DEBUG. Whe have
+# to enable them manually for release builds with debug symbols.
+flags msvc LINKFLAGS <debug-symbols>on/<runtime-debugging>off : /OPT:REF,ICF ;
+
+flags msvc LINKFLAGS <user-interface>console : /subsystem:console ;
+flags msvc LINKFLAGS <user-interface>gui : /subsystem:windows ;
+flags msvc LINKFLAGS <user-interface>wince : /subsystem:windowsce ;
+flags msvc LINKFLAGS <user-interface>native : /subsystem:native ;
+flags msvc LINKFLAGS <user-interface>auto : /subsystem:posix ;
+
+flags msvc LINKFLAGS <main-target-type>LIB/<link>shared : /DLL ;
+
+toolset.flags msvc.link USER_LINKFLAGS <linkflags> ;
+toolset.flags msvc.link LINKPATH <library-path> ;
+
+
+flags msvc.link FINDLIBS_ST <find-static-library> ;
+flags msvc.link FINDLIBS_SA <find-shared-library> ;
+flags msvc.link LIBRARY_OPTION <toolset>msvc : "" : unchecked ;
+
+
+rule archive ( targets + : sources * : properties * )    
+{
+    common.response-file $(targets) : $(sources) : $(targets[2]) : $(properties) ;             
+}
+
+rule link ( targets + : sources * : properties * )
+{
+    common.response-file $(targets) : $(sources) : $(targets[2]) 
+      : $(properties) ;
+}
+
+rule link.dll ( targets + : sources * : properties * )
+{
+    common.response-file $(targets) : $(sources) : $(targets[3]) : $(properties) ;
+    DEPENDS $(<) : [ on $(<) return $(DEF_FILE) ] ;
+}    
+
+# Declare action for creating static libraries
+# If library exists, remove it before adding files. See
+# http://article.gmane.org/gmane.comp.lib.boost.build/4241    
+# for rationale.
+if [ os.name ] in NT
+{    
+    # The 'DEL' command would issue a message to stdout
+    # if the file does not exist, so need a check.
+    actions archive 
+    {  
+        if exist "$(<[1])" DEL "$(<[1])"  
+        $(.LD) /lib /NOLOGO /out:"$(<[1])" @"$(<[2])"
+    }
+}
+else
+{
+    actions archive 
+    {  
+        $(RM) "$(<[1])"
+        $(.LD) /lib /NOLOGO /out:"$(<[1])" @"$(<[2])"
+    }
+}
+        
+# incremental linking a DLL causes no end of problems: if the
+# actual exports don't change, the import .lib file is never
+# updated. Therefore, the .lib is always out-of-date and gets
+# rebuilt every time. I'm not sure that incremental linking is
+# such a great idea in general, but in this case I'm sure we
+# don't want it.
+actions link bind DEF_FILE
+{
+    $(.LD) /NOLOGO $(LINKFLAGS) /out:"$(<[1]:W)" /INCREMENTAL:NO /LIBPATH:"$(LINKPATH:W)" $(USER_LINKFLAGS) @"$(<[2]:W)"
+}
+
+actions link.dll bind DEF_FILE
+{
+    $(.LD) /NOLOGO $(LINKFLAGS) /out:"$(<[1]:W)" /INCREMENTAL:NO /IMPLIB:"$(<[2]:W)" /LIBPATH:"$(LINKPATH:W)" /def:$(DEF_FILE) $(USER_LINKFLAGS) @"$(<[3]:W)"
+}
+
+        

Added: boost-jam/boost-build/branches/upstream/current/tools/qt.jam
===================================================================
--- boost-jam/boost-build/branches/upstream/current/tools/qt.jam	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/tools/qt.jam	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,154 @@
+#  Copyright (C) Vladimir Prus 2002. Permission to copy, use, modify, sell and
+#  distribute this software is granted provided this copyright notice appears in
+#  all copies. This software is provided "as is" without express or implied
+#  warranty, and with no claim as to its suitability for any purpose.
+
+import modules ;
+import feature ;
+import errors ;
+import type ;
+import "class" : new ;
+import generators ;
+import project ;
+import toolset : flags ;
+
+# Convert this module into a project, so that we can declare
+# targets here.
+
+project.initialize $(__name__) ;
+project qt ;
+
+# Initialized the QT support module. The 'prefix' parameter 
+# tells where QT is installed. When not given, environmental
+# variable QTDIR should be set.
+rule init ( prefix ? )
+{
+    if ! $(prefix)
+    {
+        prefix = [ modules.peek : QTDIR ] ;
+        if ! $(prefix) 
+        {
+            errors.error 
+              "QT installation prefix not given and QTDIR variable is empty" ;
+        }        
+    }
+ 
+    if $(.initialized)
+    {
+        if $(prefix) != $(.prefix)
+        {
+            errors.error 
+              "Attempt the reinitialize QT with different installation prefix" ;
+        }        
+    } 
+    else
+    {            
+        .initialized = true ;
+        .prefix = $(prefix) ;
+        
+        generators.register-standard qt.moc : H : CPP(moc_%) : <allow>qt ;    
+        
+        type.register UI : ui ;
+        type.register UIC_H : : H ;
+        
+        generators.register-standard qt.uic-h : UI : UIC_H : <allow>qt ;
+        
+        # The following generator is used to convert UI files to CPP
+        # It creates UIC_H from UI, and constructs CPP from UI/UIC_H
+        # In addition, it also returns UIC_H target, so that it can bee
+        # mocced.
+        class qt::uic-cpp-generator : generator
+        {
+            rule __init__ ( )
+            {
+                generator.__init__ qt.uic-cpp : UI UIC_H : CPP : <allow>qt ;
+            }
+                        
+            rule run ( project name ? : properties * : sources + :  multiple ? )
+            {
+                # Consider this:
+                #    obj test : test_a.cpp : <optimization>off ;
+                #
+                # This generator will somehow be called in this case, and,
+                # will fail -- which is okay. However, if there are <library>
+                # properties they will be converted to sources, so the size of 
+                # 'sources' will be more than 1. In this case, the base generator
+                # will just crash -- and that's not good. Just use a quick test
+                # here.
+                                
+                local result ;
+                if ! $(sources[2])
+                {    
+                    # Construct CPP as usual
+                    result = [ generator.run $(project) $(name) 
+                      : $(properties) : $(sources) : $(multiple) ] ;
+                    # If OK, add "UIC_H" target to the returned list
+                    if $(result)
+                    {
+                        local action = [ $(result[1]).action ] ;
+                        local sources = [ $(action).sources ] ;
+                        result += $(sources[2]) ;
+                    }
+                }
+                            
+                return $(result) ;
+            }               
+        }
+    
+        generators.register [ new qt::uic-cpp-generator ] ;
+        
+        # Finally, declare prebuilt target for QT library.
+        local usage-requirements = 
+             <include>$(.prefix)/include 
+             <dll-path>$(.prefix)/lib
+             <library-path>$(.prefix)/lib     
+             <allow>qt
+             ;  
+        lib qt : : <name>qt-mt <threading>multi : : $(usage-requirements) ;
+        lib qt : : <name>qt <threading>single : : $(usage-requirements) ;        
+    }
+}
+
+# Query the installation directory
+# This is needed in at least two scenarios
+# First, when re-using sources from the Qt-Tree.
+# Second, to "install" custom Qt plugins to the Qt-Tree.
+rule directory 
+{ 
+    return $(.prefix) ; 
+} 
+
+# -f forces moc to include the processed source file.
+# Without it, it would think that .qpp is not a header and would not
+# include it from the generated file.
+actions moc 
+{
+    $(.prefix)/bin/moc -f $(>) -o $(<)
+}
+
+space = " " ;
+
+# Sometimes it's required to make 'plugins' available during
+# uic invocation. To help with this we add paths to all dependency
+# libraries to uic commane line. The intention is that it's possible
+# to write
+#    
+#     exe a : ... a.ui ... : <uses>some_plugin ; 
+# 
+# and have everything work. We'd add quite a bunch of unrelated paths
+# but it won't hurt.
+flags qt.uic-h LIBRARY_PATH <xdll-path> ;
+actions uic-h
+{
+    $(.prefix)/bin/uic $(>) -o $(<) -L$(space)$(LIBRARY_PATH)
+}
+
+flags qt.uic-cpp LIBRARY_PATH <xdll-path> ;
+# The second target is uic-generated header name. It's placed in
+# build dir, but we want to include it using only basename.
+actions uic-cpp
+{
+    $(.prefix)/bin/uic $(>[1]) -i $(>[2]:D=) -o $(<) -L$(space)$(LIBRARY_PATH)
+}
+
+

Added: boost-jam/boost-build/branches/upstream/current/tools/rc.jam
===================================================================
--- boost-jam/boost-build/branches/upstream/current/tools/rc.jam	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/tools/rc.jam	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,131 @@
+#  Copyright (C) Andre Hentz 2003. Permission to copy, use, modify, sell and
+#  distribute this software is granted provided this copyright notice appears in
+#  all copies. This software is provided "as is" without express or implied
+#  warranty, and with no claim as to its suitability for any purpose.
+
+import type ;
+import generators ;
+import feature ;
+import errors ;
+import scanner ;
+
+type.register RC : rc ;
+
+rule init ( )
+{
+}
+
+rule resource-compile ( target : sources * : properties * )
+{
+    local OS = [ feature.get-values <os> : $(properties) ] ;
+    switch $(OS)
+    {
+        case "NT" :
+            resource-compile-nt $(target) : $(sources[1]) ;
+        case "CYGWIN" :
+            resource-compile-cygwin $(target) : $(sources[1]) ;
+        case "FREEBSD" :
+            create-empty-object $(target) : $(sources[1]) ;
+        case "SOLARIS" :
+            create-empty-object $(target) : $(sources[1]) ;
+        case "LINUX" :
+            create-empty-object $(target) : $(sources[1]) ;
+        case "*" :
+            errors.error "Cannot process RC files for OS=$(OS)" ;
+    }
+}
+
+
+actions quietly resource-compile-nt
+{
+    rc /i "$(>:D)" /i "$(<:D)" /fo "$(<)" "$(>)"
+}
+
+actions quietly resource-compile-cygwin
+{
+    windres --include-dir "$(>:D)" -o "$(<)" -i "$(>)"
+}
+
+actions quietly create-empty-object
+{
+    as /dev/null -o "$(<)"
+}
+
+# Since it's a common practice to write
+# exe hello : hello.cpp hello.rc
+# we change the name of object created from RC file, to
+# avoid conflict with hello.cpp.
+# The reason we generate OBJ and not RES, is that gcc does not
+# seem to like RES files, but works OK with OBJ.
+# See http://article.gmane.org/gmane.comp.lib.boost.build/5643/
+generators.register-standard rc.resource-compile : RC : OBJ(%_res) ;
+
+# Register scanner for resources
+class res-scanner : scanner 
+{
+    import regex virtual-target path scanner ;    
+    
+    rule __init__ ( includes * )
+    {
+        scanner.__init__ ;
+    
+        self.includes = $(includes) ;
+    }    
+
+    rule pattern ( )
+    {
+        return "(([^ ]+[ ]+(BITMAP|CURSOR|FONT|ICON|MESSAGETABLE|RT_MANIFEST)[ ]+([^ \"]+|\"[^\"]+\"))|(#include[ ]*(<[^<]+>|\"[^\"]+\")))" ;
+    }
+
+    rule process ( target : matches * : binding )
+    {
+        local angle = [ regex.transform $(matches) : "#include[ ]*<([^<]+)>" ] ;
+        local quoted = [ regex.transform $(matches) : "#include[ ]*\"([^\"]+)\"" ] ;
+        local res = [ regex.transform $(matches) : "[^ ]+[ ]+(BITMAP|CURSOR|FONT|ICON|MESSAGETABLE|RT_MANIFEST)[ ]+(([^ \"]+)|\"([^\"]+)\")" : 3 4 ] ;
+
+        # Icons and other includes may referenced as 
+        #
+        # IDR_MAINFRAME ICON "res\\icon.ico"
+        #
+        # so we have to replace double backslashes to single ones.
+        res = [ regex.replace-list $(res) : "\\\\\\\\" : "/" ] ;
+
+        # CONSIDER: the new scoping rule seem to defeat "on target" variables.
+        local g = [ on $(target) return $(HDRGRIST) ] ;  
+        local b = [ NORMALIZE_PATH $(binding:D) ] ;
+
+        # Attach binding of including file to included targets.
+        # When target is directly created from virtual target
+        # this extra information is unnecessary. But in other
+        # cases, it allows to distinguish between two headers of the 
+        # same name included from different places.      
+        # We don't need this extra information for angle includes,
+        # since they should not depend on including file (we can't
+        # get literal "." in include path).
+        local g2 = $(g)"#"$(b) ;
+       
+        angle = $(angle:G=$(g)) ;
+        quoted = $(quoted:G=$(g2)) ;
+        res = $(res:G=$(g2)) ;
+        
+        local all = $(angle) $(quoted) ;
+
+        INCLUDES $(target) : $(all) ;
+        DEPENDS $(target) : $(res) ;
+        NOCARE $(all) $(res) ;
+        SEARCH on $(angle) = $(self.includes:G=) ;
+        SEARCH on $(quoted) = $(b) $(self.includes:G=) ;
+        SEARCH on $(res) = $(b) $(self.includes:G=) ;
+        
+        # Just propagate current scanner to includes, in a hope
+        # that includes do not change scanners. 
+        scanner.propagate $(__name__) : $(angle) $(quoted) : $(target) ;
+    }        
+}
+
+scanner.register res-scanner : include ;
+type.set-scanner RC : res-scanner ;
+
+
+
+

Added: boost-jam/boost-build/branches/upstream/current/tools/stage.jam
===================================================================
--- boost-jam/boost-build/branches/upstream/current/tools/stage.jam	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/tools/stage.jam	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,332 @@
+#  Copyright (C) Vladimir Prus 2002. Permission to copy, use, modify, sell and
+#  distribute this software is granted provided this copyright notice appears in
+#  all copies. This software is provided "as is" without express or implied
+#  warranty, and with no claim as to its suitability for any purpose.
+
+#  This module defines the 'stage' rule, used to copy a set of targets to
+#  a single location
+#
+#  Typical usage:
+#
+#  stage dist : hello_world : <location>/usr/bin ;
+#
+#  The source target will be copied to the specified location. Some targets will
+#  we specially processed. In particular, binaries will be relinked. Free properties
+#  from stage dist will be included to properties used for relinking. For example
+#
+#  stage dist : hello_world : <location>/usr/bin <dll-path>/opt/lib ;
+# 
+#  will cause 'hello_world' to be relinked to the new location, and <dll-path>
+#  property will be added when relinking.
+#
+#  Two properties specifically control 'stage' rule.
+# 
+#  - <location> tells where to put targets. If not specified, directory
+#    with the same name as stage name will be used.
+#  
+#  - <name> tells the new name of the staged target. In this case, only
+#    one target can be specified in sources.
+#
+#  The stage rule can also traverse dependencies, for example to install a
+#  program an all required libraries. Two properties affect this.
+#
+#  - <traverse-dependencies>on tells that dependencies should be traversed.
+#    For each target in 'stage' sources, all sources to that target and all
+#    dependency properties are traversed. Sources and dependecy properties of
+#    those target are traversed recursively.
+#
+#  - <include-type>SOME_TYPE tells that targets of SOME_TYPE or a type derived
+#    from SOME_TYPE, should be included.
+#    If no such property is specified, then all found targets will be staged.
+#    Otherwise, only targets with types mentioned in <include-type> property
+#    will be included.
+#    
+#    Example usage::
+#
+#      stage dist : hello_world : 
+#        <traverse-dependencies>on <include-type>EXE <include-type>SHARED_LIB ;
+#
+
+import targets ;
+import "class" : new ;
+import property ;
+import errors : error ;
+import type : type ;
+import type ;
+import regex ;
+import generators ;
+import feature ;
+import project ;
+
+feature.feature <traverse-dependencies> : off on : incidental ;
+feature.feature <include-type> : : free incidental ;
+
+class stage-target-class : basic-target
+{
+    import feature project type errors generators path ;    
+    import "class" : new ;
+    
+    rule __init__ ( name-and-dir : project : sources * : requirements * : default-build * )
+    {
+        basic-target.__init__ $(name-and-dir) : $(project) : $(sources) : $(requirements) 
+          : $(default-build) ;
+    }
+
+    # If <location> is not set, sets it based on the project data.
+    rule update-location ( property-set )
+    {
+        local loc = [ $(property-set).get <location> ] ;
+        if ! $(loc)
+        {
+            loc = [ path.root $(self.name) [ $(self.project).get location ] ] ;
+
+            property-set = [ $(property-set).add-raw $(loc:G=<location>) ] ;
+        }
+        
+        return $(property-set) ;
+    }
+        
+    # Constructs the targets of types for which a type exists
+    # with the form STAGED_*.
+    rule construct-special-targets ( property-set : source : type )
+    {
+        local targets = [ generators.construct $(self.project) : $(type) :
+            $(property-set) : $(source) : * ] ;
+
+        return $(targets) ;
+    }
+    
+    # Constructs the targets of types for which there is no STAGED_* type.
+    rule construct-regular-targets ( property-set : source )
+    {
+        local n = [ $(source).name ] ;
+        if $(name)
+        {
+            n = $(name) ;
+        }
+        
+        targets = [ new file-target $(n:D=) : [ $(source).type ] 
+            : $(self.project) ] ;
+        local a = [ $(source).action ] ;
+        local new-a ;
+        if $(a)
+        {                    
+            # Copy the properties of original target. They, in particular
+            # can affect the suffix of the target.
+            new-a = [ new action $(targets) : $(source) : common.copy : [ $(a).properties ] ] ;
+        }
+        else
+        {
+            new-a = [ new action $(targets) : $(source) : common.copy ] ;
+        }                                
+        $(targets).suffix [ $(source).suffix ] ;
+        $(targets).action $(new-a) ;
+    
+        return $(targets) ;
+    }
+    
+    rule construct ( source-targets * : property-set )
+    {        
+        local name = [ $(property-set).get <name> ] ;
+        if $(name) && $(source-targets[2])
+        {
+            errors.error "<name> property cannot be specified when staging several targets" ;
+        }
+        
+        if [ $(property-set).get <traverse-dependencies> ] = "on"
+        {
+            source-targets = [ collect-targets $(source-targets) 
+              : [ $(property-set).get <include-type> ] ] ;
+        }
+
+
+        property-set = [ update-location $(property-set) ] ;          
+        local include-types = [ $(property-set).get <include-type> ] ;
+        
+        local result ;
+        for local i in $(source-targets)
+        {
+            # Intermediate targets are those with "unrequested" types.
+            # For example, given "exe a : a.cpp" we can end with RSP
+            # target on windows, and it will be marked as "intermediate".
+            # By default, we don't install such targets.
+            # If specific list of installable types is given, we don't
+            # care if target is intermediate or not.
+            if ! [ $(i).intermediate ] && [ $(i).type ] != SEARCHED_LIB
+            {
+                local staged-targets ;
+                
+                local t = [ $(i).type ] ;
+                
+                # See if something special should be done when staging this
+                # type. It is indicated by presense of special "staged" type            
+                if $(t) && [ type.registered STAGED_$(t) ]
+                {
+                    staged-targets = [ construct-special-targets $(property-set) : $(i) : STAGED_$(t) ] ;
+                }
+                else             
+                {                
+                    staged-targets = [ construct-regular-targets $(property-set) : $(i) ] ;
+                }
+                
+                if ! $(staged-targets)
+                {                    
+                    errors.error "Unable to generate staged version of " [ $(source).str ] ;
+                }                
+
+                for t in [ select-included $(staged-targets) : $(include-types) ]
+                {
+                    local a = [ $(t).action ] ;
+                    {
+                        for local s in [ $(a).targets ]
+                        {
+                            $(s).set-path [ $(property-set).get <location> ] ;
+                        }                        
+                    }
+                    
+                    result += [ virtual-target.register $(t) ] ;          
+                }            
+            }            
+        }
+        
+        return $(result) ;
+    }   
+    
+    rule select-included ( source-targets * : types-to-include * )
+    {
+        local result-targets ;
+        if $(types-to-include)
+        {            
+            for local r in $(source-targets)
+            {
+                local ty = [ $(r).type ] ;        
+                if $(ty)
+                {
+                    if [ include-type $(ty) : $(types-to-include) ]                  
+                    {
+                        result-targets += $(r) ;
+                    }                
+                }           
+            }
+        }
+        else
+        {
+            result-targets = $(source-targets) ;
+        }
+        
+        
+        return $(result-targets) ;
+    }
+    
+    rule collect-targets ( targets * : types-to-include * )
+    {
+        # Find subvariants
+        local s ;        
+        for local t in $(targets)
+        {
+            s += [ $(t).creating-subvariant ] ;
+        }
+        s = [ sequence.unique $(s) ] ;
+        
+        local result = $(targets) ;
+        for local i in $(s)
+        {
+            result += [ $(i).all-referenced-targets ] ;
+        }
+        result = [ sequence.unique $(result) ] ;        
+    }
+        
+    rule check-for-link-compatibility ( * : * )
+    {
+    }
+        
+    # Returns true iff 'type' is subtype of some element of 'types-to-include'.
+    local rule include-type ( type : types-to-include * )
+    {
+        local found ;
+        while $(types-to-include) && ! $(found)
+        {
+            if [ type.is-subtype $(type) $(types-to-include[1]) ]
+            {
+                found = true ;
+            }            
+            types-to-include = $(types-to-include[2-]) ;
+        }
+        
+        return $(found) ;
+    }
+    
+    
+}
+
+# Declare staged version of the EXE type. Generator for this type will
+# cause relinking to the new location.
+type.register STAGED_EXE : : EXE ;
+
+class stage-exe-generator : generator
+{
+    import type property-set modules ;    
+    
+    rule __init__ ( )
+    {
+        generator.__init__ stage-exe : EXE : STAGED_EXE ;
+    }
+    
+    rule run ( project name ? : property-set : source : multiple ? )
+    {
+        local action = [ $(source).action ] ;
+                       
+        # stage can affect the relinking details.
+        local ps = [ $(action).properties ] ;
+        local ps-raw = [ $(ps).raw ] ;
+        # Unless <hardcode-dll-paths>true is in properties, which can
+        # happen only if the user has explicitly requested it, nuke all
+        # <dll-path> properties.
+        if [ $(property-set).get <hardcode-dll-paths> ] != true
+        {
+            ps-raw = [ property.change $(ps-raw) : <dll-path> ] ;
+        }
+        ps-raw = $(ps-raw) [ $(property-set).free ] ;
+        local new-ps = [ property-set.create $(ps-raw) ] ;
+        
+        local cloned-action = [ virtual-target.clone-action $(action) : $(project) :
+          "" : $(new-ps) ] ;
+        local result = [ $(cloned-action).targets ] ;                        
+
+        return $(result) ;
+    }    
+}
+
+generators.register [ new stage-exe-generator ] ;
+
+
+
+# Declares a stage target. When build, it will construct all sources
+# and place in one directory. The directory can be specified in requirements
+# with 'location' property. If not specified, the directory name will be
+# the same as target name, relative to the project where the target 
+# is declared.
+rule stage ( name : sources * : requirements * : default-build * )
+{
+    local project = [ project.current ] ;
+    
+    # Unless the user has explicitly asked us to hardcode dll paths, add
+    # <hardcode-dll-paths>false in requirements, to override default
+    # value.
+    if ! <hardcode-dll-paths>true in $(requirements)
+    {
+        requirements += <hardcode-dll-paths>false ;
+    }        
+   
+    targets.main-target-alternative
+      [ new stage-target-class $(name) : $(project) 
+        : [ targets.main-target-sources $(sources) : $(name) ]
+        : [ targets.main-target-requirements $(requirements) : $(project) ] 
+        : [ targets.main-target-default-build $(default-build) : $(project) ] 
+      ] ;
+}
+
+IMPORT $(__name__) : stage : : stage ;
+
+
+

Added: boost-jam/boost-build/branches/upstream/current/tools/stlport.jam
===================================================================
--- boost-jam/boost-build/branches/upstream/current/tools/stlport.jam	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/tools/stlport.jam	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,188 @@
+# (C) Copyright Gennadiy Rozental 2002. 
+# (C) Copyright Vladimir Prus 2003. 
+# Permission to copy, use,
+# modify, sell and distribute this software is granted provided this
+# copyright notice appears in all copies. This software is provided
+# "as is" without express or implied warranty, and with no claim as
+# to its suitability for any purpose.
+
+# The STLPort is usable by means of 'stdlib' feature. When
+# stdlib=stlport is specified, default version of STLPort will be used,
+# while stdlib=stlport-4.5 will use specific version.
+# The subfeature value 'hostios' means to use host compiler's iostreams.
+#
+# The specific version of stlport is selected by features:
+# The <link> feature selects between static and shared library
+# The <runtime-debugging>on selects STLPort with debug symbols
+# and stl debugging.
+# There's no way to use STLPort with debug symbols but without
+# stl debugging.
+
+# TODO: must implement selection of different STLPort installations based
+# on used toolset.
+# Also, finish various flags:
+#
+# This is copied from V1 toolset, "+" means "impelemnted"
+#+flags $(CURR_TOOLSET) DEFINES <stlport-iostream>off : _STLP_NO_OWN_IOSTREAMS=1 _STLP_HAS_NO_NEW_IOSTREAMS=1 ;
+#+flags $(CURR_TOOLSET) DEFINES <stlport-extensions>off : _STLP_NO_EXTENSIONS=1 ;
+# flags $(CURR_TOOLSET) DEFINES <stlport-anachronisms>off : _STLP_NO_ANACHRONISMS=1 ;
+# flags $(CURR_TOOLSET) DEFINES <stlport-cstd-namespace>global : _STLP_VENDOR_GLOBAL_CSTD=1 ;
+# flags $(CURR_TOOLSET) DEFINES <exception-handling>off : _STLP_NO_EXCEPTIONS=1 ;
+# flags $(CURR_TOOLSET) DEFINES <stlport-debug-alloc>on : _STLP_DEBUG_ALLOC=1 ;
+#+flags $(CURR_TOOLSET) DEFINES <runtime-build>debug : _STLP_DEBUG=1 _STLP_DEBUG_UNINITIALIZED=1 ;
+#+flags $(CURR_TOOLSET) DEFINES <runtime-link>dynamic : _STLP_USE_DYNAMIC_LIB=1 ;
+
+
+import feature : feature subfeature ;
+import project ;
+import "class" : new ;
+import targets ;
+import property-set ; 
+
+# Make this module into a project.
+project.initialize $(__name__) ;
+project stlport ;
+
+# The problem: how to request to use host compiler's iostreams?
+#
+# Solution 1: Global 'stlport-iostream' feature.
+#    That's ugly. Subfeature make more sense for stlport-specific thing.
+# Solution 2: Use subfeature with two values, one of which ("use STLPort iostream")
+#     is default.
+#    The problem is that such subfeature will appear in target paths, and that's ugly
+# Solution 3: Use optional subfeature with only one value.
+
+feature.extend stdlib : stlport ;
+feature.compose <stdlib>stlport : <library>/stlport//stlport ;
+
+subfeature stdlib stlport : version : : optional propagated link-incompatible ;
+
+# STLport iostreams or native iostreams
+subfeature stdlib stlport : iostream : hostios : optional propagated  ;
+
+# STLport extensions
+subfeature stdlib stlport : extensions : noext : optional propagated ;
+
+# STLport anachronisms -- NOT YET SUPPORTED
+# subfeature stdlib stlport : anachronisms : on off ;
+
+# STLport debug allocation -- NOT YET SUPPORTED
+#subfeature stdlib stlport : debug-alloc : off on ;
+
+# Declare a special target class to handle the creation of search-lib-target 
+# instances for STLport. We need a special class, because otherwise we'll have
+# - declare prebuilt targets for all possible toolsets. And by the time 'init'
+#   is called we don't even know the list of toolsets that are registered
+# - when host iostreams are used, we really should produce nothing. It would
+#   be hard/impossible to achieve this using prebuilt targets.
+
+class stlport-target-class : basic-target
+{
+    import feature project type errors generators ;
+    import set : difference ;       
+    
+    rule __init__ ( project : headers ? : libraries ? : requirements * )
+    {
+        basic-target.__init__ stlport : $(project) : : $(requirements) ;
+        self.headers = $(headers) ;
+        self.libraries = $(libraries) ;
+    }
+            
+    rule generate ( property-set )
+    {
+        # Since this target is built with <stdlib>stlport, it will also
+        # have <library>/stlport//stlport in requirements, which will
+        # cause a loop in main target references. Remove that property
+        # manually.
+        
+        property-set = [ property-set.create [ difference
+            [ $(property-set).raw ] : <library>/stlport//stlport <stdlib>stlport ] ] ;
+        return [ basic-target.generate $(property-set) ] ;
+    }
+    
+    
+    rule construct ( source-targets * : property-set )
+    {
+        # Deduce the name of stlport library, based on toolset and
+        # debug setting.
+        local raw = [ $(property-set).raw ] ;
+        local hostios = [ feature.get-values <stdlib-stlport:iostream> : $(raw) ] ;
+        local toolset = [ feature.get-values <toolset> : $(raw) ] ;
+
+        
+        # We don't need libraries if host istreams are used. For
+        # msvc, automatic library selection will be used.
+        if ! $(hostios) && $(toolset) != msvc
+        {            
+            local debug = [ feature.get-values <runtime-debugging> : $(raw) ] ;
+            
+            local name = stlport ;
+            name = $(name)_$(toolset) ;
+            if $(debug) = "on"
+            {
+                name = $(name)_stldebug ;
+            }
+                
+            return [ generators.construct $(self.project) $(name) : SEARCHED_LIB 
+              : $(property-set) ] ;
+        }
+        
+    }
+    
+    rule compute-usage-requirements ( subvariant )
+    {
+        local usage-requirements ;
+        usage-requirements += 
+            <include>$(self.headers) 
+            <dll-path>$(self.libraries)                   
+             <library-path>$(self.libraries)               
+                ;
+            
+        local rproperties = [ $(subvariant).build-properties ] ;
+        # CONSIDER: should this "if" sequence be replaced with
+        # some use of 'property-map' class?
+        if [ $(rproperties).get <runtime-debugging> ] = "on"
+        {
+            usage-requirements += <define>_STLP_DEBUG=1 
+              <define>_STLP_DEBUG_UNINITIALIZED=1 ;
+        }
+        if [ $(rproperties).get <runtime-debugging> ] = "on"            
+        {
+            usage-requirements += <define>_STLP_USE_DYNAMIC_LIB=1 ;
+        }
+        if [ $(rproperties).get <stdlib-stlport:extensions> ] = noext
+        {
+            usage-requirements += <define>_STLP_NO_EXTENSIONS=1 ;
+        }
+        if [ $(rproperties).get <stdlib-stlport:iostream> ] = hostios
+        {
+            usage-requirements += <define>_STLP_NO_OWN_IOSTREAMS=1 
+                                  <define>_STLP_HAS_NO_NEW_IOSTREAMS=1 ;
+        }
+                        
+        return [ property-set.create $(usage-requirements) ] ;
+    }    
+}
+
+rule stlport-target ( headers ? : libraries ? : requirements * )
+{
+    local project = [ project.current ] ;
+    
+    targets.main-target-alternative
+      [ new stlport-target-class  $(project) : $(headers) : $(libraries)        
+        : [ targets.main-target-requirements $(requirements) : $(project) ] 
+      ] ;
+}
+
+# Initialize stlport support. 
+rule init ( version ? :
+            headers       # Location of header files
+            libraries ? # Location of libraries
+         )
+{
+    feature.extend-subfeature stdlib stlport : version : $(version) ;
+    
+    # Declare the main target for this STLPort version.
+    stlport-target $(headers) : $(libraries) : <stdlib>stlport-$(version) ;
+}
+

Added: boost-jam/boost-build/branches/upstream/current/tools/sun.jam
===================================================================
--- boost-jam/boost-build/branches/upstream/current/tools/sun.jam	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/tools/sun.jam	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,112 @@
+#  Copyright (C) Christopher Currie 2003. Permission to copy, use,
+#  modify, sell and distribute this software is granted provided this
+#  copyright notice appears in all copies. This software is provided
+#  "as is" without express or implied warranty, and with no claim as
+#  to its suitability for any purpose.
+
+import property ;
+import generators ;
+import os ;
+import toolset : flags ;
+import feature ;
+import type ;
+import common ;
+
+feature.extend toolset : sun ;
+toolset.inherit  sun : unix ;
+feature.subfeature toolset sun : version ;
+
+feature.extend stdlib : sun-stlport ;
+feature.compose <stdlib>sun-stlport
+    : <cxxflags>-library=stlport4 <linkflags>-library=stlport4
+    ;
+
+rule init ( version ? : command * : options * ) 
+{
+    local condition = [ 
+      common.check-init-parameters sun : version $(version) ] ;
+    
+    command = [ common.get-invocation-command sun : CC 
+        : $(command) : "/opt/SUNWspro/bin" ] ;
+    
+    common.handle-options sun : $(condition) : $(command) : $(options) ;
+    
+    command_c = $(command[1--2]) $(command[-1]:B=cc) ;
+
+    toolset.flags sun CONFIG_C_COMMAND $(condition) : $(command_c) ;
+}
+
+# Declare generators
+generators.register-c-compiler sun.compile.c : C : OBJ : <toolset>sun ;
+generators.register-c-compiler sun.compile.c++ : CPP : OBJ : <toolset>sun ;
+
+# Declare flags and actions for compilation
+flags sun.compile OPTIONS <debug-symbols>on : -g ;
+flags sun.compile OPTIONS <profiling>on : -xprofile=tcov ;
+flags sun.compile OPTIONS <optimization>speed : -fast -xarch=generic ;
+flags sun.compile OPTIONS <optimization>space : -xO2 -xspace ;
+flags sun.compile OPTIONS <threading>multi : -mt ;
+
+flags sun.compile.c++ OPTIONS <inlining>off : +d ;
+
+flags sun.compile OPTIONS <cflags> ;
+flags sun.compile.c++ OPTIONS <cxxflags> ;
+flags sun.compile DEFINES <define> ;
+flags sun.compile INCLUDES <include> ;
+
+actions compile.c
+{
+    "$(CONFIG_C_COMMAND)" $(OPTIONS) -D$(DEFINES) -I"$(INCLUDES)" -c -o "$(<)" "$(>)"
+}
+
+actions compile.c++
+{
+    "$(CONFIG_COMMAND)" $(OPTIONS) -D$(DEFINES) -I"$(INCLUDES)" -c -o "$(<)" "$(>)"
+}
+
+# Declare flags and actions for linking
+flags sun.link OPTIONS <debug-symbols>on : -g ;
+# Strip the binary when no debugging is needed
+flags sun.link OPTIONS <debug-symbols>off : -s ;
+flags sun.link OPTIONS <profiling>on : -xprofile=tcov ;
+flags sun.link OPTIONS <threading>multi : -mt ;
+flags sun.link OPTIONS <linkflags> ;
+flags sun.link LINKPATH <library-path> ;
+flags sun.link FINDLIBS-ST <find-static-library> ;
+flags sun.link FINDLIBS-SA <find-shared-library> ;
+flags sun.link LIBRARIES <library-file> ;
+flags sun.link LINK-RUNTIME <link-runtime>static : static ;
+flags sun.link LINK-RUNTIME <link-runtime>shared : dynamic ;
+flags sun.link RPATH <dll-path> ;
+# On gcc, there are separate options for dll path at runtime and
+# link time. On Solaris, there's only one: -R, so we have to use
+# it, even though it's bad idea.
+flags sun.link RPATH <xdll-path> ;
+
+rule link ( targets * : sources * : properties * )
+{
+    SPACE on $(targets) = " " ;
+}
+
+actions link bind LIBRARIES
+{
+    "$(CONFIG_COMMAND)" $(OPTIONS) -L"$(LINKPATH)" -R"$(RPATH)" -o "$(<)" "$(>)" "$(LIBRARIES)" -Bdynamic -l$(FINDLIBS-SA) -Bstatic -l$(FINDLIBS-ST) -B$(LINK-RUNTIME)
+}
+
+# Slight mods for dlls
+rule link.dll ( targets * : sources * : properties * )
+{
+    SPACE on $(targets) = " " ;
+}
+
+actions link.dll bind LIBRARIES
+{
+    "$(CONFIG_COMMAND)" $(OPTIONS) -L"$(LINKPATH)" -R"$(RPATH)" -o "$(<)" -h$(<[1]:D=) -G "$(>)" "$(LIBRARIES)" -Bdynamic -l$(FINDLIBS-SA) -Bstatic -l$(FINDLIBS-ST) -B$(LINK-RUNTIME)
+}
+
+# Declare action for creating static libraries
+actions piecemeal archive
+{
+    "$(CONFIG_COMMAND)" -xar -o "$(<)" "$(>)"
+}
+

Added: boost-jam/boost-build/branches/upstream/current/tools/symlink.jam
===================================================================
--- boost-jam/boost-build/branches/upstream/current/tools/symlink.jam	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/tools/symlink.jam	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,136 @@
+# (C) Copyright Rene Rivera, 2002-2003.
+#
+# See accompanying license for terms and conditions of use.
+#
+
+# Defines the "symlink" special target. 'symlink' targets make symbolic links
+# to the sources.
+
+import targets modules path class os feature project ;
+
+.count = 0 ;
+
+feature.feature symlink-location : project-relative build-relative : incidental ;
+
+# The class representing "symlink" targets.
+#
+class symlink-targets : basic-target
+{
+    import numbers modules class property project path ;
+    
+    rule __init__ (
+      project
+        : targets *
+        : sources *
+    )
+    {    
+        # Generate a fake name for now. Need unnamed targets eventually.
+        local c = [ modules.peek symlink : .count ] ;
+        modules.poke symlink : .count : [ numbers.increment $(c) ] ;
+        local fake-name = symlink#$(c) ;
+    
+          basic-target.__init__ $(fake-name) : $(project) : $(sources) ;
+    
+        # Remember the targets to map the sources onto. Pad or truncate
+        # to fit the sources given.
+        self.targets = ;
+        for local source in $(sources)
+        {
+            if $(targets)
+            {
+                self.targets += $(targets[1]) ;
+                targets = $(targets[2-]) ;
+            }
+            else
+            {
+                self.targets += $(source) ;
+            }
+        }
+    
+        # The virtual targets corresponding to the given targets.
+        self.virtual-targets = ;
+    }    
+    
+    rule construct ( source-targets * : property-set )
+    {
+        local i = 1 ;
+        for local t in $(source-targets)
+        {
+            local s = $(self.targets[$(i)]) ;
+            local vt = [ class.new file-target $(s:D=) : [ $(t).type ] : $(self.project) ] ;
+            $(vt).action [ class.new action $(vt) : $(t) : symlink.ln : $(property-set) ] ;
+            
+            # Place the symlink in the directory relative to the project
+            # location, instead of placing it in the build directory.
+            if [ property.select <symlink-location> : [ $(property-set).raw ] ] = <symlink-location>project-relative
+            {
+                $(vt).set-path [ path.root $(s:D) [ $(self.project).get location ] ] ;
+            }
+            
+            self.virtual-targets += $(vt) ;
+            i = [ numbers.increment $(i) ] ;
+        }
+        return $(self.virtual-targets) ;
+    }
+}
+
+# Creates a symbolic link from a set of targets to a set of sources.
+# The targets and sources map one to one. The symlinks generated are
+# limited to be the ones given as the sources. That is, the targets
+# are either padded or trimmed to equate to the sources. The padding
+# is done with the name of the corresponding source. For example::
+#
+#     symlink : one two ;
+#
+# Is equal to::
+#
+#     symlink one two : one two ;
+#
+# Names for symlink are relative to the project location. They cannot
+# include ".." path components.
+rule symlink (
+    targets *
+    : sources *
+    )
+{
+    local project = [ project.current ] ;
+    
+    return [ targets.main-target-alternative
+        [ class.new symlink-targets $(project) : $(targets) : 
+          # Note: inline targets are not supported for symlink, intentionally,
+          # since it's used to linking existing non-local targets.
+          $(sources) ] ] ;
+}
+
+rule ln
+{
+    local os ;
+    if [ modules.peek : UNIX ] { os = UNIX ; }
+    else { os ?= [ os.name ] ; }
+    # Remember the path to make the link relative to where the symlink is located.
+    local path-to-source = [ path.relative-to
+        [ path.make [ on $(<) return $(LOCATE) ] ]
+        [ path.make [ on $(>) return $(LOCATE) ] ] ] ;
+    if $(path-to-source) = .
+    {
+        PATH_TO_SOURCE on $(<) = "" ;
+    }
+    else
+    {
+        PATH_TO_SOURCE on $(<) = [ path.native $(path-to-source) ] ;
+    }
+    ln-$(os) $(<) : $(>) ;
+}
+
+actions ln-UNIX
+{
+    ln -f -s '$(>:D=:R=$(PATH_TO_SOURCE))' '$(<)'
+}
+
+# there is a way to do this; it's a dummy rule for now
+actions ln-NT
+{
+    echo "NT symlinks not supported yet"
+}
+
+IMPORT $(__name__) : symlink : : symlink ;

Added: boost-jam/boost-build/branches/upstream/current/tools/testing.jam
===================================================================
--- boost-jam/boost-build/branches/upstream/current/tools/testing.jam	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/tools/testing.jam	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,395 @@
+#  (C) Copyright David Abrahams 2002. 
+#  (C) Copyright Vladimir Prus 2002-2003. 
+#  Permission to copy, use, modify, sell and
+#  distribute this software is granted provided this copyright notice appears in
+#  all copies. This software is provided "as is" without express or implied
+#  warranty, and with no claim as to its suitability for any purpose.
+
+#  This module implements regression testing framework. It declares a number of 
+#  main target rules, which perform some action, and if the results are ok,
+#  creates an output file.
+#  
+#  The exact list of rules is:
+#  'compile'       -- creates .test file if compilation of sources was successfull
+#  'compile-fail'  -- creates .test file if compilation of sources failed
+#  'run'           -- creates .test file is running of executable produced from
+#                     sources was successfull. Also leaves behing .output file
+#                     with the output from program run.
+#  'run-fail'      -- same as above, but .test file is created if running fails.
+#
+#  In all cases, presense of .test file is an incication that
+#  the test passed. For more convenient reporting, you might want to use C++ Boost
+#  regression testing utilities, see
+#  http://www.boost.org/more/regression.html
+#
+#  For historical reason, a 'unit-test' rule is available which
+#  has the same syntax as 'exe' and behaves just like 'run'.
+
+# Things to do:
+#  - Teach compiler_status handle Jamfile.v2.
+# Notes:
+#  - <no-warn> is not implemented, since in Como-specific, and it's not clear how
+#     to implement it
+#  - std::locale-support is not impelemted (it's used in one test).
+
+  
+import targets ;
+import "class" : new ;
+import property ;
+import feature ;
+import toolset ;
+import alias ;
+import type ;
+import generators ;
+import project ;
+import property-set ;
+import virtual-target ;
+import path ;
+import os ;
+import common ;
+import sequence ;
+
+rule init ( ) { }
+
+# The feature which controls the name of program used to
+# lanch test programs. 
+feature.feature testing.launcher : : optional free ;
+feature.feature test-info : : free incidental ;
+feature.feature testing.arg : : free incidental ;
+feature.feature testing.input-file : : free dependency ;
+
+# Register target types.
+type.register TEST : test ;
+type.register COMPILE : : TEST : main ;
+type.register COMPILE_FAIL : : TEST : main ;
+type.register RUN_OUTPUT : run : : main ;
+type.register RUN : : TEST : main ;
+type.register RUN_FAIL : : TEST : main ;
+type.register UNIT_TEST : passed : TEST : main ;
+
+# Declare the rules which create main targets. 
+# While the 'type' module already creates rules with the same names for us,
+# we need extra convenience: default name of main target, so write
+# our own versions.
+
+# Helper rule. Create a test target, using basename of first source of no
+# target name is explicitly passed. Remembers the created target in
+# a global variable.
+rule make-test ( target-type : sources + : requirements * : target-name ? )
+{
+    target-name ?= $(sources[1]:D=:S=) ;
+
+    local project = [ project.current ] ;
+    # The <location-prefix> forces the build system for generate paths in the form
+    # $build_dir/array1.test/gcc/debug
+    # This is necessary to allow post-processing tools to work.
+    local t = 
+      [ targets.create-typed-target 
+          [ type.type-from-rule-name $(target-type) ] : $(project)
+            : $(target-name) : $(sources) 
+            : $(requirements) <location-prefix>$(target-name).test ] ;
+    
+    # Remember the test (for --dump-test). 
+    # A good way would be to collect all given a project.
+    # This has some technical problems: e.g. we can't call this dump from
+    # Jamfile since projects referred by 'build-project' are not available until
+    # whole Jamfile is loaded.
+    .all-tests += $(t) ;
+    return $(t) ;    
+}
+
+rule compile ( sources + : requirements * : target-name ? )
+{    
+    return [ make-test compile : $(sources) : $(requirements) : $(target-name) ] ;
+}
+
+rule compile-fail ( sources + : requirements * : target-name ? )
+{    
+    return [ make-test compile-fail : $(sources) : $(requirements) : $(target-name) ] ;
+}
+
+rule run ( sources + : args * : input-files * : requirements * : target-name ? 
+    : default-build * )
+{      
+    requirements += <testing.arg>$(args:J=" ") ;
+    requirements += <testing.input-file>$(input-files[1]) ;
+    if $(input-files[2]) || $(default-build)
+    {
+        EXIT "NOT supported" ;
+    }    
+    return [ make-test run : $(sources) : $(requirements) : $(target-name) ] ;
+}
+
+rule run-fail ( sources + : args * : input-files * : requirements * : target-name ? 
+    : default-build * )
+{    
+    requirements += <testing.arg>$(args:J=" ") ;    
+    requirements += <testing.input-file>$(input-files[1]) ;
+    if $(input-files[2]) || $(default-build)
+    {
+        EXIT "NOT supported" ;
+    }    
+    return [ make-test run-fail : $(sources) : $(requirements) : $(target-name) ] ;
+}
+
+
+# Rule for grouping tests in suites.
+rule test-suite ( suite-name : tests + ) 
+{
+    # In V2, if 'tests' are instances of 'abstract-target', they will be considered
+    # 'inline-targets' and will suffer some adjustments. This will not be compatible
+    # with V1 behaviour, so we get names of 'tests' and use them.
+    local names ;
+    for local t in $(tests)
+    {
+        names += [ $(t).name ] ;
+    }    
+    modules.call-in [ CALLER_MODULE ] : alias $(suite-name) : $(names) ;
+}
+
+# For all main target in 'project-module', 
+# which are typed target with type derived from 'TEST', 
+# produce some interesting information.
+rule dump-tests # ( project-module )
+{
+    for local t in $(.all-tests)
+    {
+        dump-test $(t) ;
+    }    
+}
+
+rule dump-test ( target )
+{
+    local type = [ $(target).type ] ;
+    local name = [ $(target).name ] ;
+    local project = [ $(target).project ] ;
+    
+    local project-root = [ $(project).get project-root ] ;
+    local project-root-location = [ $(project-root).get-location ] ;
+    
+    local sources = [ $(target).sources ] ;
+    local source-files ;
+    for local s in $(sources)
+    {
+        if [ class.is-a $(s) : file-reference ] 
+        {
+            source-files += 
+              [ path.relative 
+                  [ path.root [ $(s).location ] [ path.pwd ] ]
+                  [ path.root $(project-root-location) [ path.pwd ] ] ] ;
+        }                
+    }
+          
+    local r = [ $(t).requirements ] ;
+    # Extract values of the <test-info> feature
+    local test-info = [ $(r).get <test-info> ] ;
+    
+    # Format them into a single string of quoted strings
+    test-info = \"$(test-info:J=\"\ \")\" ;
+    
+    ECHO boost-test($(type)) \"$(name)\" 
+      [$(test-info)]            
+        ":" \"$(source-files)\"
+          ;            
+}
+
+# Register generators. Depending on target type, either
+# 'expect-success' or 'expect-failure' rule will be used.
+generators.register-standard testing.expect-success : OBJ : COMPILE ;
+generators.register-standard testing.expect-failure : OBJ : COMPILE_FAIL ;
+generators.register-standard testing.expect-success : RUN_OUTPUT : RUN ;
+generators.register-standard testing.expect-failure : RUN_OUTPUT : RUN_FAIL ;
+
+# Generator which runs an EXE and captures output.
+generators.register-standard testing.capture-output : EXE : RUN_OUTPUT ;
+
+# Generator which creates target if sources runs successfully.
+# Differers from RUN in that run output is not captured.
+# The reason why it exists is that the 'run' rule is much better for
+# automated testing, but is not user-friendly. See
+# http://article.gmane.org/gmane.comp.lib.boost.build/6353/
+generators.register-standard testing.unit-test : EXE : UNIT_TEST ;
+
+
+# The action rules called by generators.
+
+# Causes the 'target' to exist after bjam invocation if and only if all the 
+# dependencies were successfully built.
+rule expect-success ( target : dependency + : requirements * )
+{
+    **passed** $(target) : $(sources) ;    
+}
+
+# Causes the 'target' to exist after bjam invocation if and only if all some
+# of the dependencies were not successfully built.
+rule expect-failure ( target : dependency + : properties * )
+{
+    local grist = [ MATCH ^<(.*)> : $(dependency:G) ] ;
+    local marker = $(dependency:G=$(grist)*fail) ;
+    (failed-as-expected) $(marker) ;
+    FAIL_EXPECTED $(dependency) ;    
+    LOCATE on $(marker) = [ on $(dependency) return $(LOCATE) ] ;
+    RMOLD $(marker) ;
+    DEPENDS $(marker) : $(dependency) ;
+    
+    DEPENDS $(target) : $(marker) ;
+    **passed** $(target) : $(marker) ;
+}
+
+# The rule/action combination used to report successfull passing
+# of a test.
+rule **passed**
+{
+    # Dump all the tests, if needed.
+    # We do it here, since dump should happen after all Jamfiles are read,
+    # and there's no such place currently defined (but should).
+    if ! $(.dumped-tests) && --dump-tests in [ modules.peek : ARGV ] 
+    {
+        .dumped-tests = true ;
+        dump-tests ;
+    }
+                 
+    # Force deletion of the target, in case any dependencies failed
+    # to build.
+    RMOLD $(<) ;
+}
+
+actions **passed**
+{
+    echo passed > $(<)
+}
+
+actions (failed-as-expected)
+{
+    echo failed as expected > $(<)
+}
+
+rule run-path-setup ( target : source : properties * )
+{
+    # For testing, we need to make sure that all dynamic libraries needed by
+    # the test are found. So, we collect all paths from dependency libraries
+    # (via xdll-path property) and add whatever explicit dll-path user has
+    # specified. The resulting paths are added to environment on each test
+    # invocation.
+    local dll-paths = [ feature.get-values <dll-path> : $(properties) ] ;
+    dll-paths += [ feature.get-values <xdll-path> : $(properties) ] ;
+    dll-paths = [ sequence.unique $(dll-paths) ] ;
+    if $(dll-paths)
+    {    
+        dll-paths = [ sequence.transform path.native : $(dll-paths) ] ;
+        if [ modules.peek : NT ]
+        {
+            PATH_SETUP on $(target) = 
+              [ common.path-variable-setting-command PATH : $(dll-paths) %PATH% ] ;
+        }
+        else
+        {
+            PATH_SETUP on $(target) = 
+              [ common.path-variable-setting-command LD_LIBRARY_PATH :
+                  $(dll-paths) $LD_LIBRARY_PATH : exported ] ;
+        }        
+    }            
+}
+
+
+toolset.flags testing.capture-output ARGS <testing.arg> ;
+toolset.flags testing.capture-output INPUT_FILES <testing.input-file> ;
+toolset.flags testing.capture-output LAUNCHER <testing.launcher> ;
+rule capture-output ( target : source : properties * )
+{
+    output-file on $(target) = $(target:S=.output) ;
+    LOCATE on $(target:S=.output) = [ on $(target) return $(LOCATE) ] ;
+    
+    # The INCLUDES kill a warning about independent target...
+    INCLUDES $(target) : $(target:S=.output) ;
+    # but it also puts .output into dependency graph, so we must tell jam
+    # it's OK if it cannot find the target or updating rule.
+    NOCARE $(target:S=.output) ;        
+    
+    # This has two-fold effect. First it adds input files to the dependendency
+    # graph, preventing a warning. Second, it causes input files to be bound
+    # before target is created. Therefore, they are bound using SEARCH setting 
+    # on them and not LOCATE setting of $(target), as in other case (due to jam bug).
+    DEPENDS $(target) : [ on $(target) return $(INPUT_FILES) ] ;
+    
+    run-path-setup $(target) : $(source) : $(properties) ;
+}
+
+
+if [ os.name ] = NT
+{
+    STATUS = %status% ;
+    SET_STATUS = "set status=%ERRORLEVEL%" ;
+    RUN_OUTPUT_NL = "echo." ;
+    STATUS_0 = "%status% EQU 0 (" ;
+    STATUS_NOT_0 = "%status% NEQ 0 (" ;
+    VERBOSE = "%verbose% EQU 1 (" ;
+    ENDIF = ")" ;
+    SHELL_SET = "set " ;
+    
+    CATENATE = type ;
+    CP = copy ;
+}
+else
+{
+    STATUS = "$status" ;
+    SET_STATUS = "status=$?" ;
+    RUN_OUTPUT_NL = "echo" ;
+    STATUS_0 = "test $status -eq 0 ; then" ;
+    STATUS_NOT_0 = "test $status -ne 0 ; then" ;
+    VERBOSE = "test $verbose -eq 1 ; then" ;
+    ENDIF = "fi" ;
+    SHELL_SET = "" ;
+    
+    CATENATE = cat ;
+    CP = cp ;
+}
+
+if --verbose-test in [ modules.peek : ARGV ] 
+{
+    VERBOSE_TEST = 1 ;
+}
+else
+{
+    VERBOSE_TEST = 0 ;
+}
+
+actions capture-output bind INPUT_FILES output-file
+{
+    $(PATH_SETUP)
+    $(LAUNCHER) $(>) $(ARGS) "$(INPUT_FILES)" > $(output-file) 2>&1      
+    $(SET_STATUS)
+    $(RUN_OUTPUT_NL) >> $(output-file)
+    echo EXIT STATUS: $(STATUS) >> $(output-file)
+    if $(STATUS_0)
+        $(CP) $(output-file) $(<)
+    $(ENDIF)
+    $(SHELL_SET)verbose=$(VERBOSE_TEST)
+    if $(STATUS_NOT_0)
+        $(SHELL_SET)verbose=1
+    $(ENDIF)
+    if $(VERBOSE)
+        echo ====== BEGIN OUTPUT ======
+        $(CATENATE) $(output-file)
+        echo ====== END OUTPUT ======
+    $(ENDIF)
+    exit $(STATUS)      
+}
+
+MAKE_FILE = [ common.file-creation-command ] ;
+
+toolset.flags testing.unit-test LAUNCHER <testing.launcher> ;
+rule unit-test ( target : source : properties * )
+{
+    run-path-setup $(target) : $(source) : $(properties) ;
+}
+
+actions unit-test 
+{
+    $(PATH_SETUP)
+    $(LAUNCHER) $(>) && $(MAKE_FILE) $(<)
+}
+
+IMPORT $(__name__) : compile compile-fail test-suite run run-fail 
+  : : compile compile-fail test-suite run run-fail ;
+

Added: boost-jam/boost-build/branches/upstream/current/tools/unix.jam
===================================================================
--- boost-jam/boost-build/branches/upstream/current/tools/unix.jam	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/tools/unix.jam	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,224 @@
+#  Copyright (c) 2004 Vladimir Prus.
+#
+#  Use, modification and distribution is subject to the Boost Software
+#  License Version 1.0. (See accompanying file LICENSE_1_0.txt or
+#  http://www.boost.org/LICENSE_1_0.txt)
+
+#  This file implements linking semantic common to all unixes. On unix, static
+#  libraries must be specified in a fixed order on the linker command line. Generators
+#  declared there store information about the order and use it property.
+
+import feature ;
+import "class" : new ;
+import generators ;
+import type ;
+import set ;
+import order ;
+import builtin ;
+
+class unix-linking-generator : linking-generator
+{
+    import property-set ;
+    import type ;
+    import unix ;
+    
+    rule __init__ ( id 
+        composing ? : # Specify if generator is composing. The generator will be
+        # composing if non-empty string is passed, or parameter is
+        # not given. To make generator non-composing, pass empty
+        # string ("")
+        source-types + : target-types + : 
+        requirements * )
+    {
+        composing ?= true ;
+        generator.__init__ $(id) $(composing) : $(source-types) : $(target-types) :
+          $(requirements) ;
+    }
+    
+    rule run ( project name ? : property-set : sources + :  multiple ? )
+    {   
+        local result = [ linking-generator.run $(project) $(name) : $(property-set)
+          : $(sources) : $(multiple) ] ;
+        
+        unix.set-library-order $(sources) : $(property-set) : $(result) ;
+                                
+        return $(result) ;
+    }
+    
+    rule generated-targets ( sources + : property-set : project name ? )
+    {
+        local sources2 ;
+        local libraries ;
+        for local l in $(sources)
+        {
+            if [ type.is-derived [ $(l).type ] LIB ]
+            {
+                libraries += $(l) ;
+            }
+            else
+            {
+                sources2 += $(l) ;
+            }            
+        }
+        
+        sources = $(sources2) [ unix.order-libraries $(libraries) ] ;
+        
+        return [ linking-generator.generated-targets $(sources) : $(property-set)
+          : $(project) $(name) ] ;
+    }
+    
+} 
+
+class unix-archive-generator : generator
+{
+    import unix ; 
+
+    rule __init__ ( id composing ? : source-types + : target-types + : 
+        requirements * )
+    {
+        composing ?= true ;
+        generator.__init__ $(id) $(composing) : $(source-types) : $(target-types) :
+          $(requirements) ;
+    }
+        
+    rule run ( project name ? : property-set : sources + :  multiple ? )
+    {                                
+        local result = [ generator.run $(project) $(name) : $(property-set)
+          : $(sources) : $(multiple) ] ;
+        
+        unix.set-library-order $(sources) : $(property-set) : $(result) ;
+        
+        return $(result) ;
+
+    }    
+}
+
+class unix-searched-lib-generator : searched-lib-generator
+{
+    import unix ;
+    rule __init__ ( * : * )
+    { 
+        generator.__init__ 
+          $(1) : $(2) : $(3) : $(4) : $(5) : $(6) : $(7) : $(8) : $(9) ;
+    }
+    
+    rule optional-properties ( )
+    {
+        return $(self.requirements) ;
+    }
+              
+    rule run ( project name ? : property-set : sources * : multiple ? )
+    {
+        local result = [ searched-lib-generator.run $(project) $(name) 
+          : $(property-set) : $(sources) : $(multiple) ] ;
+        
+        unix.set-library-order $(sources) : $(property-set) : $(result) ;
+        
+        return $(result) ;
+    }    
+}
+
+class unix-prebuilt-lib-generator : generator
+{
+    import unix ;
+    rule __init__ ( * : * )
+    {
+        generator.__init__ $(1) : $(2) : $(3) : $(4) : $(5) : $(6) : $(7) : $(8) : $(9) ;
+    }
+
+    rule run ( project name ? : property-set : sources * : multiple ? )
+    {
+        local f = [ $(property-set).get <file> ] ;
+        unix.set-library-order-aux $(f) : $(sources) ;
+        return $(f) $(sources) ;
+    }    
+}
+
+generators.register 
+  [ new unix-prebuilt-lib-generator unix.prebuilt : : LIB 
+      : <file> <toolset>unix ] ;
+
+
+
+
+# Declare generators
+generators.register [ new unix-linking-generator unix.link : LIB OBJ : EXE 
+    : <toolset>unix ] ;
+
+generators.register [ new unix-archive-generator unix.archive : OBJ : STATIC_LIB 
+    : <toolset>unix ] ;
+
+generators.register [ new unix-linking-generator unix.link.dll : LIB OBJ : SHARED_LIB 
+    : <toolset>unix ] ;
+
+generators.register [ new unix-searched-lib-generator 
+   unix.searched-lib-generator : : SEARCHED_LIB : <toolset>unix ] ;
+
+
+# The derived toolset must specify their own actions.
+actions link {
+}
+
+actions link.dll {
+}
+
+actions archive {    
+}
+
+actions searched-lib-generator {    
+}
+
+actions prebuilt {
+}
+
+    
+
+
+
+.order = [ new order ] ;
+
+rule set-library-order-aux ( from * : to * )
+{
+    for local f in $(from)
+    {
+        for local t in $(to)
+        {            
+            if $(f) != $(t)
+            {                
+                $(.order).add-pair $(f) $(t) ;
+            }            
+        }        
+    }    
+}
+
+rule set-library-order ( sources * : property-set : result * )
+{
+    local used-libraries ;
+    local deps = [ $(property-set).dependency ] ;
+    for local l in $(sources) $(deps:G=)        
+    {
+        if [ $(l).type ] && [ type.is-derived [ $(l).type ] LIB ]
+        {
+            used-libraries += $(l) ;
+        }
+    }
+
+    local created-libraries ;
+    for local l in $(result)
+    {
+        if [ $(l).type ] && [ type.is-derived [ $(l).type ] LIB ] 
+        {
+            created-libraries += $(l) ;
+        }            
+    }
+    
+    created-libraries = [ set.difference $(created-libraries) : $(used-libraries) ] ;
+    set-library-order-aux $(created-libraries) : $(used-libraries) ;
+}
+
+rule order-libraries ( libraries * )
+{
+    local r = [ $(.order).order $(libraries) ] ;
+    return $(r) ;
+}
+     
\ No newline at end of file

Added: boost-jam/boost-build/branches/upstream/current/tools/vacpp.jam
===================================================================
--- boost-jam/boost-build/branches/upstream/current/tools/vacpp.jam	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/tools/vacpp.jam	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,108 @@
+# Copyright Vladimir Prus 2004.
+# Copyright Toon Knapen 2004.
+# Distributed under the Boost Software License, Version 1.0.
+# (See accompanying file LICENSE_1_0.txt
+# or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#
+# Boost.Build V2 toolset for the IBM VisualAge compiler
+#
+
+import toolset : flags ;
+import feature ;
+
+feature.extend toolset : vacpp ;
+toolset.inherit vacpp : unix ;
+feature.subfeature toolset vacpp : version ;
+
+# Configures the vacpp toolset. 
+rule init ( version ? : command * : options * )
+{
+    local condition = [ common.check-init-parameters vacpp : version $(version) ] ;
+    local command = [ common.get-invocation-command vacpp : xlc : $(command) ] ;
+
+    common.handle-options acc : $(condition) : $(command) : $(options) ;    
+    
+    if $(command)
+    {        
+        command = [ common.get-absolute-tool-path $(command[-1]) ] ;
+    }
+    local root = $(command:D) ;
+    
+    flags vacpp ROOT $(condition) : $(root) ;    
+}
+
+
+# Declare generators
+generators.register-c-compiler vacpp.compile.c : C : OBJ : <toolset>vacpp ;
+generators.register-c-compiler vacpp.compile.c++ : CPP : OBJ : <toolset>vacpp ;
+
+# Declare flags.
+flags vacpp CFLAGS <optimization>off : -qNOOPTimize ;
+flags vacpp CFLAGS <optimization>speed : -O3 -qstrict ;
+flags vacpp CFLAGS <optimization>space : -O2 -qcompact ;
+
+flags vacpp CFLAGS <inlining>off : -qnoinline ;
+flags vacpp CFLAGS <inlining>on : -qinline ;
+flags vacpp CFLAGS <inlining>full : -qinline ;
+
+flags vacpp C++FLAGS <exception-handling>off : -qnoeh ;
+flags vacpp C++FLAGS <exception-handling>on : -qeh ;
+
+flags vacpp C++FLAGS <rtti>off : -qnortti ;
+flags vacpp C++FLAGS <rtti>on : -qrtti ;
+
+# flags vacpp LINKFLAGS <link-runtime>static : -llibstd_v2.a ;
+# flags vacpp LINKFLAGS <link-runtime>shared : -llibstd_v2.sl ;
+
+# We want the full path to the sources in the debug symbols because otherwise
+# the debugger won't find the sources when we use boost.build.
+flags vacpp CFLAGS <debug-symbols>on : -g ;
+flags vacpp LINKFLAGS <debug-symbols>on : -g ;
+flags vacpp LINKFLAGS <debug-symbols>off : -s ;
+
+# V2 does not have <shared-linkable>, not sure what this meant in V1.
+#flags vacpp CFLAGS <shared-linkable>true : +Z ;
+
+flags vacpp CFLAGS <profiling>on : -pg ;
+flags vacpp LINKFLAGS <profiling>on : -pg ;
+
+flags vacpp CFLAGS <cflags> ;
+flags vacpp C++FLAGS <cxxflags> ;
+flags vacpp DEFINES <define> ;
+flags vacpp UNDEFS <undef> ;
+flags vacpp HDRS <include> ;
+flags vacpp STDHDRS <sysinclude> ;
+flags vacpp LINKFLAGS <linkflags> ;
+flags vacpp ARFLAGS <arflags> ;
+
+flags vacpp LIBPATH <library-path> ;
+flags vacpp NEEDLIBS <library-file> ;
+flags vacpp FINDLIBS <find-shared-library> ;
+flags vacpp FINDLIBS <find-static-library> ;
+
+# Select the compiler name according to the threading model.
+flags vacpp VA_C_COMPILER  <threading>single : xlc   ;
+flags vacpp VA_C_COMPILER  <threading>multi : xlc_r ;
+flags vacpp VA_CXX_COMPILER <threading>single : xlC   ;
+flags vacpp VA_CXX_COMPILER <threading>multi : xlC_r ;
+
+actions vacpp.link bind NEEDLIBS
+{
+    $(ROOT)/$(VA_CXX_COMPILER) $(LINKFLAGS) -o "$(<[1])" -L$(LIBPATH) -L$(STDLIBPATH) "$(>)" "$(NEEDLIBS)" "$(NEEDLIBS)" -l$(FINDLIBS)
+}
+
+actions vacpp.compile.c
+{    
+    $(ROOT)/$(VA_C_COMPILER) -c -I$(BOOST_ROOT) -U$(UNDEFS) -D$(DEFINES) $(CFLAGS) -I"$(HDRS)" -I"$(STDHDRS)" -o "$(<)" "$(>)"
+}
+
+actions vacpp.compile.c++
+{
+    $(ROOT)/$(VA_CXX_COMPILER) -c -I$(BOOST_ROOT) -U$(UNDEFS) -D$(DEFINES) $(CFLAGS) $(C++FLAGS) -I"$(HDRS)" -I"$(STDHDRS)" -o "$(<)" "$(>)"
+}
+
+actions updated together piecemeal vacpp.archive
+{
+    ar ru$(ARFLAGS:E="") "$(<)" "$(>)"
+}

Added: boost-jam/boost-build/branches/upstream/current/tools/xsltproc.jam
===================================================================
--- boost-jam/boost-build/branches/upstream/current/tools/xsltproc.jam	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/tools/xsltproc.jam	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,87 @@
+#  Copyright (C) 2003 Doug Gregor. Permission to copy, use, modify,
+#  sell and distribute this software is granted provided this
+#  copyright notice appears in all copies. This software is provided
+#  "as is" without express or implied warranty, and with no claim as
+#  to its suitability for any purpose.
+
+#  This module defines rules to apply an XSLT stylesheet to an XML file 
+#  using the xsltproc driver, part of libxslt.
+#
+#  Note: except for 'init', this modules does not provide any rules
+#  for end users. 
+
+import feature ;
+import regex ;
+import common ;
+
+feature.feature xsl:param : : free ;
+feature.feature xsl:path : : free ;
+
+# Initialize xsltproc support. The parameters are:
+#   xsltproc: The xsltproc executable
+rule init ( xsltproc ? )
+{
+  if ! $(xsltproc)
+  {
+    xsltproc = [ modules.peek : XSLTPROC ] ;
+  }
+
+  if ! $(.initialized) 
+  {
+    $(.initialized) = true ;
+    .xsltproc = $(xsltproc) ;
+  }
+}
+
+rule compute-xslt-flags ( target : properties * )
+{
+  local flags ;
+  # Translate <xsl:param> into command line flags.  
+  for local param in [ feature.get-values <xsl:param> : $(properties) ]
+  {
+    local namevalue = [ regex.split $(param) "=" ] ;
+    flags += --stringparam $(namevalue[1]) $(namevalue[2]) ;
+  }
+  # Translate <xsl:path>
+  for local path in [ feature.get-values <xsl:path> : $(properties) ] 
+  {
+    flags += --path $(path:G=) ;
+  }
+        
+  return $(flags) ;
+}
+
+
+rule xslt ( target : source stylesheet : properties * )
+{ 
+  STYLESHEET on $(target) = $(stylesheet) ;
+  FLAGS on $(target) = [ compute-xslt-flags $(target) : $(properties) ] ;
+  NAME on $(target) = $(.xsltproc) ;
+    
+  CATALOG = [ common.variable-setting-command "XML_CATALOG_FILES" "catalog.xml" ] ;  
+  xslt-xsltproc $(target) : $(source) ;
+}
+
+rule xslt-dir ( target : source stylesheet : properties * : dirname )
+{   
+  STYLESHEET on $(target) = $(stylesheet) ;
+  FLAGS on $(target) = [ compute-xslt-flags $(target) : $(properties) ] ;
+  DIRECTORY on $(target) = $(dirname) ;
+  NAME on $(target) = $(.xsltproc) ;
+  CATALOG = [ common.variable-setting-command "XML_CATALOG_FILES" "catalog.xml" ] ;      
+  xslt-xsltproc-dir $(target) : $(source) ;
+}
+
+
+actions xslt-xsltproc
+{
+  $(CATALOG) "$(NAME:E=xsltproc)" $(FLAGS) --xinclude -o "$(<)" "$(STYLESHEET)" "$(>)"
+}
+
+actions xslt-xsltproc-dir
+{
+  $(CATALOG) "$(NAME:E=xsltproc)" $(FLAGS) --xinclude -o "$(DIRECTORY)/" "$(STYLESHEET)" "$(>)"
+}
+
+IMPORT $(__name__) : xslt : : xslt ;
+IMPORT $(__name__) : xslt-dir : : xslt-dir ;

Added: boost-jam/boost-build/branches/upstream/current/user-config.jam
===================================================================
--- boost-jam/boost-build/branches/upstream/current/user-config.jam	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/user-config.jam	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,68 @@
+#  Copyright (C) Vladimir Prus 2003. Permission to copy, use, modify, sell and
+#  distribute this software is granted provided this copyright notice appears in
+#  all copies. This software is provided "as is" without express or implied
+#  warranty, and with no claim as to its suitability for any purpose.
+
+#  This file is used to configure your Boost.Build installation. Please read
+#  the user manual to find out where to put it.
+
+#  Toolset declarations are most important in this file. The tell Boost.Build
+#  what compilers are available and where to look for them. The first toolset
+#  will become "default" one.
+#  Some important libraries can also be configured.
+#  Uncomment relevant parts to suite your local configuration and preferences.
+
+import toolset : using ;
+
+#  GCC configuration
+
+#  Configure gcc (default version)
+#  using gcc ;
+
+#  Configure specific gcc version, giving alternative name to use
+#  using gcc : 3.2 g++-3.2 ;
+
+#  MSVC configuration
+
+#  Configure msvc (default version, searched in standard location
+#  and PATH).
+#  using msvc ;
+
+#  Borland configuration
+#  using borland ;
+
+
+#  STLPort configuration
+
+#  Configure, specifying location of STLPort headers. 
+#  Libraries must be either not needed, or available to
+#  the compiler by default
+#  using stlport : : /usr/include/stlport ;
+
+#  Configure, specifying locatioh of both headers and libraries
+#  using stlport : : /usr/include/stlport : /usr/lib ;
+
+
+#  QT configuration
+
+#  Configure, assuming QTDIR gives the installation prefix
+#  using qt ;
+
+#  Configure with explicit installation prefix
+#  using qt : /usr/opt/qt ;
+
+#  xsltproc (from libxslt) configuration
+#  using xsltproc ;
+
+#  BoostBook configuration. Please see BoostBook for documentation
+#  on this.
+#  using boostbook ;
+#  using boostbook : /home/gregod/Projects/share/docbook-xsl-1.60.1/ 
+#                  : /home/gregod/Projects/share/docbook-dtd-4.2/
+#                  ;
+
+
+
+  
+ 
+

Added: boost-jam/boost-build/branches/upstream/current/util/assert.jam
===================================================================
--- boost-jam/boost-build/branches/upstream/current/util/assert.jam	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/util/assert.jam	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,112 @@
+#  (C) Copyright David Abrahams 2001. Permission to copy, use, modify, sell and
+#  distribute this software is granted provided this copyright notice appears in
+#  all copies. This software is provided "as is" without express or implied
+#  warranty, and with no claim as to its suitability for any purpose.
+
+import errors : error-skip-frames lol->list ;
+import modules ;
+
+# assert the equality of A and B 
+rule equal ( a * : b * )
+{
+    if $(a) != $(b)
+    {
+        error-skip-frames 3 assertion failure: \"$(a)\" "!=" \"$(b)\" ;
+    }
+}
+
+# assert that EXPECTED is the result of calling RULE-NAME with the
+# given arguments
+rule result ( expected * : rule-name args * : * )
+{
+    local result ;
+    module [ CALLER_MODULE ]
+    {
+        modules.poke assert : result
+            : [ $(2) : $(3) : $(4) : $(5) : $(6) : $(7) : $(8) : $(9) ] ;
+    }
+
+    if $(result) != $(expected)
+    {
+        error-skip-frames 3 assertion failure: "[" $(rule-name) 
+          [ lol->list $(args) : $(3) : $(4) : $(5) : $(6) : $(7) : $(8) : $(9) ]
+            "]"
+          : expected: \"$(expected)\"
+          : got: \"$(result)\" ;
+    }
+}
+
+# assert that the given variable is nonempty.
+rule nonempty-variable ( name )
+{
+    local value = [ modules.peek [ CALLER_MODULE ] : $(name) ] ;
+
+    if ! $(value)-is-nonempty
+    {
+        error-skip-frames 3 assertion failure: expecting non-empty variable $(variable) ;
+    }
+}
+
+# assert that the result of calling RULE-NAME on the given arguments
+# has a true logical value (is neither an empty list nor all empty
+# strings).
+rule true ( rule-name args * : * )
+{
+    local result ;
+    module [ CALLER_MODULE ]
+    {
+        modules.poke assert : result
+          : [ $(1) : $(2) $(3) : $(4)
+            : $(5) : $(6) : $(7) : $(8) : $(9) ] ;
+    }
+
+    if ! $(result)
+    {
+        error-skip-frames 3 assertion failure: expecting true result from
+          "[" $(rule-name) 
+          [ lol->list $(args) : $(2) : $(3) : $(4) : $(5) : $(6) : $(7) : $(8) : $(9) ]
+            "]" ;
+    }
+}
+
+# assert that the result of calling RULE-NAME on the given arguments
+# has a false logical value (is either an empty list or all empty
+# strings).
+rule false ( rule-name args * : * )
+{
+    local result ;
+    module [ CALLER_MODULE ]
+    {
+        modules.poke assert : result
+          : [ $(1) : $(2) $(3) : $(4)
+            : $(5) : $(6) : $(7) : $(8) : $(9) ] ;
+    }
+
+    if $(result)
+    {
+        error-skip-frames 3 assertion failure: expecting false result from
+          "[" $(rule-name) 
+          [ lol->list $(args) : $(2) : $(3) : $(4) : $(5) : $(6) : $(7) : $(8) : $(9) ]
+            "]" : got [ lol->list $(result) ] instead  ;
+    }
+}
+
+# assert that 'element' is present in 'list'.
+rule "in" ( element : list * )
+{
+    if ! $(element) in $(list)
+    {
+        error-skip-frames 3 assertion failure: expecting $(element) in 
+                          "[" $(list) "]" ;
+    }
+}
+
+# assert that 'element' is not present in 'list'.
+rule not-in ( element : list * )
+{
+    if $(element) in $(list)
+    {
+        error-skip-frames 3 assertion failure: did not expect $(element) in 
+                          "[" $(list) "]" ;
+    }
+}
\ No newline at end of file

Added: boost-jam/boost-build/branches/upstream/current/util/container.jam
===================================================================
--- boost-jam/boost-build/branches/upstream/current/util/container.jam	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/util/container.jam	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,312 @@
+# (C) Copyright Rene Rivera, 2002.
+#
+# See accompanying license for terms and conditions of use.
+#
+
+# Various container classes.
+
+import "class" : * ;
+
+# Base for container objects. This lets us construct recursive structures.
+# That is containers with containers in them, specifically so we can tell
+# literal values from node values.
+#
+class node 
+{
+    rule __init__ (
+      value ? # Optional value to set node to initially.
+    )
+    {
+        self.value = $(value) ;
+    }
+        
+    # Set the value of this node, passing nothing will clear it.
+    #
+    rule set ( value ? )
+    {
+        self.value = $(value) ;
+    }
+    
+    # Get the value of this node.
+    #
+    rule get ( )
+    {
+        return $(self.value) ;
+    }
+}
+
+
+# A simple vector. Interface mimics the C++ std::vector and std::list,
+# with the exception that indices are one (1) based to follow Jam standard.
+#
+# TODO: Possibly add assertion checks.
+#
+class vector : node 
+{
+    import numbers : range ;
+    import utility ;
+    import sequence ;
+        
+    rule __init__ (
+      values * # Initial contents of vector.
+    )
+    {
+        node.__init__ ;
+        self.value = $(values) ;
+    }    
+    
+    # Get the value of the first element.
+    #
+    rule front ( )
+    {
+        return $(self.value[1]) ;
+    }
+    
+    # Get the value of the last element.
+    #
+    rule back ( )
+    {
+        return $(self.value[-1]) ;
+    }
+    
+    # Get the value of the element at the given index, one based.
+    # Access to elements of recursive structures is supported directly.
+    # Specifying additional index values recursively accesses the elements as
+    # containers. For example: [ $(v).at 1 : 2 ] would retrieve the second element
+    # of our first element. This assuming the first element is a container.
+    #
+    rule at (
+        index # The element index, one based.
+        : * # Additional indices to access recursively.
+        )
+    {
+        local r = $(self.value[$(index)]) ;
+        if $(2)
+        {
+            r = [ $(r).at $(2) : $(3) : $(4) : $(5) : $(6) : $(7) : $(8) : $(9) ] ;
+        }
+        return $(r) ;
+    }
+    
+    # Get the value contained in the given element. This has the same
+    # functionality and interface as "at" but in addition gets the value
+    # of the referenced element, assuming it's a "node".
+    #
+    rule get-at (
+        index # The element index, one based.
+        : * # Additional indices to access recursively.
+        )
+    {
+        local r = $(self.value[$(index)]) ;
+        if $(2)
+        {
+            r = [ $(r).at $(2) : $(3) : $(4) : $(5) : $(6) : $(7) : $(8) : $(9) ] ;
+        }
+        return [ $(r).get ] ;
+    }
+    
+    # Insert the given value into the front of the vector pushing the
+    # rest of the elements back.
+    #
+    rule push-front (
+        value # Value to become first element.
+        )
+    {
+        self.value = $(value) $(self.value) ;
+    }
+    
+    # Remove the front element from the vector. Does not return the value.
+    # No effect if vector is empty.
+    #
+    rule pop-front ( )
+    {
+        self.value = $(self.value[2-]) ;
+    }
+    
+    # Add the given value at the end of the vector.
+    #
+    rule push-back (
+        value # Value to become back element.
+        )
+    {
+        self.value += $(value) ;
+    }
+    
+    # Remove the back element from the vector. Does not return the value.
+    # No effect if vector is empty.
+    #
+    rule pop-back ( )
+    {
+        self.value = $(self.value[1--2]) ;
+    }
+    
+    # Insert the given value at the given index, one based. The values
+    # at and to the right of the of the index are push back to make room
+    # for the new value.
+    #
+    rule insert (
+        index # The index to insert at, one based.
+        : value # The value to insert.
+        )
+    {
+        local left = $(self.value[1-$(index)]) ;
+        left = $(left[1--2]) ;
+        local right = $(self.value[$(index)-]) ;
+        self.value = $(left) $(value) $(right) ;
+    }
+    
+    # Remove one or more elements from the vector. The range is inclusive,
+    # and not specifying an end is equivalent to the [start,start] range.
+    #
+    rule erase (
+        start # Index of first element ro remove.
+        end ? # Optional, index of last element to remove.
+        )
+    {
+        end ?= $(start) ;
+        local left = $(self.value[1-$(start)]) ;
+        left = $(left[1--2]) ;
+        local right = $(self.value[$(end)-]) ;
+        right = $(right[2-]) ;
+        self.value = $(left) $(right) ;
+    }
+    
+    # Remove all elements from the vector.
+    #
+    rule clear ( )
+    {
+        self.value = ;
+    }
+    
+    # The number of elements in the vector.
+    #
+    rule size ( )
+    {
+        return [ sequence.length $(self.value) ] ;
+    }
+    
+    # Returns "true" if there are NO elements in the vector, empty
+    # otherwise.
+    #
+    rule empty ( )
+    {
+        if ! $(self.value)
+        {
+            return true ;
+        }
+    }
+
+    # Returns the list of all valid indices for this vector.
+    rule indices ( )
+    {
+        if ! [ empty ] 
+        {
+            local size = [ size ] ;
+            return [ range 1 : $(size) ] $(size) ;
+        }      
+    }
+
+    # Returns the textual representation of content.
+    rule str ( )
+    {
+        return "[" [ sequence.transform utility.str : $(self.value) ] "]" ;
+    }
+
+    # Sorts the vector inplace, calling 'utility.less' for
+    # comparisons.
+    rule sort ( )
+    {
+        self.value = 
+            [ sequence.insertion-sort $(self.value) : utility.less ] ;
+    }
+
+    # Returns true if content is equal to the content of other vector.
+    # Uses 'utility.equal' for comparison.
+    rule equal ( another )
+    {        
+        local mismatch ;
+        if [ size ] = [ $(another).size ]
+        {
+            for local i in [ indices ]
+            {
+                if ! [ utility.equal [ at $(i) ] [ $(another).at $(i) ] ]
+                {
+                    mismatch = true ;
+                }
+            }
+        } 
+        else
+        {
+            mismatch = true ;
+        }
+                        
+        if ! $(mismatch) 
+        {
+            return true ;
+        }
+    }
+}
+
+local rule __test__ ( )
+{
+    import assert ;
+    import "class" : new ;
+    
+    local l = [ new vector ] ;
+    assert.result 0 : $(l).size ;
+    assert.result : $(l).indices ;
+    assert.result "[" "]" : $(l).str ;
+    $(l).push-back b ;
+    $(l).push-front a ;
+    assert.result 1 2 : $(l).indices ;
+    assert.result "[" a b "]" : $(l).str ;
+    assert.result a : $(l).front ;
+    assert.result b : $(l).back ;
+    $(l).insert 2 : d ;
+    $(l).insert 2 : c ;
+    $(l).insert 4 : f ;
+    $(l).insert 4 : e ;
+    $(l).pop-back ;
+    assert.result 5 : $(l).size ;
+    assert.result d : $(l).at 3 ;
+    $(l).pop-front ;
+    assert.result c : $(l).front ;
+    assert.false $(l).empty ;
+    $(l).erase 3 4 ;
+    assert.result 2 : $(l).size ;
+    
+    local l2 = [ new vector q w e r t y ] ;
+    assert.result 6 : $(l2).size ;
+    $(l).push-back $(l2) ;
+    assert.result 3 : $(l).size ;
+    local l2-alias = [ $(l).back ] ;
+    assert.result e : $(l2-alias).at 3 ;
+    $(l).clear ;
+    assert.true $(l).empty ;
+    assert.false $(l2-alias).empty ;
+    $(l2).pop-back ;
+    assert.result t : $(l2-alias).back ;
+    
+    local l3 = [ new vector ] ;
+    $(l3).push-back [ new vector 1 2 3 4 5 ] ;
+    $(l3).push-back [ new vector a b c ] ;
+    assert.result "[" "[" 1 2 3 4 5 "]" "[" a b c "]" "]" : $(l3).str ;
+    $(l3).push-back [ new vector [ new vector x y z ] [ new vector 7 8 9 ] ] ;
+    assert.result 1 : $(l3).at 1 : 1 ;
+    assert.result b : $(l3).at 2 : 2 ;
+    assert.result a b c : $(l3).get-at 2 ;
+    assert.result 7 8 9 : $(l3).get-at 3 : 2 ;
+
+    local l4 = [ new vector 4 3 6 ] ;
+    $(l4).sort ;
+    assert.result 3 4 6 : $(l4).get ;
+
+    assert.false $(l4).equal $(l3) ;
+    local l5 = [ new vector 3 4 6 ] ;
+    assert.true $(l4).equal $(l5) ;
+    # Check that vectors of different sizes are considered non-equal
+    $(l5).pop-back ;    
+    assert.false $(l4).equal $(l5) ;
+    local l6 = [ new vector [ new vector 1 2 3 ] ] ;
+    assert.true $(l6).equal [ new vector [ new vector 1 2 3 ] ] ;
+}

Added: boost-jam/boost-build/branches/upstream/current/util/doc.jam
===================================================================
--- boost-jam/boost-build/branches/upstream/current/util/doc.jam	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/util/doc.jam	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,903 @@
+# (C) Copyright Rene Rivera, 2002-2003.
+#
+# See accompanying license for terms and conditions of use.
+#
+
+# Documentation system, handles --help requests.
+# It defines rules that attach documentation to modules, rules, and variables.
+# Collects and generates documentation for the various parts of the build system.
+# The documentation is collected from comments integrated into the code.
+
+import modules ;
+import print ;
+import set ;
+import container ;
+import "class" ;
+import sequence ;
+
+# The type of output to generate.
+# "console" is formated text echoed to the console (the default);
+# "text" is formated text appended to the output file;
+# "html" is HTLM output to the file.
+#
+help-output = console ;
+
+# The file to output documentation to when generating "text" or "html"
+# help. This is without extension as the extension is determined by the
+# type of output.
+#
+help-output-file = help ;
+
+# Whether to include local rules in help output.
+#
+.option.show-locals ?= ;
+
+# When showing documentation for a module, whether to also generate
+# automatically the detailed docs for each item in the module.
+#
+.option.detailed ?= ;
+
+# Generate debug output as the help is generated and modules
+# are parsed.
+#
+.option.debug ?= ;
+
+# Enable or disable a documentation option.
+#
+local rule set-option (
+    option # The option name.
+    : value ? # Enabled (non-empty), or disabled (empty)
+    )
+{
+    .option.$(option) = $(value) ;
+}
+
+# Set the type of output.
+#
+local rule set-output (
+    type
+    )
+{
+    help-output = $(type) ;
+}
+
+# Set the output to a file.
+#
+local rule set-output-file (
+    file
+    )
+{
+    help-output-file = $(file) ;
+}
+
+# Extracts the brief comment from a complete comment. The brief
+# comment is the first sentence.
+#
+local rule brief-comment (
+    docs * # The comment documentation.
+    )
+{
+    local d = $(docs:J=" ") ;
+    local p = [ MATCH ".*([.])$" : $(d) ] ;
+    if ! $(p) { d = $(d)"." ; }
+    d = $(d)" " ;
+    local m = [ MATCH "^([^.]+[.])(.*)" : $(d) ] ;
+    local brief = $(m[1]) ;
+    while $(m[2]) && [ MATCH "^([^ ])" : $(m[2]) ]
+    {
+        m = [ MATCH "^([^.]+[.])(.*)" : $(m[2]) ] ;
+        brief += $(m[1]) ;
+    }
+    return $(brief:J="") ;
+}
+
+# Specifies the documentation for the current module.
+#
+local rule set-module-doc (
+    module-name ? # The name of the module to document.
+    : docs * # The documentation for the module.
+    )
+{
+    module-name ?= * ;
+
+    $(module-name).brief = [ brief-comment $(docs) ] ;
+    $(module-name).docs = $(docs) ;
+
+    if ! $(module-name) in $(documented-modules)
+    {
+        documented-modules += $(module-name) ;
+    }
+}
+
+# Specifies the documentation for the current module.
+#
+local rule set-module-copyright (
+    module-name ? # The name of the module to document.
+    : copyright * # The copyright for the module.
+    )
+{
+    module-name ?= * ;
+
+    $(module-name).copy-brief = [ brief-comment $(copyright) ] ;
+    $(module-name).copy-docs = $(docs) ;
+
+    if ! $(module-name) in $(documented-modules)
+    {
+        documented-modules += $(module-name) ;
+    }
+}
+
+# Specifies the documentation for a rule in the current module.
+# If called in the global module, this documents a global rule.
+#
+local rule set-rule-doc (
+    name # The name of the rule.
+    module-name ? # The name of the module to document.
+    is-local ? # Whether the rule is local to the module.
+    : docs * # The documentation for the rule.
+    )
+{
+    module-name ?= * ;
+
+    $(module-name).$(name).brief = [ brief-comment $(docs) ] ;
+    $(module-name).$(name).docs = $(docs) ;
+    $(module-name).$(name).is-local = $(is-local) ;
+
+    if ! $(name) in $($(module-name).rules)
+    {
+        $(module-name).rules += $(name) ;
+    }
+}
+
+# Specify a class, will turn a rule into a class.
+#
+local rule set-class-doc (
+    name # The name of the class.
+    module-name ? # The name of the module to document.
+    : super-name ? # The super class name.
+    )
+{
+    module-name ?= * ;
+
+    $(module-name).$(name).is-class = true ;
+    $(module-name).$(name).super-name = $(super-name) ;
+    $(module-name).$(name).class-rules =
+        [ MATCH "^($(name)[.].*)" : $($(module-name).rules) ] ;
+    $(module-name).$($(module-name).$(name).class-rules).is-class-rule = true ;
+
+    $(module-name).classes += $(name) ;
+    $(module-name).class-rules += $($(module-name).$(name).class-rules) ;
+    $(module-name).rules =
+        [ set.difference $($(module-name).rules) :
+            $(name) $($(module-name).$(name).class-rules) ] ;
+}
+
+# Set the argument call signature of a rule.
+#
+local rule set-rule-arguments-signature (
+    name # The name of the rule.
+    module-name ? # The name of the module to document.
+    : signature * # The arguments signature.
+    )
+{
+    module-name ?= * ;
+
+    $(module-name).$(name).signature = $(signature) ;
+}
+
+# Specifies the documentation for an argument of a rule.
+#
+local rule set-argument-doc (
+    name # The name of the argument.
+    qualifier # Argument syntax qualifier, "*", "+", etc.
+    rule-name # The name of the rule.
+    module-name ? # THe optional name of the module.
+    : docs * # The documentation.
+    )
+{
+    module-name ?= * ;
+
+    $(module-name).$(rule-name).args.$(name).qualifier = $(qualifier) ;
+    $(module-name).$(rule-name).args.$(name).docs = $(docs) ;
+
+    if ! $(name) in $($(module-name).$(rule-name).args)
+    {
+        $(module-name).$(rule-name).args += $(name) ;
+    }
+}
+
+# Specifies the documentation for a variable in the current module.
+# If called in the global module, the global variable is documented.
+#
+local rule set-variable-doc (
+    name # The name of the variable.
+    default # The default value.
+    initial # The initial value.
+    module-name ? # The name of the module to document.
+    : docs * # The documentation for the variable.
+    )
+{
+    module-name ?= * ;
+
+    $(module-name).$(name).brief = [ brief-comment $(docs) ] ;
+    $(module-name).$(name).default = $(default) ;
+    $(module-name).$(name).initial = $(initial) ;
+    $(module-name).$(name).docs = $(docs) ;
+
+    if ! $(name) in $($(module-name).variables)
+    {
+        $(module-name).variables += $(name) ;
+    }
+}
+
+# Generates a general description of the documentation and help system.
+#
+local rule print-help-top ( )
+{
+    print.section "Available Help"
+        These are the available options for obtaining documentation.
+        Some options have additional instructions on how to get more
+        detailed information. Multiple options are allowed and
+        sometimes required. For example, the options that configure
+        the help system still require a regular help request option
+        for any output to be generated.
+        ;
+    print.list-start ;
+    print.list-item --help; This help message. ;
+    print.list-item --help-usage; How to invoke '"bjam".' ;
+    print.list-item --help-all; Brief information on available modules. ;
+    print.list-item --help <module-name>; Get information about a module. ;
+    print.list-item --help-options; Options for controlling the help display. ;
+    print.list-item --help-output <type>; The type of output to genetare.
+        '"console" is formated text echoed to the console (the default);'
+        '"text" is formated text appended to the output file;'
+        '"html" is HTLM output to the file.' ;
+    print.list-item --help-output-file <file>; The file to output the documentation. ;
+    print.list-end ;
+}
+
+# Generate Jam/Boost.Jam command usage information.
+#
+local rule print-help-usage ( )
+{
+    print.section "Boost.Jam Usage"
+        "bjam [ options... ] targets..."
+        ;
+    print.list-start ;
+    print.list-item -a;
+        Build all targets, even if they are current. ;
+    print.list-item -fx;
+        Read '"x"' as the Jamfile for building instead of searching
+        for the Boost.Build system. ;
+    print.list-item -jx;
+        Run up to '"x"' commands concurrently. ;
+    print.list-item -n;
+        Do not execute build commands. Instead print out the commands
+        as they would be executed if building. ;
+    print.list-item -ox;
+        Write the build commands to the file '"x"'. ;
+    print.list-item -q;
+        Quit as soon as the build of a target fails. Specifying this prevents the
+        attempt of building as many targets as possible regardless of failures. ;
+    print.list-item -sx=y;
+        Sets a Jam variable '"x"' to the value '"y"', overriding any value that
+        variable would have from the environment. ;
+    print.list-item -tx;
+        Rebuild the target '"x"', even if it is up-to-date. ;
+    print.list-item -v;
+        Display the version of bjam. ;
+    print.list-item --x;
+        Option '"x"' is ignored but considered and option. The option is then
+        available from the '"ARGV"' variable. ;
+    print.list-item -dn;
+        Enables output of diagnostic messages. The debug level '"n"' and all
+        below it are enabled by this option. ;
+    print.list-item -d+n;
+        Enables output of diagnostic messages. Only the output for debug level '"n"'
+        is enabled. ;
+    print.list-end ;
+    print.section "Debug Levels"
+        Each debug level shows a different set of information. Usually with the higher
+        levels producing more verbose information. The following levels are supported:
+        ;
+    print.list-start ;
+    print.list-item 0;
+        Turn off all diagnostic output. Only errors are reported. ;
+    print.list-item 1;
+        Show the actions taken for building targets, as they are executed. ;
+    print.list-item 2;
+        Show "quiet" actions and display all action text, as they are executed. ;
+    print.list-item 3;
+        Show dependency analysis, and target/source timestamps/paths. ;
+    print.list-item 4;
+        Show arguments of shell invocations. ;
+    print.list-item 5;
+        Show rule invocations and variable expansions. ;
+    print.list-item 6;
+        Show directory/header file/archive scans, and attempts at binding to targets. ;
+    print.list-item 7;
+        Show variable settings. ;
+    print.list-item 8;
+        Show variable fetches, variable expansions, and evaluation of '"if"' expressions. ;
+    print.list-item 9;
+        Show variable manipulation, scanner tokens, and memory usage. ;
+    print.list-item 10;
+        Show execution times for rules. ;
+    print.list-item 11;
+        Show parsing progress of Jamfiles. ;
+    print.list-item 12;
+        Show graph for target dependencies. ;
+    print.list-item 13;
+        Show changes in target status (fate). ;
+    print.list-end ;
+}
+
+# Generates description of options controlling the help system.
+# This automatically reads the options as all variables in the doc
+# module of the form ".option.*".
+#
+local rule print-help-options (
+    module-name # The doc module.
+    )
+{
+    print.section "Help Options"
+        These are all the options available for enabling or disabling
+        to control the help system in various ways. Options can be enabled
+        or disabled with '"--help-enable-<option>"', and "'--help-disable-<option>'"
+        respectively.
+        ;
+    local options-to-list = [ MATCH ^[.]option[.](.*) : $($(module-name).variables) ] ;
+    if $(options-to-list)
+    {
+        print.list-start ;
+        for local option in [ sequence.insertion-sort $(options-to-list) ]
+        {
+            local def = disabled ;
+            if $($(module-name)..option.$(option).default) != "(empty)"
+            {
+                def = enabled ;
+            }
+            print.list-item $(option): $($(module-name)..option.$(option).docs)
+                Default is $(def). ;
+        }
+        print.list-end ;
+    }
+}
+
+# Generate brief documentation for all the known items in the section
+# for a module. Possible sections are: "rules", and "variables".
+#
+local rule print-help-module-section (
+    module # The module name.
+    section # rules or variables.
+    : section-head # The title of the section.
+    section-description * # The detailed description of the section.
+    )
+{
+    if $($(module).$(section))
+    {
+        print.section $(section-head) $(section-description) ;
+        print.list-start ;
+        for local item in [ sequence.insertion-sort $($(module).$(section)) ]
+        {
+            local show = ;
+            if ! $($(module).$(item).is-local)
+            {
+                show = yes ;
+            }
+            if $(.option.show-locals)
+            {
+                show = yes ;
+            }
+            if $(show)
+            {
+                print.list-item $(item): $($(module).$(item).brief) ;
+            }
+        }
+        print.list-end ;
+    }
+}
+
+# Generate documentation for possible modules. We attempt to list all known
+# modules, and a brief description of each.
+#
+local rule print-help-all (
+    ignored # Usually the module name, but is ignored here.
+    )
+{
+    print.section "Modules"
+        "These are all the known modules. Use --help <module> to get more"
+        "detailed information."
+        ;
+    if $(documented-modules)
+    {
+        print.list-start ;
+        for local module-name in [ sequence.insertion-sort $(documented-modules) ]
+        {
+            # The brief docs for each module.
+            print.list-item $(module-name): $($(module-name).brief) ;
+        }
+        print.list-end ;
+    }
+    # The documentation for each module when details are requested.
+    if $(documented-modules) && $(.option.detailed)
+    {
+        for local module-name in [ sequence.insertion-sort $(documented-modules) ]
+        {
+            # The brief docs for each module.
+            print-help-module $(module-name) ;
+        }
+    }
+}
+
+# Generate documentation for a module. Basic information about
+# the module is generated.
+#
+local rule print-help-module (
+    module-name # The module to generate docs for.
+    )
+{
+    # Print the docs.
+    print.section "Module '$(module-name)'" $($(module-name).docs) ;
+    
+    # Print out the documented classes.
+    print-help-module-section $(module-name) classes : "Module '$(module-name)' classes"
+        Use --help $(module-name).<class-name> to get more information. ;
+    
+    # Print out the documented rules.
+    print-help-module-section $(module-name) rules : "Module '$(module-name)' rules"
+        Use --help $(module-name).<rule-name> to get more information. ;
+    
+    # Print out the documented variables.
+    print-help-module-section $(module-name) variables : "Module '$(module-name)' variables"
+        Use --help $(module-name).<variable-name> to get more information. ;
+    
+    # Print out all the same information but indetailed form.
+    if $(.option.detailed)
+    {
+        print-help-classes $(module-name) ;
+        print-help-rules $(module-name) ;
+        print-help-variables $(module-name) ;
+    }
+}
+
+# Generate documentation for a set of rules in a module.
+#
+local rule print-help-rules (
+    module-name # Module of the rules.
+    : name * # Optional list of rules to describe.
+    )
+{
+    name ?= $($(module-name).rules) ;
+    if [ set.intersection $(name) : $($(module-name).rules) $($(module-name).class-rules) ]
+    {
+        # Print out the given rules.
+        for local rule-name in [ sequence.insertion-sort $(name) ]
+        {
+            if $(.option.show-locals) || ! $($(module-name).$(rule-name).is-local)
+            {
+                local signature = $($(module-name).$(rule-name).signature:J=" ") ;
+                signature ?= "" ;
+                print.section "Rule '$(module-name).$(rule-name) ( $(signature) )'"
+                    $($(module-name).$(rule-name).docs) ;
+                if $($(module-name).$(rule-name).args)
+                {
+                    print.list-start ;
+                    for local arg-name in $($(module-name).$(rule-name).args)
+                    {
+                        print.list-item $(arg-name): $($(module-name).$(rule-name).args.$(arg-name).docs) ;
+                    }
+                    print.list-end ;
+                }
+            }
+        }
+    }
+}
+
+# Generate documentation for a set of classes in a module.
+#
+local rule print-help-classes (
+    module-name # Module of the classes.
+    : name * # Optional list of classes to describe.
+    )
+{
+    name ?= $($(module-name).classes) ;
+    if [ set.intersection $(name) : $($(module-name).classes) ]
+    {
+        # Print out the given classes.
+        for local class-name in [ sequence.insertion-sort $(name) ]
+        {
+            if $(.option.show-locals) || ! $($(module-name).$(class-name).is-local)
+            {
+                local signature = $($(module-name).$(class-name).signature:J=" ") ;
+                signature ?= "" ;
+                print.section "Class '$(module-name).$(class-name) ( $(signature) )'"
+                    $($(module-name).$(class-name).docs)
+                   "Inherits from '"$($(module-name).$(class-name).super-name)"'." ;
+                if $($(module-name).$(class-name).args)
+                {
+                    print.list-start ;
+                    for local arg-name in $($(module-name).$(class-name).args)
+                    {
+                        print.list-item $(arg-name): $($(module-name).$(class-name).args.$(arg-name).docs) ;
+                    }
+                    print.list-end ;
+                }
+            }
+            
+            # Print out the documented rules of the class.
+            print-help-module-section $(module-name) $(class-name).class-rules : "Class '$(module-name).$(class-name)' rules"
+                Use --help $(module-name).<rule-name> to get more information. ;
+            
+            # Print out all the rules if details are requested.
+            if $(.option.detailed)
+            {
+                print-help-rules $(module-name) : $($(module-name).$(class-name).class-rules) ;
+            }
+        }
+    }
+}
+
+# Generate documentation for a set of variables in a module.
+#
+local rule print-help-variables (
+    module-name ? # Module of the variables.
+    : name * # Optional list of variables to describe.
+    )
+{
+    name ?= $($(module-name).variables) ;
+    if [ set.intersection $(name) : $($(module-name).variables) ]
+    {
+        # Print out the given variables.
+        for local variable-name in [ sequence.insertion-sort $(name) ]
+        {
+            print.section "Variable '$(module-name).$(variable-name)'" $($(module-name).$(variable-name).docs) ;
+            if $($(module-name).$(variable-name).default) ||
+                $($(module-name).$(variable-name).initial)
+            {
+                print.list-start ;
+                if $($(module-name).$(variable-name).default)
+                {
+                    print.list-item "default value:" '$($(module-name).$(variable-name).default:J=" ")' ;
+                }
+                if $($(module-name).$(variable-name).initial)
+                {
+                    print.list-item "initial value:" '$($(module-name).$(variable-name).initial:J=" ")' ;
+                }
+                print.list-end ;
+            }
+        }
+    }
+}
+
+local rule __test__
+{
+}
+
+ws = "	 " ;
+
+# Extract the text from a block of comments.
+#
+local rule extract-comment (
+    var # The name of the variable to extract from.
+    )
+{
+    local comment = ;
+    local line = $($(var)[1]) ;
+    local l = [ MATCH "^[$(ws)]*(#)(.*)$" : $(line) ] ;
+    while $(l[1]) && $($(var))
+    {
+        if $(l[2]) { comment += [ MATCH "^[$(ws)](.*)$" : $(l[2]) ] ; }
+        else { comment += "" ; }
+        $(var) = $($(var)[2-]) ;
+        line = $($(var)[1]) ;
+        l = [ MATCH "^[$(ws)]*(#)(.*)$" : $(line) ] ;
+    }
+    return $(comment) ;
+}
+
+# Extract s single line of Jam syntax, ignoring any comments.
+#
+local rule extract-syntax (
+    var # The name of the variable to extract from.
+    )
+{
+    local syntax = ;
+    local line = $($(var)[1]) ;
+    while ! $(syntax) && ! [ MATCH "^[$(ws)]*(#)" : $(line) ] && $($(var))
+    {
+        local m = [ MATCH "^[$(ws)]*(.*)$" : $(line) ] ;
+        if $(m) && ! $(m) = ""
+        {
+            syntax = $(m) ;
+        }
+        $(var) = $($(var)[2-]) ;
+        line = $($(var)[1]) ;
+    }
+    return $(syntax) ;
+}
+
+# Extract the next token, this is either a single Jam construct
+# or a comment as a single token.
+#
+local rule extract-token (
+    var # The name of the variable to extract from.
+    )
+{
+    local parts = ;
+    while ! $(parts)
+    {
+        parts = [ MATCH "^[$(ws)]*([^$(ws)]+)[$(ws)]*(.*)" : $($(var)[1]) ] ;
+        if ! $(parts)
+        {
+            $(var) = $($(var)[2-]) ;
+        }
+    }
+    local token = ;
+    if [ MATCH "^(#)" : $(parts[1]) ]
+    {
+        token = $(parts:J=" ") ;
+        $(var) = $($(var)[2-]) ;
+    }
+    else
+    {
+        token = $(parts[1]) ;
+        $(var) = $(parts[2-]:J=" ") $($(var)[2-]) ;
+    }
+    return $(token) ;
+}
+
+# Scan for a rule declaration as the next item in the variable.
+#
+local rule scan-rule (
+    syntax ? # The first part of the text which contains the rule declaration.
+    : var # The name of the variable to extract from.
+    )
+{
+    local rule-parts =
+        [ MATCH "^[$(ws)]*(rule|local[$(ws)]*rule)[$(ws)]+([^$(ws)]+)[$(ws)]*(.*)" : $(syntax:J=" ") ] ;
+    if $(rule-parts[1])
+    {
+        # mark as doc for rule.
+        local rule-name = $(rule-parts[2]) ;
+        if $(scope-name)
+        {
+            rule-name = $(scope-name).$(rule-name) ;
+        }
+        local is-local = [ MATCH "^(local).*" : $(rule-parts[1]) ] ;
+        if $(comment-block)
+        {
+            set-rule-doc $(rule-name) $(module-name) $(is-local) : $(comment-block) ;
+        }
+        # parse args of rule.
+        $(var) = $(rule-parts[3-]) $($(var)) ;
+        set-rule-arguments-signature $(rule-name) $(module-name) : [ scan-rule-arguments $(var) ] ;
+        # scan within this rules scope.
+        local scope-level = [ extract-token $(var) ] ;
+        local scope-name = $(rule-name) ;
+        while $(scope-level)
+        {
+            local comment-block = [ extract-comment $(var) ] ;
+            local syntax-block = [ extract-syntax $(var) ] ;
+            if [ scan-rule $(syntax-block) : $(var) ]
+            {
+            }
+            else if [ MATCH "^(\\{)" : $(syntax-block) ]
+            {
+                scope-level += "{" ;
+            }
+            else if [ MATCH "^[^\\}]*([\\}])[$(ws)]*$"  : $(syntax-block) ]
+            {
+                scope-level = $(scope-level[2-]) ;
+            }
+        }
+        
+        return true ;
+    }
+}
+
+# Scan the arguments of a rule.
+#
+local rule scan-rule-arguments (
+    var # The name of the variable to extract from.
+    )
+{
+    local arg-syntax = ;
+    local token = [ extract-token $(var) ] ;
+    while $(token) != "(" && $(token) != "{"
+    {
+        token = [ extract-token $(var) ] ;
+    }
+    if $(token) != "{"
+    {
+        token = [ extract-token $(var) ] ;
+    }
+    local arg-signature = ;
+    while $(token) != ")" && $(token) != "{"
+    {
+        local arg-name = ;
+        local arg-qualifier = " " ;
+        local arg-doc = ;
+        if $(token) = ":"
+        {
+            arg-signature += $(token) ;
+            token = [ extract-token $(var) ] ;
+        }
+        arg-name = $(token) ;
+        arg-signature += $(token) ;
+        token = [ extract-token $(var) ] ;
+        if [ MATCH "^([\\*\\+\\?])" : $(token) ]
+        {
+            arg-qualifier = $(token) ;
+            arg-signature += $(token) ;
+            token = [ extract-token $(var) ] ;
+        }
+        if $(token) = ":"
+        {
+            arg-signature += $(token) ;
+            token = [ extract-token $(var) ] ;
+        }
+        if [ MATCH "^(#)" : $(token) ]
+        {
+            $(var) = $(token) $($(var)) ;
+            arg-doc = [ extract-comment $(var) ] ;
+            token = [ extract-token $(var) ] ;
+        }
+        set-argument-doc $(arg-name) $(arg-qualifier) $(rule-name) $(module-name) : $(arg-doc) ;
+    }
+    while $(token) != "{"
+    {
+        token = [ extract-token $(var) ] ;
+    }
+    $(var) = "{" $($(var)) ;
+    arg-signature ?= "" ;
+    return $(arg-signature) ;
+}
+
+# Scan for a variable declaration.
+local rule scan-variable (
+    syntax ? # The first part of the text which contains the variable declaration.
+    : var # The name of the variable to extract from.
+    )
+{
+    # [1] = name, [2] = value(s)
+    local var-parts =
+        [ MATCH "^[$(ws)]*([^$(ws)]+)[$(ws)]+([\\?\\=]*)[$(ws)]+([^\\;]*)\\;" : $(syntax) ] ;
+    if $(var-parts)
+    {
+        local value = [ MATCH "^(.*)[ ]$" : $(var-parts[3-]:J=" ") ] ;
+        local default-value = "" ;
+        local initial-valie = "" ;
+        if $(var-parts[2]) = "?="
+        {
+            default-value = $(value) ;
+            default-value ?= "(empty)" ;
+        }
+        else
+        {
+            initial-value = $(value) ;
+            initial-value ?= "(empty)" ;
+        }
+        if $(comment-block)
+        {
+            set-variable-doc $(var-parts[1]) $(default-value) $(initial-value) $(module-name) : $(comment-block) ;
+        }
+        return true ;
+    }
+}
+
+# Scan a class declaration.
+local rule scan-class (
+    syntax ? # The syntax text for the class declaration.
+    )
+{
+    # [1] = class?, [2] = name, [3] = superclass
+    local class-parts =
+        [ MATCH "^[$(ws)]*([^$(ws)]+)[$(ws)]+([^$(ws)]+)[$(ws)]+:*[$(ws)]*([^$(ws);]*)" : $(syntax) ] ;
+    if $(class-parts[1]) = "class" || $(class-parts[1]) = "class.class"
+    {
+        set-class-doc $(class-parts[2]) $(module-name) : $(class-parts[3]) ;
+    }
+}
+
+# Scan a module file for documentation comments. This also
+# invokes any actions assigned to the module. The actions
+# are the rules that do the actual output of the documentation.
+# This rue is invoked as the header scan rule for the module file.
+#
+rule scan-module (
+    target # The module file.
+    : text * # The text in the file, one item per line.
+    : binding
+    )
+{    
+    if $(.option.debug) { ECHO "HELP:" scanning module target '$(target)' ; }
+    local module-name = $(.module<$(target)>.name) ;
+    local module-documented = ;
+    local comment-block = ;
+    local syntax-block = ;
+    # This is a hack because we can't get the line of a file if it
+    # happens to not have a new-line termination.
+    text += "}" ;
+    while $(text)
+    {
+        comment-block = [ extract-comment text ] ;
+        syntax-block = [ extract-syntax text ] ;
+        if $(.option.debug)
+        {
+            ECHO "HELP:" comment block; '$(comment-block)' ;
+            ECHO "HELP:" syntax block; '$(syntax-block)' ;
+        }
+        if [ scan-rule $(syntax-block) : text ] { }
+        else if [ scan-variable $(syntax-block) : text ] { }
+        else if [ scan-class $(syntax-block) ] { }
+        else if [ MATCH .*([cC]opyright).* : $(comment-block:J=" ") ]
+        {
+            # mark as the copy for the module.
+            set-module-copyright $(module-name) : $(comment-block) ;
+        }
+        else if ! $(module-documented)
+        {
+            # document the module.
+            set-module-doc $(module-name) : $(comment-block) ;
+            module-documented = true ;
+        }
+    }
+    for local action in $(.module<$(target)>.actions)
+    {
+        local action-rule = [ $(action).front ] ; $(action).pop-front ;
+        local action-args = [ $(action).get ] ;
+        local ignored = [ $(action-rule) $(module-name) : $(action-args) ] ;
+    }
+}
+
+# Import scan-module to global scope, so that it's available during
+# header scanning phase.
+IMPORT $(__name__) : scan-module : : doc.scan-module ;
+
+
+# Add a scan action to perform to generate the help documentation.
+# The action rule is passed the name of the module as the first argument.
+# The second argument(s) are optional and passed directly as specified
+# here.
+#
+local rule do-scan (
+    modules + # The modules to scan and perform the action on.
+    : action * # The action rule, plus the secondary arguments to pass to the action rule.
+    )
+{
+    local targets = ;
+    for local module-file in $(modules)
+    {
+        local module-name = $(module-file:B) ;
+        .module<$(module-file)>.name = $(module-name) ;
+        if $(action)
+        {
+            .module<$(module-file)>.actions += [ class.new vector $(action) ] ;
+        }
+        HDRSCAN on $(module-file) = "^(.*).$" ;
+        HDRRULE on $(module-file) = doc.scan-module ;
+        NOTFILE $(module-name).scan ;
+        ALWAYS $(module-name).scan ;
+        INCLUDES $(module-name).scan : $(module-file) ;
+        targets += $(module-name).scan ;
+    }
+    if $(help-output) = console
+    {
+        DEPENDS all : $(targets) ;
+    }
+    if $(help-output) = text
+    {
+        print.output $(help-output-file).txt plain ;
+        ALWAYS $(help-output-file).txt ;
+        DEPENDS $(help-output-file).txt : $(targets) ;
+        DEPENDS all : $(help-output-file).txt ;
+    }
+    if $(help-output) = html
+    {
+        print.output $(help-output-file).html html ;
+        ALWAYS $(help-output-file).html ;
+        DEPENDS $(help-output-file).html : $(targets) ;
+        DEPENDS all : $(help-output-file).html ;
+    }
+}

Added: boost-jam/boost-build/branches/upstream/current/util/indirect.jam
===================================================================
--- boost-jam/boost-build/branches/upstream/current/util/indirect.jam	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/util/indirect.jam	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,103 @@
+# Copyright David Abrahams 2003. Permission to copy, use,
+# modify, sell and distribute this software is granted provided this
+# copyright notice appears in all copies. This software is provided
+# "as is" without express or implied warranty, and with no claim as
+# to its suitability for any purpose.
+import modules ;
+import numbers ;
+
+# The pattern that indirect rules must match: module$rule
+.pattern = ^([^%]*)%([^%]+)$ ;
+  
+#
+# Type checking rules.
+#
+local rule indirect-rule ( x )
+{
+    if ! [ MATCH $(.pattern) : $(x) ]
+    {
+        return "expected a string of the form module$rule, but got \""$(x)"\" for argument" ;
+    }
+}
+
+# make an indirect rule which calls the given rule; if context is
+# supplied it is expected to be the module in which to invoke the rule
+# by the 'call' rule below.  Otherwise, the rule will be invoked in
+# the module of this rule's caller.
+rule make ( rulename bound-args * : context ? )
+{
+    context ?= [ CALLER_MODULE ] ;
+    context ?= "" ;
+    return $(context)%$(rulename) $(bound-args) ;
+}
+
+# make an indirect rule which calls the given rule.  rulename may be a
+# qualified rule; if so it is returned unchanged.  Otherwise, if
+# frames is not supplied, the result will be invoked (by 'call',
+# below) in the module of the caller.  Otherwise, frames > 1
+# specifies additional call frames to back up in order to find the
+# module context.
+rule make-qualified ( rulename bound-args * : frames ? )
+{
+    if [ MATCH $(.pattern) : $(rulename) ]
+    {
+        return $(rulename) $(bound-args) ;
+    }
+    else
+    {
+        frames ?= 1 ;
+        # Take the first dot-separated element as module name.
+        # This disallows module names with dots, but allows rule names
+        # with dots.
+        local module-context = [ MATCH ^([^.]*)\\..* : $(rulename) ] ;
+        module-context ?= [ CALLER_MODULE $(frames) ] ;
+        return [ make $(rulename) $(bound-args) : $(module-context) ] ;
+    }
+}
+
+# return the module name in which the given indirect rule will be
+# invoked.
+rule get-module ( [indirect-rule] x )
+{
+    local m = [ MATCH $(.pattern) : $(x) ] ;
+    if ! $(m[1])
+    {
+        m = ;
+    }
+    return $(m[1]) ;
+}
+
+# return the rulename that will be called when x is invoked
+rule get-rule ( [indirect-rule] x )
+{
+    local m = [ MATCH $(.pattern) : $(x) ] ;
+    return $(m[2]) ;
+}
+
+# Invoke the given indirect-rule.
+rule call ( [indirect-rule] r args * : * )
+{
+    return [
+      modules.call-in [ get-module $(r) ]
+        : [ get-rule $(r) ] $(args) : $(2) : $(3) : $(4) : $(5) : $(6) : $(7) : $(8) : $(9) 
+    ] ;
+}
+
+rule __test__
+{
+    import assert ;
+    
+    rule foo-barr! ( x )
+    {
+        assert.equal $(x) : x ;
+    }
+    
+    assert.equal [ get-rule [ make foo-barr! ] ] : foo-barr! ;
+    assert.equal [ get-module [ make foo-barr! ] ] : [ CALLER_MODULE ] ;
+    
+    call [ make foo-barr! ] x ;
+    call [ make foo-barr! x ] ;
+    
+    
+    call [ make foo-barr! : [ CALLER_MODULE ] ] x ;
+}
\ No newline at end of file


Property changes on: boost-jam/boost-build/branches/upstream/current/util/indirect.jam
___________________________________________________________________
Name: svn:executable
   + 

Added: boost-jam/boost-build/branches/upstream/current/util/numbers.jam
===================================================================
--- boost-jam/boost-build/branches/upstream/current/util/numbers.jam	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/util/numbers.jam	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,230 @@
+#  (C) Copyright David Abrahams 2001. Permission to copy, use, modify, sell and
+#  distribute this software is granted provided this copyright notice appears in
+#  all copies. This software is provided "as is" without express or implied
+#  warranty, and with no claim as to its suitability for any purpose.
+
+digits = 0 1 2 3 4 5 6 7 8 9 ;
+powers = 1 ;
+zeros = "" ;
+natural = $(digits) ;
+positive = $(digits[2-]) ;
+incr = $(positive[2-]) ;
+znatural = $(digits) ;
+zero-test = is zero ; # if $(zero-test[$(n)]) == "is" "zero", n == 0
+
+import errors : * ;
+
+local rule extend ( )
+{
+    local next = $(digits[2-])$(znatural) ;
+    natural += $(next) ;
+    positive += $(next) ;
+    incr += $(next) ;
+    znatural = $(digits)$(znatural) ;
+}
+
+rule check ( numbers * )
+{
+    for local n in $(numbers)
+    {
+        switch $(n)
+        {
+            case *[^0-9]* :
+              error $(n) "in" $(numbers) : is not a number ;
+        }
+    }
+}
+
+rule increment ( number )
+{
+    return [ CALC $(number) + 1 ] ;
+}
+
+rule decrement ( number )
+{
+    # Previous rule did not allow decrementing zero. 
+    # Is that what we want?
+    return [ CALC $(number) - 1 ] ;
+}
+
+rule range ( start finish ? : step ? )
+{
+    if ! $(finish)
+    {
+        finish = $(start) ;
+        start = 1 ;
+    }
+    step ?= 1 ;
+    
+    check $(start) $(finish) $(step) ;
+
+    if $(finish) != 0
+    {
+        while ! $(positive[$(finish)])
+        {
+            extend ;
+        }
+        
+        if $(step) = 1
+        {
+            return $(positive[$(start)-$(finish)]) ;
+        }
+        else
+        {
+            local index = [ increment $(step) ] ;
+            local by1 = $(positive[$(start)-$(finish)]) ;
+            local result ;
+            while $(by1)
+            {
+                result += $(by1[1]) ;
+                by1 = $(by1[$(index)-]) ;
+            }
+            return $(result) ;
+        }
+    }
+}
+
+rule less ( n1 n2 )
+{
+    check $(n1) $(n2) ;
+    # avoid messy 0 case by appending 1
+    local l1 = [ range 2 [ log10 $(n1)1 ] ] ;
+    local l2 = [ range 2 [ log10 $(n2)1 ] ] ;
+    
+    # number of digits mismatch?
+    if ( $(l1) < $(l2) ) || ( ( $(l1) = $(l2) ) && $(n1) < $(n2) )
+    {
+        return true ;
+    }
+}
+
+rule log10 ( number )
+{
+    switch $(number)
+    {
+        case *[^0-9]* : error $(number) is not a number ;
+        case 0 : error can't take log of zero ;
+        case [1-9] : return 0 ;
+        case [1-9]? : return 1 ;
+        case [1-9]?? : return 2 ;
+        case [1-9]??? : return 3 ;
+        case [1-9]???? : return 4 ;
+        case [1-9]????? : return 5 ;
+        case [1-9]?????? : return 6 ;
+        case [1-9]??????? : return 7 ;
+        case [1-9]???????? : return 8 ;
+        case [1-9]????????? : return 9 ;
+        case * :
+        {
+            import sequence ;
+            import string ;
+            local chars = [ string.chars $(number) ] ;
+            while $(chars[1]) = 0
+            {
+                chars = $(chars[2-]) ;
+            }
+            
+            if ! $(chars)
+            {
+                error can't take log of zero ;
+            }
+            else
+            {
+                return [ sequence.length $(chars) ] ;
+            }
+        }
+    }
+}
+
+rule __test__ ( )
+{
+    import assert ;
+    
+    assert.result 1 : increment 0 ;
+    assert.result 2 : increment 1 ;
+    assert.result 1 : decrement 2 ;
+    assert.result 0 : decrement 1 ;
+    assert.result 50 : increment 49 ;
+    assert.result 49 : decrement 50 ;
+    assert.result 99 : increment 98 ;
+    assert.result 99 : decrement 100 ;
+    assert.result 100 : increment 99 ;
+    # This just makes debugging output too large
+    # assert.result 1000 : increment 999 ;
+    # assert.result 999 : decrement 1000 ;
+    
+    assert.result 1 2 3 : range 3 ;
+    assert.result 1 2 3 4 5 6 7 8 9 10 11 12 : range 12 ;
+    assert.result 3 4 5 6 7 8 9 10 11 : range 3 11 ;
+    assert.result : range 0 ;
+    assert.result 1 4 7 10 : range 10 : 3 ;
+    assert.result 2 4 6 8 10 : range 2 10 : 2 ;
+    assert.result 25 50 75 100 : range 25 100 : 25 ;
+    
+    assert.true less 1 2 ;
+    assert.true less 1 12 ;
+    assert.true less 1 21 ;
+    assert.false less 0 0 ;
+      
+    # TEMPORARY disabled, because nested "try"/"catch" do not work, I don't the
+    # time to fix that right now.
+    if $(0) 
+    {        
+    try ;
+    {
+        decrement 0 ;
+    }
+    catch can't decrement zero! ;
+    
+    try ;
+    {
+        check foo ;
+    }
+    catch : not a number ;
+    
+    try ;
+    {
+        increment foo ;
+    }
+    catch : not a number ;
+        
+    try ;
+    {
+        log10 0 ;
+    }
+    catch can't take log of zero ;
+    
+    try ;
+    {
+        log10 000 ;
+    }
+    catch can't take log of zero ;
+
+    }
+        
+    assert.result 0 : log10 1 ;
+    assert.result 0 : log10 9 ;
+    assert.result 1 : log10 10 ;
+    assert.result 1 : log10 99 ;
+    assert.result 2 : log10 125 ;
+    assert.result 11 : log10 12345678901 ;
+    
+    for local x in [ range 75 110 : 5 ]
+    {
+        for local y in [ range $(x) 111 : 3 ]
+        {
+            if $(x) != $(y)
+            {
+                assert.true less $(x) $(y) ;
+            }
+        }
+    }
+    
+    for local x in [ range 90 110 : 2 ]
+    {
+        for local y in [ range 80 $(x) : 4 ]
+        {
+            assert.false less $(x) $(y) ;
+        }
+    }
+}

Added: boost-jam/boost-build/branches/upstream/current/util/order.jam
===================================================================
--- boost-jam/boost-build/branches/upstream/current/util/order.jam	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/util/order.jam	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,173 @@
+#  Copyright (C) 2003 Vladimir Prus
+#  Use, modification, and distribution is subject to the Boost Software
+#  License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy
+#  at http://www.boost.org/LICENSE_1_0.txt)
+
+#  This module defines a class which allows to order arbitrary object
+#  with regard to arbitrary binary relation.
+#
+#  The primary use case is the gcc toolset, which is sensitive to
+#  library order: if library 'a' uses symbols from library 'b',
+#  then 'a' must be present before 'b' on the linker's command line.
+#
+#  This requirement can be lifted for gcc with GNU ld, but for gcc with
+#  Solaris LD (and for Solaris toolset as well), the order always matters.
+#
+#  So, we need to store order requirements and then order libraries
+#  according to them. It it not possible to use dependency graph as
+#  order requirements. What we need is "use symbols" relationship
+#  while dependency graph provides "needs to be updated" relationship.
+#
+#  For example::
+#    lib a : a.cpp b;
+#    lib b ;
+#
+#  For static linking, the 'a' library need not depend on 'b'. However, it
+#  still should come before 'b' on the command line.
+
+class order 
+{
+    rule __init__ ( ) {
+    }
+    
+    # Adds the constraint that 'first' should precede 'second' 
+    rule add-pair ( first second )
+    {
+        .constraits += $(first)--$(second) ;
+    }
+    NATIVE_RULE class at order : add-pair ;
+    
+    # Given a list of objects, reorder them so that the constains specified
+    # by 'add-pair' are satisfied.
+    #
+    # The algorithm was adopted from an awk script by Nikita Youshchenko
+    # (yoush at cs dot msu dot su)
+    rule order ( objects * )
+    {
+        # The algorithm used is the same is standard transitive closure,
+        # except that we're not keeping in-degree for all vertices, but
+        # rather removing edges.
+        local result ;
+        if $(objects)
+        {        
+            local constraints = [ eliminate-unused-constraits $(objects) ] ;            
+            
+            # Find some library that nobody depends upon and add it to
+            # the 'result' array.
+            local obj ;
+            while $(objects)
+            {              
+                local new_objects ;
+                while $(objects)
+                {
+                    obj = $(objects[1]) ;            
+                    if [ has-no-dependents $(obj) : $(constraints) ]
+                    {
+                        # Emulate break ;
+                        new_objects += $(objects[2-]) ;
+                        objects = ;
+                    }                
+                    else
+                    {
+                        new_objects += $(obj) ;
+                        obj = ;
+                        objects = $(objects[2-]) ;
+                    }
+                }
+                
+                if ! $(obj)
+                {
+                    errors.error "Circular order dependencies" ;
+                }
+                # No problem with placing first.
+                result += $(obj) ;
+                # Remove all containts where 'obj' comes first,
+                # since they are already satisfied.
+                constraints = [ remove-satisfied $(constraints) : $(obj) ] ;
+                # Add the remaining objects for further processing
+                # on the next iteration
+                                
+                objects = $(new_objects) ;                
+            }                                                
+            
+        }        
+        return $(result) ;
+    }                     
+    NATIVE_RULE class at order : order ;
+    
+    # Eliminate constains which mentions objects not in 'objects'.
+    # In graph-theory terms, this is finding subgraph induced by
+    # ordered vertices.
+    rule eliminate-unused-constraits ( objects * )
+    {
+        local result ;
+        for local c in $(.constraints)
+        {
+            local m = [ MATCH (.*)--(.*) : $(c) ] ;
+            if $(m[1]) in $(objects) && $(m[2]) in $(objects)
+            {
+                result += $(c) ;
+            }           
+        }    
+        return $(result) ;
+    }
+    
+    # Returns true if there's no constrain in 'constaraint' where 
+    # 'obj' comes second.
+    rule has-no-dependents ( obj : constraints * )
+    {
+        local failed ;
+        while $(constraints) && ! $(failed)          
+        {
+            local c = $(constraints[1]) ;
+            local m = [ MATCH (.*)--(.*) : $(c) ] ;
+            if $(m[2]) = $(obj)
+            {
+                failed = true ;
+            }            
+            constraints = $(constraints[2-]) ;
+        }
+        if ! $(failed)
+        {
+            return true ;
+        }    
+    }
+    
+    rule remove-satisfied ( constraints * : obj )
+    {
+        local result ;
+        for local c in $(constraints)
+        {
+            local m = [ MATCH (.*)--(.*) : $(c) ] ;
+            if $(m[1]) != $(obj)
+            {
+                result += $(c) ;
+            }            
+        }
+        return $(result) ;        
+    }            
+}
+
+rule __test__ ( )
+{
+    import "class" : new ;
+    import assert ;
+    
+    c1 = [ new order ] ;
+    $(c1).add-pair l1 l2 ;
+    
+    assert.result l1 l2 : $(c1).order l1 l2 ;
+    assert.result l1 l2 : $(c1).order l2 l1 ;
+    
+    $(c1).add-pair l2 l3 ;
+    assert.result l1 l2 : $(c1).order l2 l1 ;
+    $(c1).add-pair x l2 ;
+    assert.result l1 l2 : $(c1).order l2 l1 ;
+    assert.result l1 l2 l3 : $(c1).order l2 l3 l1 ;
+    
+
+    
+    
+}
+
+

Added: boost-jam/boost-build/branches/upstream/current/util/os.jam
===================================================================
--- boost-jam/boost-build/branches/upstream/current/util/os.jam	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/util/os.jam	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,51 @@
+#  (C) Copyright David Abrahams 2001. Permission to copy, use, modify, sell and
+#  distribute this software is granted provided this copyright notice appears in
+#  all copies. This software is provided "as is" without express or implied
+#  warranty, and with no claim as to its suitability for any purpose.
+
+import modules ;
+name = [ modules.peek : OS ] ;
+platform = [ modules.peek : OSPLAT ] ;
+version = [ modules.peek : OSVER ] ;
+
+rule name { return $(name) ; }
+rule platform { return $(platform) ; }
+rule version { return $(version) ; }
+
+# Returns true if running on windows, whether in cygwin or not.
+rule on-windows 
+{
+    local result ;
+    if [ modules.peek : NT ] 
+    {
+        result = true ;
+    }
+    else if [ modules.peek : UNIX ] 
+    {
+        switch [ modules.peek : JAMUNAME ] 
+        {
+            case CYGWIN* :
+            {
+                result = true ;
+            }
+        }
+    }
+    return $(result) ;
+}
+
+     
+
+import regex ;
+
+rule __test__
+{
+    import assert ;
+    rule identity ( args * ) { return $(args) ; }
+
+    if ! ( --quiet in [ modules.peek : ARGV ] )
+    {
+        ECHO os: name= [ name ] ;
+        ECHO os: version= [ version ] ;
+    }
+    assert.true name ;
+}

Added: boost-jam/boost-build/branches/upstream/current/util/path.jam
===================================================================
--- boost-jam/boost-build/branches/upstream/current/util/path.jam	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/util/path.jam	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,727 @@
+#  Copyright (C) Vladimir Prus 2002. Permission to copy, use, modify, sell and
+#  distribute this software is granted provided this copyright notice appears in
+#  all copies. This software is provided "as is" without express or implied
+#  warranty, and with no claim as to its suitability for any purpose.
+
+#  Performs various path manipulations. Path are always in a 'normilized' 
+#  representation. In it, a path may be either:
+#
+#     - '.', or
+#
+#     - ['/'] [ ( '..' '/' )*  (token '/')* token ]
+# 
+#   In plain english, path can be rooted, '..' elements are allowed only
+#   at the beginning, and it never ends in slash, except for path consisting
+#   of slash only.
+
+import modules ;
+import sequence ;
+import regex ;
+import errors : error ;
+
+
+os = [ modules.peek : OS ] ;
+if [ modules.peek : UNIX ] 
+{    
+    local uname = [ modules.peek : JAMUNAME ] ;
+    switch $(uname)
+    {
+        case CYGWIN* :
+          os = CYGWIN ;
+        
+        case * :
+          os = UNIX ;
+    }        
+}
+
+#
+#    Converts the native path into normalized form.
+#
+rule make ( native )
+{
+    return [ make-$(os) $(native) ] ;
+}
+
+#
+#    Builds native representation of the path.
+#
+rule native ( path )
+{
+    return [ native-$(os) $(path) ] ;
+}
+
+#
+#    Tests if a path is rooted.
+#
+rule is-rooted ( path )
+{
+    return [ MATCH "^(/)" : $(path) ] ;
+}
+
+#
+#    Tests if a path has a parent.
+#
+rule has-parent ( path )
+{
+    if $(path) != / {
+        return 1 ;
+    } else {
+        return ;
+    }
+}
+
+#
+#    Returns the path without any directory components.
+#
+rule basename ( path )
+{
+    return [ MATCH "([^/]+)$" : $(path) ] ;
+}
+
+#
+#    Returns parent directory of the path. If no parent exists, error is issued.
+#
+rule parent ( path )
+{
+    if [ has-parent $(path) ] {
+
+        if $(path) = . {
+            return .. ;
+        } else {
+
+            # Strip everything at the end of path up to and including
+            # the last slash
+            local result = [ regex.match "((.*)/)?([^/]+)" : $(path) : 2 3 ] ;
+
+            # Did we strip what we shouldn't?
+            if $(result[2]) = ".." {
+                return $(path)/.. ;
+            } else {
+                if ! $(result[1]) {
+                    if [ is-rooted $(path) ] {
+                        result = / ;
+                    } else {
+                        result = . ;
+                    }
+                }
+                return $(result[1]) ;
+            }
+        }
+    } else {
+        error "Path '$(path)' has no parent" ;
+    }
+}
+
+#
+#    Returns path2 such that "[ join path path2 ] = .".
+#    The path may not contain ".." element or be rooted.
+#
+rule reverse ( path )
+{
+    if $(path) = .
+    {
+        return $(path) ;
+    }
+    else
+    {
+        local tokens = [ regex.split $(path) "/" ] ;
+        local tokens2 ;
+        for local i in $(tokens) {
+            tokens2 += .. ;
+        }
+        return [ sequence.join $(tokens2) : "/" ] ;
+    }
+}
+
+#
+# Auxillary rule: does all the semantic of 'join', except for error cheching.
+# The error checking is separated because this rule is recursive, and I don't
+# like the idea of checking the same input over and over.
+#
+local rule join-imp ( elements + )
+{
+    return [ NORMALIZE_PATH $(elements:J="/") ] ;
+}
+
+#
+#    Contanenates the passed path elements. Generates an error if
+#    any element other than the first one is rooted.
+#
+rule join ( elements + )
+{
+    if ! $(elements[2]) 
+    {
+        return $(elements[1]) ;
+    }
+    else
+    {        
+        for local e in $(elements[2-])
+        {
+            if [ is-rooted $(e) ]
+            {
+                error only first element may be rooted ;
+            }
+        }
+        return [ join-imp $(elements) ] ;
+    }    
+}
+
+
+#
+#    If 'path' is relative, it is rooted at 'root'. Otherwise, it's unchanged.
+#
+rule root ( path root )
+{
+    if [ is-rooted $(path) ] {
+        return $(path) ;
+    } else {
+        return [ join $(root) $(path) ] ;
+    }
+}
+
+#
+#   Returns the current working directory.
+#
+rule pwd ( )
+{
+    return [ make [ PWD ] ] ;
+}
+
+#
+#    Returns the list of files matching the given pattern in the specified directory.
+#
+rule glob ( dirs * : patterns + )
+{
+    local result ;
+    for dir in $(dirs)
+    {
+        result += [ sequence.transform make : [ GLOB [ native $(dir) ] : $(patterns) ] ] ;
+    }
+    return $(result) ;
+}
+
+#
+#    Returns true is the specified file exists.
+#
+rule exists ( file )
+{
+    return [ path.glob $(file:D) : $(file:D=) ] ;
+}
+NATIVE_RULE path : exists ;
+
+
+
+#
+#   Find out the absolute name of path and returns the list of all the parents,
+#   starting with the immediate one. Parents are returned as relative names.
+#   If 'upper_limit' is specified, directories above it will be pruned.
+#
+rule all-parents ( path : upper_limit ? : cwd ? )
+{
+    cwd ?= [ pwd ] ;
+    local path_ele = [ regex.split [ root $(path) $(cwd) ] "/" ] ;
+
+    if ! $(upper_limit) {
+        upper_limit = / ;
+    }
+    local upper_ele = [ regex.split [ root $(upper_limit) $(cwd) ] "/" ] ;
+
+    # Leave only elements in 'path_ele' below 'upper_ele'
+    while $(path_ele) && $(upper_ele[1]) = $(path_ele[1]) {
+        upper_ele = $(upper_ele[2-]) ;
+        path_ele = $(path_ele[2-]) ;
+    }
+    
+    # All upper elements removed ?
+    if ! $(upper_ele) {
+        # Create the relative paths to parents, number of elements in 'path_ele'
+        local result ;
+        for local i in $(path_ele) {
+            path = [ parent $(path) ] ;
+            result += $(path) ;
+        }
+        return $(result) ;
+    }
+    else {
+        error "$(upper_limit) is not prefix of $(path)" ;
+    }
+}
+
+
+#
+#  Search for 'pattern' in parent directories of 'dir', up till and including
+#  'upper_limit', if it is specified, or till the filesystem root otherwise.
+#
+rule glob-in-parents ( dir : patterns + : upper-limit ? )
+{
+    local result ;
+    local parent-dirs = [ all-parents $(dir) : $(upper-limit) ] ;
+
+    while $(parent-dirs) && ! $(result)
+    {
+        result = [ glob $(parent-dirs[1]) : $(patterns) ] ;
+        parent-dirs = $(parent-dirs[2-]) ;
+    }
+    return $(result) ;    
+}
+
+#
+# Assuming 'child' is a subdirectory of 'parent', return the relative
+# path from 'parent' to 'child'
+#
+rule relative ( child parent )
+{
+    if $(parent) = "." 
+    {
+        return $(child) ;
+    }
+    else 
+    {       
+        local split1 = [ regex.split $(parent) / ] ;
+        local split2 = [ regex.split $(child) / ] ;
+    
+        while $(split1)
+        {
+            if $(split1[1]) = $(split2[1])
+            {
+                split1 = $(split1[2-]) ;
+                split2 = $(split2[2-]) ;
+            }
+            else
+            {
+                errors.error $(child) is not a subdir of $(parent) ;
+            }                
+        }    
+        return [ join $(split2) ] ;    
+    }    
+}
+
+# Returns the minimal path to path2 that is relative path1.
+#
+rule relative-to ( path1 path2 )
+{
+    local root_1 = [ regex.split [ reverse $(path1) ] / ] ;
+    local split1 = [ regex.split $(path1) / ] ;
+    local split2 = [ regex.split $(path2) / ] ;
+
+    while $(split1) && $(root_1)
+    {
+        if $(split1[1]) = $(split2[1])
+        {
+            root_1 = $(root_1[2-]) ;
+            split1 = $(split1[2-]) ;
+            split2 = $(split2[2-]) ;
+        }
+        else
+        {
+            split1 = ;
+        }
+    }
+    return [ join . $(root_1) $(split2) ] ;
+}
+
+# Returns the list of paths which are used by the operating system
+# for looking up programs
+rule programs-path ( )
+{
+    local result ;
+    local raw = [ modules.peek : PATH Path path ] ;
+    for local p in $(raw)
+    {
+        if $(p)
+        {
+            result += [ path.make $(p) ] ;
+        }        
+    }
+    return $(result) ;
+}
+
+rule make-NT ( native )
+{
+    local tokens = [ regex.split $(native) "[/\\]" ] ;
+    local result ;
+
+    # Handle paths ending with slashes
+    if $(tokens[-1]) = ""
+    {
+        tokens = $(tokens[1--2]) ; # discard the empty element
+    }
+
+    result = [ path.join $(tokens) ] ;
+
+    if [ regex.match "(^.:)" : $(native)  ]
+    {
+        result = /$(result) ;
+    }
+    
+    if $(native) = ""
+    {
+        result = "." ;
+    }
+        
+    return $(result) ;
+}
+
+rule native-NT ( path )
+{
+    local result = [ MATCH "^/?(.*)" : $(path) ] ;
+    result = [ sequence.join [ regex.split $(result) "/" ] : "\\" ] ;
+    return $(result) ;
+}
+
+rule make-UNIX ( native )
+{
+    # VP: I have no idea now 'native' can be empty here! But it can!
+    if $(native) = ""
+    {
+        errors.error "Empty path passed to 'make-UNIX'" ;
+    }
+    else
+    {        
+        return [ NORMALIZE_PATH $(native:T) ] ;
+    }    
+}
+
+rule native-UNIX ( path )
+{
+    return $(path) ;
+}
+
+rule make-CYGWIN ( path )
+{
+    return [ make-NT $(path) ] ;
+}
+
+rule native-CYGWIN ( path )
+{
+    local result = $(path) ;
+    if [ regex.match "(^/.:)" : $(path)  ] # win absolute
+    {
+        result = [ MATCH "^/?(.*)" : $(path) ] ; # remove leading '/'
+    }
+    return [ native-UNIX $(result) ] ;
+}
+
+#
+# split-VMS: splits input native path into
+# device dir file (each part is optional),
+# example:
+#
+# dev:[dir]file.c => dev: [dir] file.c
+#
+rule split-path-VMS ( native )
+{
+    local matches = [ MATCH ([a-zA-Z0-9_-]+:)?(\\[[^\]]*\\])?(.*)?$   : $(native) ] ;
+    local device = $(matches[1]) ;
+    local dir = $(matches[2]) ;
+    local file = $(matches[3]) ;
+
+    return $(device) $(dir) $(file) ;
+}
+
+#
+# Converts a native VMS path into a portable path spec.
+#
+# Does not handle current-device absolute paths such
+# as "[dir]File.c" as it is not clear how to represent
+# them in the portable path notation.
+#
+# Adds a trailing dot (".") to the file part if no extension
+# is present (helps when converting it back into native path).
+#
+rule make-VMS ( native )
+{
+    if [ MATCH ^(\\[[a-zA-Z0-9]) : $(native) ]
+    {
+        errors.error "Can't handle default-device absolute paths: " $(native) ;
+    }
+        
+    local parts = [ split-path-VMS $(native) ] ;
+    local device = $(parts[1]) ;
+    local dir = $(parts[2]) ;
+    local file = $(parts[3]) ;
+    local elems ;
+    
+    if $(device)
+    {
+        #
+        # rooted
+        #
+        elems = /$(device) ;
+    }
+    
+    if $(dir) = "[]"
+    {
+        #
+        # Special case: current directory
+        #
+        elems = $(elems) "." ;
+    }
+    else if $(dir)
+    {
+        dir = [ regex.replace $(dir) "\\[|\\]" "" ] ;
+        local dir_parts = [ regex.split $(dir) \\. ]  ;
+    
+        if $(dir_parts[1]) = ""
+        {
+            #
+            # Relative path
+            #
+            dir_parts = $(dir_parts[2--1]) ;
+        }
+        
+        #
+        # replace "parent-directory" parts (- => ..)
+        #
+        dir_parts = [ regex.replace-list $(dir_parts) : - : .. ] ;
+        
+        elems = $(elems) $(dir_parts) ;
+    }
+    
+    if $(file)
+    {
+        if ! [ MATCH (\\.) : $(file) ]
+        {
+            #
+            # Always add "." to end of non-extension file
+            #
+            file = $(file). ;
+        }
+        elems = $(elems) $(file) ;
+    }
+
+    local portable = [ path.join $(elems) ] ;
+
+    return $(portable) ;
+}
+
+#
+# Converts a portable path spec into a native VMS path.
+#
+# Relies on having at least one dot (".") included in the file
+# name to be able to differentiate it ftom the directory part.
+#
+rule native-VMS ( path )
+{
+    local device = "" ;
+    local dir = $(path) ;
+    local file = "" ;
+    local native ;
+    local split ;
+
+    #
+    # Has device ?
+    #
+    if [ is-rooted $(dir) ]
+    {
+        split = [ MATCH ^/([^:]+:)/?(.*) : $(dir) ] ;
+        device = $(split[1]) ;
+        dir = $(split[2]) ;
+    }
+
+    #
+    # Has file ?
+    #
+    # This is no exact science, just guess work:
+    #
+    # If the last part of the current path spec
+    # includes some chars, followed by a dot,
+    # optionally followed by more chars -
+    # then it is a file (keep your fingers crossed).
+    #
+    split = [ regex.split $(dir) / ] ;
+    local maybe_file = $(split[-1]) ;
+
+    if [ MATCH ^([^.]+\\..*) : $(maybe_file) ]
+    {
+        file = $(maybe_file) ;
+        dir = [ sequence.join $(split[1--2]) : / ] ;
+    }
+    
+    #
+    # Has dir spec ?
+    #
+    if $(dir) = "."
+    {
+        dir = "[]" ;
+    }
+    else if $(dir)
+    {
+        dir = [ regex.replace $(dir) \\.\\. - ] ;
+        dir = [ regex.replace $(dir) / . ] ;
+
+        if $(device) = ""
+        {
+            #
+            # Relative directory
+            # 
+            dir = "."$(dir) ;
+        }
+        dir = "["$(dir)"]" ;
+    }
+    
+    native = [ sequence.join $(device) $(dir) $(file) ] ;
+
+    return $(native) ;
+}
+
+
+rule __test__ ( ) {
+
+    import assert ;
+    import errors : try catch ;
+
+    assert.true is-rooted "/" ;
+    assert.true is-rooted "/foo" ;
+    assert.true is-rooted "/foo/bar" ;
+    assert.result : is-rooted "." ;
+    assert.result : is-rooted "foo" ;
+    assert.result : is-rooted "foo/bar" ;
+
+    assert.true has-parent "foo" ;
+    assert.true has-parent "foo/bar" ;
+    assert.true has-parent "." ;
+    assert.result : has-parent "/" ;
+
+    assert.result "." : basename "." ;
+    assert.result ".." : basename ".." ;
+    assert.result "foo" : basename "foo" ;
+    assert.result "foo" : basename "bar/foo" ;
+    assert.result "foo" : basename "gaz/bar/foo" ;
+    assert.result "foo" : basename "/gaz/bar/foo" ;
+
+    assert.result "." : parent "foo" ;
+    assert.result "/" : parent "/foo" ;
+    assert.result "foo/bar" : parent "foo/bar/giz" ;
+    assert.result ".." : parent "." ;
+    assert.result ".." : parent "../foo" ;
+    assert.result "../../foo" : parent "../../foo/bar" ;
+
+
+    assert.result "." : reverse "." ;
+    assert.result ".." : reverse "foo" ;
+    assert.result "../../.." : reverse "foo/bar/giz" ;
+
+    assert.result "foo" : join "foo" ;
+    assert.result "/foo" : join "/" "foo" ;
+    assert.result "foo/bar" : join "foo" "bar" ;
+    assert.result "foo/bar" : join "foo/giz" "../bar" ;
+    assert.result "foo/giz" : join "foo/bar/baz" "../../giz" ;
+    assert.result ".." : join "." ".." ;
+    assert.result ".." : join "foo" "../.." ;
+    assert.result "../.." : join "../foo" "../.." ;
+    assert.result "/foo" : join "/bar" "../foo" ;
+    assert.result "foo/giz" : join "foo/giz" "." ;
+    assert.result "." : join lib2 ".." ;
+    assert.result "/" : join "/a" ".." ;
+
+    assert.result /a/b : join /a/b/c .. ;
+
+    assert.result "foo/bar/giz" : join "foo" "bar" "giz" ;
+    assert.result "giz" : join "foo" ".." "giz" ;
+    assert.result "foo/giz" : join "foo" "." "giz" ;
+
+    try ;
+    {
+        join "a" "/b" ;
+    }
+    catch only first element may be rooted ;
+
+    local CWD = "/home/ghost/build" ;
+    assert.result : all-parents . : . : $(CWD) ;
+    assert.result . .. ../.. ../../..  : all-parents "Jamfile" : "" : $(CWD) ;
+    assert.result foo . .. ../.. ../../.. : all-parents "foo/Jamfile" : "" : $(CWD) ;
+    assert.result ../Work .. ../.. ../../.. : all-parents "../Work/Jamfile" : "" : $(CWD) ;
+
+    local CWD = "/home/ghost" ;
+    assert.result . .. : all-parents "Jamfile" : "/home" : $(CWD) ;
+    assert.result . : all-parents "Jamfile" : "/home/ghost" : $(CWD) ;
+    
+    assert.result "c/d" : relative "a/b/c/d" "a/b" ;
+    assert.result "foo" : relative "foo" "." ;
+
+    local save-os = [ modules.peek path : os ] ;
+    modules.poke path : os : NT ;
+
+    assert.result "foo/bar/giz" : make "foo/bar/giz" ;
+    assert.result "foo/bar/giz" : make "foo\\bar\\giz" ;
+    assert.result "foo" : make "foo/." ;
+    assert.result "foo" : make "foo/bar/.." ;
+    assert.result "/D:/My Documents" : make "D:\\My Documents" ;
+    assert.result "/c:/boost/tools/build/new/project.jam" : make "c:\\boost\\tools\\build\\test\\..\\new\\project.jam" ;
+
+    assert.result "foo\\bar\\giz" : native "foo/bar/giz" ;
+    assert.result "foo" : native "foo" ;
+    assert.result "D:\\My Documents\\Work" : native "/D:/My Documents/Work" ;
+
+    modules.poke path : os : UNIX ;
+
+    assert.result "foo/bar/giz" : make "foo/bar/giz" ;
+    assert.result "/sub1" : make "/sub1/." ;
+    assert.result "/sub1" : make "/sub1/sub2/.." ;    
+    assert.result "sub1" : make "sub1/." ;
+    assert.result "sub1" : make "sub1/sub2/.." ;
+    assert.result "/foo/bar" : native "/foo/bar" ;
+
+    modules.poke path : os : VMS ;
+
+    #
+    # Don't really need to poke os before these
+    #
+    assert.result "disk:" "[dir]"  "file" : split-path-VMS "disk:[dir]file" ;
+    assert.result "disk:" "[dir]"  ""     : split-path-VMS "disk:[dir]" ;
+    assert.result "disk:" ""     ""       : split-path-VMS "disk:" ;
+    assert.result "disk:" ""     "file"   : split-path-VMS "disk:file" ;
+    assert.result ""      "[dir]"  "file" : split-path-VMS "[dir]file" ;
+    assert.result ""      "[dir]"  ""     : split-path-VMS "[dir]" ;
+    assert.result ""      ""     "file"   : split-path-VMS "file" ;
+    assert.result ""      ""     ""       : split-path-VMS "" ;
+
+    #
+    # Special case: current directory
+    #
+    assert.result ""      "[]"     ""     : split-path-VMS "[]" ;
+    assert.result "disk:" "[]"     ""     : split-path-VMS "disk:[]" ;
+    assert.result ""      "[]"     "file" : split-path-VMS "[]file" ;
+    assert.result "disk:" "[]"     "file" : split-path-VMS "disk:[]file" ;
+
+    #
+    # Make portable paths
+    #
+    assert.result "/disk:" : make "disk:" ;
+    assert.result "foo/bar/giz" : make "[.foo.bar.giz]" ;
+    assert.result "foo" : make "[.foo]" ;
+    assert.result "foo" : make "[.foo.bar.-]" ;
+    assert.result ".." : make "[.-]" ;
+    assert.result ".." : make "[-]" ;
+    assert.result "." : make "[]" ;
+    assert.result "giz.h" : make "giz.h" ;
+    assert.result "foo/bar/giz.h" : make "[.foo.bar]giz.h" ;
+    assert.result "/disk:/my_docs" : make "disk:[my_docs]" ;
+    assert.result "/disk:/boost/tools/build/new/project.jam" : make "disk:[boost.tools.build.test.-.new]project.jam" ;
+
+    #
+    # Special case (adds '.' to end of file w/o extension to
+    # disambiguate from directory in portable path spec).
+    #
+    assert.result "Jamfile." : make "Jamfile" ;
+    assert.result "dir/Jamfile." : make "[.dir]Jamfile" ;
+    assert.result "/disk:/dir/Jamfile." : make "disk:[dir]Jamfile" ;
+
+    #
+    # Make native paths
+    #
+    assert.result "disk:" : native "/disk:" ;
+    assert.result "[.foo.bar.giz]" : native "foo/bar/giz" ;
+    assert.result "[.foo]" : native "foo" ;
+    assert.result "[.-]" : native ".." ;
+    assert.result "[.foo.-]" : native "foo/.." ;
+    assert.result "[]" : native "." ;
+    assert.result "disk:[my_docs.work]" : native "/disk:/my_docs/work" ;
+    assert.result "giz.h" : native "giz.h" ;
+    assert.result "disk:Jamfile." : native "/disk:Jamfile." ;
+    assert.result "disk:[my_docs.work]Jamfile." : native "/disk:/my_docs/work/Jamfile." ;
+
+    modules.poke path : os : $(save-os) ;
+
+}

Added: boost-jam/boost-build/branches/upstream/current/util/print.jam
===================================================================
--- boost-jam/boost-build/branches/upstream/current/util/print.jam	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/util/print.jam	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,465 @@
+# (C) Copyright Rene Rivera, 2002-2003.
+#
+# See accompanying license for terms and conditions of use.
+#
+
+# Utilities for generating format independent output. Using these
+# will help in generation of documentation in at minimum plain/console
+# and html.
+
+import modules ;
+import numbers ;
+import string ;
+import regex ;
+
+# The current output target. Defaults to console.
+output-target = console ;
+
+# The current output type. Defaults to plain.
+output-type = plain ;
+
+# Whitespace.
+.whitespace = [ string.whitespace ] ;
+
+# Set the target and type of output to generate. This sets both
+# the destination output and the type of docs to generate to that
+# output. The target can be either a file or "console" for echoing
+# to the console. If the type of output is not specified it defaults
+# to plain text.
+#
+rule output (
+    target # The target file or device; file or "console".
+    type ? # The type of output; "plain", or "html".
+    )
+{
+    type ?= plain ;
+    if $(output-target) != $(target)
+    {
+        output-target = $(target) ;
+        output-type = $(type) ;
+        if $(output-type) = html
+        {
+            text
+                "<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">"
+                "<html>"
+                "<head>"
+                "</head>"
+                "<body link=\"#0000ff\" vlink=\"#800080\">"
+                : true
+                : prefix ;
+            text
+                "</body>"
+                "</html>"
+                :
+                : suffix ;
+        }
+    }
+}
+
+# Generate a section with a description. The type of output can be
+# controlled by the value of the 'output-type' variable. If not set
+# it defaults to 'console' indicating immediate display to the console.
+# Other possible values are: 'html-file'.
+#
+rule section (
+    name # The name of the section.
+    description * # A number of description lines.
+    )
+{
+    if $(output-type) = plain
+    {
+        lines [ split-at-words $(name): ] ;
+        lines ;
+    }
+    else if $(output-type) = html
+    {
+        name = [ escape-html $(name) ] ;
+        text <h3>$(name)</h3> <p> ;
+    }
+    local pre = ;
+    while $(description)
+    {
+        local paragraph = ;
+        while $(description) && [ string.is-whitespace $(description[1]) ] { description = $(description[2-]) ; }
+        if $(pre)
+        {
+            while $(description) && (
+                $(pre) = " $(description[1])" ||
+                ( $(pre) < [ string.chars [ MATCH "^([$(.whitespace)]*)" : " $(description[1])" ] ] )
+                )
+                { paragraph += $(description[1]) ; description = $(description[2-]) ; }
+            while [ string.is-whitespace $(paragraph[-1]) ] { paragraph = $(paragraph[1--2]) ; }
+            pre = ;
+            if $(output-type) = plain
+            {
+                lines $(paragraph) "" : "  " "  " ;
+            }
+            else if $(output-type) = html
+            {
+                text <blockquote> ;
+                lines $(paragraph) ;
+                text </blockquote> ;
+            }
+        }
+        else
+        {
+            while $(description) && ! [ string.is-whitespace $(description[1]) ]
+                { paragraph += $(description[1]) ; description = $(description[2-]) ; }
+            if $(paragraph[1]) = :: && ! $(paragraph[2])
+            {
+                pre = " " ;
+            }
+            if $(paragraph[1]) = ::
+            {
+                if $(output-type) = plain
+                {
+                    lines $(paragraph[2-]) "" : "  " "  " ;
+                    lines ;
+                }
+                else if $(output-type) = html
+                {
+                    text <blockquote> ;
+                    lines $(paragraph[2-]) ;
+                    text </blockquote> ;
+                }
+            }
+            else
+            {
+                local p = [ MATCH "(.*)(::)$" : $(paragraph[-1]) ] ;
+                local pws = [ MATCH "([ 	]*)$" : $(p[1]) ] ;
+                p = [ MATCH "(.*)($(pws))($(p[2]))$" :  $(paragraph[-1]) ] ;
+                if $(p[3]) = ::
+                {
+                    pre = [ string.chars [ MATCH "^([$(.whitespace)]*)" : " $(p[1])" ] ] ;
+                    if ! $(p[2]) || $(p[2]) = "" { paragraph = $(paragraph[1--2]) $(p[1]): ; }
+                    else { paragraph = $(paragraph[1--2]) $(p[1]) ; }
+                    if $(output-type) = plain
+                    {
+                        lines [ split-at-words " " $(paragraph) ] : "  " "  " ;
+                        lines ;
+                    }
+                    else if $(output-type) = html
+                    {
+                        text </p> <p> [ escape-html $(paragraph) ] ;
+                    }
+                }
+                else
+                {
+                    if $(output-type) = plain
+                    {
+                        lines [ split-at-words " " $(paragraph) ] : "  " "  " ;
+                        lines ;
+                    }
+                    else if $(output-type) = html
+                    {
+                        text </p> <p> [ escape-html $(paragraph) ] ;
+                    }
+                }
+            }
+        }
+    }
+    if $(output-type) = html
+    {
+        text </p> ;
+    }
+}
+
+# Generate the start of a list of items. The type of output can be
+# controlled by the value of the 'output-type' variable. If not set
+# it defaults to 'console' indicating immediate display to the console.
+# Other possible values are: 'html-file'.
+#
+rule list-start ( )
+{
+    if $(output-type) = plain
+    {
+    }
+    else if $(output-type) = html
+    {
+        text <ul> ;
+    }
+}
+
+# Generate an item in a list. The type of output can be
+# controlled by the value of the 'output-type' variable. If not set
+# it defaults to 'console' indicating immediate display to the console.
+# Other possible values are: 'html-file'.
+#
+rule list-item (
+    item + # The item to list.
+    )
+{
+    if $(output-type) = plain
+    {
+        lines [ split-at-words "*" $(item) ] : "  " ;
+    }
+    else if $(output-type) = html
+    {
+        text <li> [ escape-html $(item) ] </li> ;
+    }
+}
+
+# Generate the end of a list of items. The type of output can be
+# controlled by the value of the 'output-type' variable. If not set
+# it defaults to 'console' indicating immediate display to the console.
+# Other possible values are: 'html-file'.
+#
+rule list-end ( )
+{
+    if $(output-type) = plain
+    {
+        lines ;
+    }
+    else if $(output-type) = html
+    {
+        text </ul> ;
+    }
+}
+
+# Split the given text into separate lines, word-wrapping to a margin.
+# The default margin is 78 characters.
+#
+rule split-at-words (
+    text + # The text to split.
+    : margin ? # An optional margin, default is 78.
+    )
+{
+    local lines = ;
+    text = [ string.words $(text:J=" ") ] ;
+    text = $(text:J=" ") ;
+    margin ?= 78 ;
+    local char-match-1 = ".?" ;
+    local char-match = "" ;
+    while $(margin) != 0
+    {
+        char-match = $(char-match)$(char-match-1) ;
+        margin = [ numbers.decrement $(margin) ] ;
+    }
+    while $(text)
+    {
+        local s = "" ;
+        local t = "" ;
+        # divide s into the first X characters and the rest
+        s = [ MATCH "^($(char-match))(.*)" : $(text) ] ;
+        
+        if $(s[2])
+        {
+            # split the first half at a space
+            t = [ MATCH "^(.*)[\\ ]([^\\ ]*)$" : $(s[1]) ] ;
+        }
+        else
+        {
+            t = $(s) ;
+        }
+        
+        if ! $(t[2])
+        {
+            t += "" ;
+        }
+        
+        text = $(t[2])$(s[2]) ;
+        lines += $(t[1]) ;
+    }
+    return $(lines) ;
+}
+
+# Generate a set of fixed lines. Each single item passed in is
+# output on a separate line. For console this just echos each line,
+# but for html this will split them with <br>.
+#
+rule lines (
+    text * # The lines of text.
+    : indent ? # Optional indentation prepended to each line after the first one.
+    outdent ? # Optional indentation to prepend to the first line.
+    )
+{
+    text ?= "" ;
+    indent ?= "" ;
+    outdent ?= "" ;
+    if $(output-type) = plain
+    {
+        text $(outdent)$(text[1]) $(indent)$(text[2-]) ;
+    }
+    else if $(output-type) = html
+    {
+        local indent-chars = [ string.chars $(indent) ] ;
+        indent = "" ;
+        for local c in $(indent-chars)
+        {
+            if $(c) = " " { c = &nbsp; ; }
+            else if $(c) = "	" { c = &nbsp;&nbsp;&nbsp;&nbsp; ; }
+            indent = $(indent)$(c) ;
+        }
+        local html-text = [ escape-html $(text) : &nbsp; ] ;
+        text $(html-text[1])<br> $(indent)$(html-text[2-])<br> ;
+    }
+}
+
+# Output text directly to the current target. When doing output
+# to a file, one can indicate if the text should be output to
+# "prefix" it, as the "body" (default), or "suffix" of the file. This is
+# independant of the actual execution order of the text rule. This rule
+# invokes a singular action, one action only once, which does the
+# build of the file. Therefore actions on the target outside of this
+# rule will happen entirely before and/or after all output using this rule.
+#
+rule text (
+    strings * # The strings of text to output.
+    : overwrite ? # true to overwrite the output (if it is a file)
+    : prefix-body-suffix ? # Indication to output prefix, body, or suffix (for a file).
+    )
+{
+    prefix-body-suffix ?= body ;
+    if $(output-target) = console
+    {
+        if ! $(strings)
+        {
+            ECHO ;
+        }
+        else
+        {
+            while $(strings)
+            {
+                ECHO $(strings[1]) ;
+                strings = $(strings[2-]) ;
+            }
+        }
+    }
+    # We ignore empty output because the Windows ECHO command is
+    # braindamaged. It doesn't have any facility for echoing a blank line.
+    else if $(output-target)
+    {
+        if ! $($(output-target).did-action)
+        {
+            $(output-target).did-action = yes ;
+            _ on $(output-target) = " " ;
+            nl on $(output-target) = "
+" ;
+            text-redirect-0 on $(output-target) = ">>" ;
+            text-redirect-n on $(output-target) = ">>" ;
+            text-front on $(output-target) = ;
+            text-prefix on $(output-target) = ;
+            text-body on $(output-target) = ;
+            text-suffix on $(output-target) = ;
+            text-action $(output-target) ;
+            text-front-section.$(soutput-target) = ;
+        }
+        if $(overwrite)
+        {
+            text-redirect-0 on $(output-target) = ">" ;
+        }
+        if ! $(text-front-section.$(output-target))
+        {
+            text-front on $(output-target) = [ echo-cmd $(strings[1]) ] ;
+            text-front-section.$(output-target) = $(prefix-body-suffix) ;
+            strings = $(strings[2-]) ;
+        }
+        if $(strings)
+        {
+            if ( $(prefix-body-suffix) = prefix &&
+                    $(text-front-section.$(output-target)) != prefix ) ||
+                ( $(prefix-body-suffix) = body &&
+                $(text-front-section.$(output-target)) = suffix )
+            {
+                text-$(text-front-section.$(output-target)) on $(output-target) =
+                    [ on $(output-target) return $(text-front) ]
+                    [ on $(output-target) return $(text-$(text-front-section.$(output-target))) ] ;
+                text-front on $(output-target) = [ echo-cmd $(strings[1]) ] ;
+                text-front-section.$(output-target) = $(prefix-body-suffix) ;
+                strings = $(strings[2-]) ;
+            }
+            while $(strings)
+            {
+                text-$(prefix-body-suffix) on $(output-target) += [ echo-cmd $(strings[1]) ] ;
+                strings = $(strings[2-]) ;
+            }
+        }
+    }
+}
+
+# Outputs the text to the current targets, after word-wrapping it.
+rule wrapped-text ( text + )
+{
+    local lines = [ split-at-words $(text) ] ;
+    text $(lines) ;
+}
+
+# Escapes text into html/xml printable equivalents.
+# Does not know about tags and therefore tags fed into
+# this will also be escaped. Currently escapes space, "<", ">", and "&".
+#
+rule escape-html (
+    text + # The text to escape.
+    : space ? # What to replace spaces with, defaults to " ".
+    )
+{
+    local html-text = ;
+    while $(text)
+    {
+        local html = $(text[1]) ;
+        text = $(text[2-]) ;
+        html = [ regex.replace $(html) "&" "&amp;" ] ;
+        html = [ regex.replace $(html) "<" "&lt;" ] ;
+        html = [ regex.replace $(html) ">" "&gt;" ] ;
+        if $(space)
+        {
+            html = [ regex.replace $(html) " " "$(space)" ] ;
+        }
+        html-text += $(html) ;
+    }
+    return $(html-text) ;
+}
+
+# Outputs the text strings collected by the text rule to the output
+# file.
+#
+actions quietly text-action
+{
+$(text-front)$(_)$(text-redirect-0)$(_)"$(<)"
+$(text-prefix)$(_)$(text-redirect-n)$(_)"$(<)"$(nl)
+$(text-body)$(_)$(text-redirect-n)$(_)"$(<)"$(nl)
+$(text-suffix)$(_)$(text-redirect-n)$(_)"$(<)"$(nl)
+}
+
+if [ modules.peek : NT ]
+{
+    rule echo-cmd ( string ? )
+    {
+        if $(string) || $(string) != ""
+        {
+            local escaped = [ regex.escape $(string) : "&|()<>^" : "^" ] ;
+            return "echo $(escaped)" ;
+        }
+        else
+        {
+            return "echo." ;
+        }
+    }
+}
+else
+{
+    rule echo-cmd ( string ? )
+    {
+        if $(string) || $(string) != ""
+        {
+            local escaped = [ regex.escape $(string) : "\\\"" : "\\" ] ;
+            return "echo \"$(escaped)\"" ;
+        }
+        else
+        {
+            return "echo" ;
+        }
+    }
+}
+
+local rule __test__ ( )
+{
+    import assert ;
+    
+    assert.result one two three : split-at-words one two three : 5 ;
+    assert.result "one two" three : split-at-words one two three : 8 ;
+    assert.result "one two" three : split-at-words one two three : 9 ;
+    assert.result "one two three" : split-at-words one two three ;
+    assert.result "one&nbsp;two&nbsp;three" "&amp;&lt;&gt;" :
+        escape-html "one two three" "&<>" ;
+}

Added: boost-jam/boost-build/branches/upstream/current/util/regex.jam
===================================================================
--- boost-jam/boost-build/branches/upstream/current/util/regex.jam	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/util/regex.jam	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,172 @@
+#  (C) Copyright David Abrahams 2001. Permission to copy, use, modify, sell and
+#  distribute this software is granted provided this copyright notice appears in
+#  all copies. This software is provided "as is" without express or implied
+#  warranty, and with no claim as to its suitability for any purpose.
+
+#
+#   Returns a list of the following substrings:
+#   1) from beginning till the first occurence of 'separator' or till the end,
+#   2) between each occurence of 'separator' and the next occurence,
+#   3) from the last occurence of 'separator' till the end.
+#   If no separator is present, the result will contain only one element.
+#
+rule split ( string separator )
+{
+    local result ;
+    local s = $(string) ;
+
+    # Break pieaces off 's' until it has no separators left.
+    local match = 1 ;
+    while $(match)
+    {
+        match = [ MATCH ^(.*)($(separator))(.*) : $(s) ] ;
+        if $(match) {
+            match += "" ; # in case 3rd item was empty - works around MATCH bug
+            result = $(match[3]) $(result) ;
+            s = $(match[1]) ;
+        }
+    }
+    # Combine the remaining part at the beginning, which does not have
+    # separators, with the pieces broken off.
+    # Note that rule's signature does not allow initial s to be empty.
+    return $(s) $(result) ;
+}
+
+# Match string against pattern, and return the elements indicated by
+# indices.
+rule match ( pattern : string : indices * )
+{
+    indices ?= 1 2 3 4 5 6 7 8 9 ;
+    local x = [ MATCH $(pattern) : $(string) ] ;
+    return $(x[$(indices)]) ;
+}
+
+# Matches all elements of 'list' agains the 'pattern' 
+# and returns a list of the elements indicated by indices of 
+# all successfull matches. If 'indices' is omitted returns
+# a list of first paranthethised groups of all successfull
+# matches.
+#
+rule transform ( list * : pattern : indices * )
+{
+    indices ?= 1 ;
+    local result ;
+    for local e in $(list)
+    {
+        local m = [ MATCH $(pattern) : $(e) ] ;
+        if $(m)
+        {
+            result += $(m[$(indices)]) ;
+        }        
+    }
+    return $(result) ;
+}
+
+# Commented out because of 'indices' parameter of 'transform' rule.
+#
+#NATIVE_RULE regex : transform ;
+
+# Escapes all of the characters in symbols using the escape symbol
+# escape-symbol for the given string, and returns the escaped string
+rule escape ( string : symbols : escape-symbol )
+{
+  local result = "" ;
+  local m = 1 ;
+  while $(m)
+  {
+    m = [ MATCH ^([^$(symbols)]*)([$(symbols)])(.*) : $(string) ] ;
+    if $(m)
+    {
+      m += "" ;  # Supposedly a bug fix; borrowed from regex.split
+      result = "$(result)$(m[1])$(escape-symbol)$(m[2])" ;
+      string = $(m[3]) ;
+    }
+  }
+  string ?= "" ;
+  result = "$(result)$(string)" ;
+  return $(result) ;
+}
+
+# Replaces occurances of a match string in a given string. Returns the
+# new string. The match string can be a regex expression.
+#
+rule replace (
+    string # The string to modify.
+    match # The characters to replace.
+    replacement # The string to replace with.
+    )
+{
+    local result = "" ;
+    local parts = 1 ;
+    while $(parts)
+    {
+        parts = [ MATCH ^(.*)($(match))(.*) : $(string) ] ;
+        if $(parts)
+        {
+            parts += "" ;
+            result = "$(replacement)$(parts[3])$(result)" ;
+            string = $(parts[1]) ;
+        }
+    }
+    string ?= "" ;
+    result = "$(string)$(result)" ;
+    return $(result) ;
+}
+
+# Replaces occurances of a match string in a given list of strings. 
+# Returns the list of new strings. The match string can be a regex 
+# expression.
+#
+# list        - the list of strings to modify.
+# match       - the search expression.
+# replacement - the string to replace with.
+#
+rule replace-list ( list * : match : replacement )
+{
+    local result ;
+    for local e in $(list)
+    {
+        result += [ replace $(e) $(match) $(replacement) ] ;
+    }
+    return $(result) ;
+}
+
+rule __test__ ( )
+{
+    import assert ;
+
+    assert.result a b c : split "a/b/c" / ;
+    assert.result "" a b c : split "/a/b/c" / ;
+    assert.result "" "" a b c : split "//a/b/c" / ;
+    assert.result "" a "" b c : split "/a//b/c" / ;
+    assert.result "" a "" b c "" : split "/a//b/c/" / ;
+    assert.result "" a "" b c "" "" : split "/a//b/c//" / ;
+    
+    assert.result a c b d
+      : match (.)(.)(.)(.) : abcd : 1 3 2 4 ;
+    
+    assert.result a b c d
+      : match (.)(.)(.)(.) : abcd ;
+    
+    assert.result ababab cddc
+      : match ((ab)*)([cd]+) : abababcddc : 1 3 ;
+
+    assert.result a.h c.h 
+      : transform <a.h> \"b.h\" <c.h> :  <(.*)> ;
+
+    assert.result a.h "" b.h c.h 
+      : transform <a.h> \"b.h\" <c.h> :  <([^>]*)>|\"([^\"]*)\" : 1 2 ;
+
+    assert.result "^<?xml version=\"1.0\"^>"
+      : escape "<?xml version=\"1.0\">" : "&|()<>^" : "^" ;
+    
+    assert.result "<?xml version=\\\"1.0\\\">"
+      : escape "<?xml version=\"1.0\">" : "\\\"" : "\\" ;
+    
+    assert.result "string&nbsp;string&nbsp;" : replace "string string " " " "&nbsp;" ;
+    assert.result "&nbsp;string&nbsp;string" : replace " string string" " " "&nbsp;" ;
+    assert.result "string&nbsp;&nbsp;string" : replace "string  string" " " "&nbsp;" ;
+    assert.result "-" : replace "&" "&" "-" ;
+
+    assert.result "-" "a-b" : replace-list "&" "a&b" : "&" : "-" ;
+}

Added: boost-jam/boost-build/branches/upstream/current/util/sequence.jam
===================================================================
--- boost-jam/boost-build/branches/upstream/current/util/sequence.jam	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/util/sequence.jam	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,319 @@
+#  (C) Copyright David Abrahams 2002. Permission to copy, use, modify, sell and
+#  distribute this software is granted provided this copyright notice appears in
+#  all copies. This software is provided "as is" without express or implied
+#  warranty, and with no claim as to its suitability for any purpose.
+
+import assert ;
+import numbers ; 
+import modules ;
+
+# Note that algorithms in this module execute largely in the caller's
+# module namespace, so that local rules can be used as function
+# objects. Also note that most predicates can be multi-element
+# lists. In that case, all but the first element are prepended to the
+# first argument which is passed to the rule named by the first
+# element.
+
+# Return the elements e of $(sequence) for which [ $(predicate) e ]
+# has a non-null value.
+rule filter ( predicate + : sequence * )
+{
+    local caller = [ CALLER_MODULE ] ;
+    local result ;
+
+    for local e in $(sequence)
+    {
+        if [ modules.call-in $(caller) : $(predicate) $(e) ]
+        {
+            result += $(e) ;
+        }
+    }
+    return $(result) ;
+}
+
+# return a new sequence consisting of [ $(function) $(e) ] for each
+# element e of $(sequence).
+rule transform ( function + : sequence * )
+{
+    local caller = [ CALLER_MODULE ] ;
+    local result ;
+
+    for local e in $(sequence)
+    {
+        result += [ modules.call-in $(caller) : $(function) $(e) ] ;
+    }
+    return $(result) ;
+}
+
+
+rule less ( a b )
+{
+    if $(a) < $(b)
+    {
+        return true ;
+    }
+}
+
+# insertion-sort s using the BinaryPredicate ordered.
+rule insertion-sort ( s * : ordered * )
+{
+    if ! $(ordered)
+    {
+        return [ SORT $(s) ] ;
+    }
+    else 
+    {           
+        local caller = [ CALLER_MODULE ] ;
+        ordered ?= sequence.less ;
+        local result = $(s[1]) ;
+        if $(ordered) = sequence.less
+        {
+            local head tail ;
+            for local x in $(s[2-])
+            {
+                head = ;
+                tail = $(result) ;
+                while $(tail) && ( $(tail[1]) < $(x) )
+                {
+                    head += $(tail[1]) ;
+                    tail = $(tail[2-]) ;
+                }
+                result = $(head) $(x) $(tail) ;
+            }
+        }
+        else
+        {
+            for local x in $(s[2-])
+            {
+                local head tail ;
+                tail = $(result) ;
+                while $(tail) && [ modules.call-in $(caller) : $(ordered) $(tail[1]) $(x) ]
+                {
+                    head += $(tail[1]) ;
+                    tail = $(tail[2-]) ;
+                }
+                result = $(head) $(x) $(tail) ;
+            }
+        }
+        
+        return $(result) ;
+    }    
+}
+
+# merge two ordered sequences using the BinaryPredicate ordered.
+rule merge ( s1 * : s2 * : ordered * )
+{
+    ordered ?= sequence.less ;
+    local result__ ;
+    local caller = [ CALLER_MODULE ] ;
+
+    while $(s1) && $(s2) {
+        if [ modules.call-in $(caller) : $(ordered) $(s1[1]) $(s2[1]) ]
+        {
+            result__ += $(s1[1]) ;
+            s1 = $(s1[2-]) ;
+        }
+        else if [ modules.call-in $(caller) : $(ordered) $(s2[1]) $(s1[1]) ]
+        {
+            result__ += $(s2[1]) ;
+            s2 = $(s2[2-]) ;
+        }
+        else 
+        {           
+            s2 = $(s2[2-]) ;
+        }
+        
+    }
+    result__ += $(s1) ;
+    result__ += $(s2) ;
+
+    return $(result__) ;
+}
+
+# join the elements of s into one long string. If joint is supplied,
+# it is used as a separator.
+rule join ( s * : joint ? )
+{
+    joint ?= "" ;
+    return $(s:J=$(joint)) ;
+}
+
+# Find the length of any sequence in log(N) time.
+rule length ( s * )
+{
+    local length = "" ;
+    local zeros p10 d z ; # declared once for speed
+
+    # Find the power of 10 that is just less than length(s)
+    zeros = "" ;
+    p10 = 1 ;
+    while $(s[$(p10)0])
+    {
+        p10 = $(p10)0 ;
+        zeros = $(zeros[1])0 $(zeros) ;
+    }
+
+    # zeros is a list of the form  ... 000 00 0 ""
+    for z in $(zeros) # for each digit in the result
+    {
+        # Find the next digit
+        d = 0 1 2 3 4 5 6 7 8 9 ;
+        while $(s[$(d[2])$(z)])
+        {
+            d = $(d[2-]) ;
+        }
+
+        # append it to the result
+        length = $(length)$(d[1]) ;
+
+        # Explanation: $(d[1])$(z) the largest number x of the form
+        # n000..., where n is a digit, such that x <= length(s). Here
+        # we're deleting x elements from the list. Since $(s[n]-)
+        # removes n - 1 elements from the list, we chop an additional
+        # one off the end.
+        s = $(s[$(d[1])$(z)--2]) ;
+    }
+    return $(length) ;
+}
+
+rule unique ( list * )
+{
+    local result ;
+    for local f in $(list)
+    {
+        if ! $(f) in $(result)
+        {
+            result += $(f) ;
+        }
+    }
+    return $(result) ;
+}
+
+# Returns the maximum number in 'elements'. Uses 'ordered' for comparisons,
+# or 'numbers.less' is none is provided.
+rule max-element ( elements + : ordered ? )
+{
+    ordered ?= numbers.less ;
+
+    local max = $(elements[1]) ;
+    for local e in $(elements[2-]) 
+    {
+        if [ $(ordered) $(max) $(e) ] 
+        {
+            max = $(e) ;
+        }
+    }
+    return $(max) ;           
+}
+
+# Returns all of 'elements' for which corresponding element in parallel
+# list 'rank' is equal to the maximum value in 'rank'.
+rule select-highest-ranked ( elements * : ranks * )
+{
+    if $(elements)
+    {        
+        local max-rank = [ max-element $(ranks) ] ;
+        local result ;
+        while $(elements) 
+        {
+            if $(ranks[1]) = $(max-rank)
+            {
+                result += $(elements[1]) ;
+            }
+            elements = $(elements[2-]) ;
+            ranks = $(ranks[2-]) ;
+        }
+        return $(result) ;
+    }    
+}
+NATIVE_RULE sequence : select-highest-ranked ;
+
+
+local rule __test__ ( )
+{
+    # use a unique module so we can test the use of local rules.
+    module sequence.__test__
+    {
+        import assert ;
+        import sequence ;
+        
+        local rule is-even ( n )
+        {
+            if $(n) in 0 2 4 6 8
+            {
+                return true ;
+            }
+        }
+
+        assert.result 4 6 4 2 8
+          : sequence.filter is-even : 1 4 6 3 4 7 2 3 8 ;
+
+        # test that argument binding works
+        local rule is-equal-test ( x y )
+        {
+            if $(x) = $(y)
+            {
+                return true ;
+            }
+        }
+
+        assert.result 3 3 3 : sequence.filter is-equal-test 3 : 1 2 3 4 3 5 3 5 7 ;
+
+        local rule append-x ( n )
+        {
+            return $(n)x ;
+        }
+
+        assert.result 1x 2x 3x : sequence.transform append-x : 1 2 3 ;
+
+        local rule repeat2 ( x )
+        {
+            return $(x) $(x) ;
+        }
+
+        assert.result 1 1 2 2 3 3 : sequence.transform repeat2 : 1 2 3 ;
+
+        local rule test-greater ( a b )
+        {
+            if $(a) > $(b)
+            {
+                return true ;
+            }
+        }
+        assert.result 1 2 3 4 5 6 7 8 9 : sequence.insertion-sort 9 6 5 3 8 7 1 2 4 ;
+        assert.result 9 8 7 6 5 4 3 2 1 : sequence.insertion-sort 9 6 5 3 8 7 1 2 4 : test-greater ;
+        assert.result 1 2 3 4 5 6 :  sequence.merge 1 3 5 : 2 4 6 ;
+        assert.result 6 5 4 3 2 1 :  sequence.merge 5 3 1 : 6 4 2 : test-greater ;
+        assert.result 1 2 3 : sequence.merge 1 2 3 : ;
+        assert.result 1 : sequence.merge 1 : 1 ;
+
+        assert.result foo-bar-baz : sequence.join foo bar baz : - ;
+        assert.result substandard : sequence.join sub stan dard ;
+        assert.result 3.0.1 : sequence.join 3.0.1 : - ;
+
+        assert.result 0 : sequence.length ;
+        assert.result 3 : sequence.length a b c ;
+        assert.result 17 : sequence.length 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 ;
+
+        assert.result 1 : sequence.length a ;
+        assert.result 10 : sequence.length a b c d e f g h i j ;
+        assert.result 11 : sequence.length a b c d e f g h i j k ;
+        assert.result 12 : sequence.length a b c d e f g h i j k l ;
+
+        local p2 = x ;
+        for local i in 1 2 3 4 5 6 7 8
+        {
+          p2 = $(p2) $(p2) ;
+        }
+        assert.result 256 : sequence.length $(p2) ;
+
+        assert.result 1 2 3 4 5
+          : sequence.unique 1 2 3 2 4 3 3 5 5 5 ;
+                
+        assert.result 5 
+          : sequence.max-element 1 3 5 0 4 ;
+        
+        assert.result e-3 h-3 
+          : sequence.select-highest-ranked e-1 e-3 h-3 m-2 : 1 3 3 2 ;
+    }
+}

Added: boost-jam/boost-build/branches/upstream/current/util/set.jam
===================================================================
--- boost-jam/boost-build/branches/upstream/current/util/set.jam	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/util/set.jam	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,62 @@
+#  (C) Copyright David Abrahams 2001. Permission to copy, use, modify, sell and
+#  distribute this software is granted provided this copyright notice appears in
+#  all copies. This software is provided "as is" without express or implied
+#  warranty, and with no claim as to its suitability for any purpose.
+
+# difference
+# returns the elements of B that are not in A
+rule difference ( B * : A * )
+{
+    local result = ;
+    local element ;
+    for element in $(B)
+    {
+        if ! ( $(element) in $(A) )
+        {
+            result += $(element) ;
+        }
+    }
+    return $(result) ;
+}
+
+NATIVE_RULE set : difference ;
+
+# intersection set1 : set2
+#
+# Removes from set1 any items which don't appear in set2 and returns the result.
+rule intersection ( set1 * : set2 * )
+{
+    local result ;
+    for local v in $(set1)
+    {
+        if $(v) in $(set2)
+        {
+            result += $(v) ;
+        }
+    }
+    return $(result) ;
+}
+
+rule equal ( set1 * : set2 * )
+{
+    if $(set1) in $(set2) && ( $(set2) in $(set1) )
+    {
+        return true ;
+    }
+}
+
+rule __test__ ( )
+{
+    import assert ;
+    
+    assert.result 0 1 4 6 8 9
+        : difference 0 1 2 3 4 5 6 7 8 9 : 2 3 5 7 ;
+        
+    assert.result 2 5 7 : intersection 0 1 2 4 5 6 7 8 9 : 2 3 5 7 ;
+    
+    assert.true equal 1 1 2 3 : 3 2 2 1 ;
+    
+    assert.false equal 2 3 : 3 2 2 1 ;
+}
+
+

Added: boost-jam/boost-build/branches/upstream/current/util/string.jam
===================================================================
--- boost-jam/boost-build/branches/upstream/current/util/string.jam	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/util/string.jam	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,122 @@
+# (C) Copyright David Abrahams, 2002.
+# (C) Copyright Rene Rivera, 2003.
+#
+# See accompanying license for terms and conditions of use.
+#
+
+import regex ;
+
+# Characters considered whitespace, as a list.
+.whitespace-chars = " " "	" "
+" ;
+
+# Characters considered whitespace, as a single string.
+.whitespace = $(.whitespace-chars:J="") ;
+
+# Returns the canonical set of whitespace characters, as a list.
+#
+rule whitespace-chars ( )
+{
+    return $(.whitespace-chars) ;
+}
+
+# Returns the canonical set of whitespace characters, as a single string.
+#
+rule whitespace ( )
+{
+    return $(.whitespace) ;
+}
+
+# Splits the given string into a list of strings composed
+# of each character of the string in sequence.
+#
+rule chars (
+    string # The string to split.
+    )
+{
+    local result ;
+    while $(string)
+    {
+        local s = [ MATCH (.?)(.?)(.?)(.?)(.?)(.?)(.?)(.?)(.*) : $(string) ] ;
+        string = $(s[9]) ;
+        result += $(s[1-8]) ;
+    }
+    
+    # trim off empty strings
+    while $(result[1]) && ! $(result[-1])
+    {
+        result = $(result[1--2]) ;
+    }
+    
+    return $(result) ;
+}
+
+# Concatenates the given strings, inserting the given separator
+# between each string.
+#
+rule join (
+    strings * # The strings to join.
+    : separator ? # The optional separator.
+    )
+{
+    separator ?= "" ;
+    return $(strings:J=$(separator)) ;
+}
+
+# Split a string into whitespace separated words.
+#
+rule words (
+    string # The string to split.
+    : whitespace * # Optional, characters to consider as whitespace.
+    )
+{
+    whitespace = $(whitespace:J="") ;
+    whitespace ?= $(.whitespace) ;
+    local w = ;
+    while $(string)
+    {
+        string = [ MATCH "^[$(whitespace)]*([^$(whitespace)]*)(.*)" : $(string) ] ;
+        if $(string[1]) && $(string[1]) != ""
+        {
+            w += $(string[1]) ;
+        }
+        string = $(string[2]) ;
+    }
+    return $(w) ;
+}
+
+# Check that the given string is composed entirely of whitespace.
+#
+rule is-whitespace (
+    string ? # The string to test.
+    )
+{
+    if ! $(string) { return true ; }
+    else if $(string) = "" { return true ; }
+    else if [ MATCH "^([$(.whitespace)]+)$" : $(string) ] { return true ; }
+    else { return ; }
+}
+
+rule __test__ ( )
+{
+    import assert ;
+    assert.result a b c : chars abc ;
+    
+    # check boundary cases
+    assert.result a : chars a ;
+    assert.result : chars "" ;
+    assert.result a b c d e f g h : chars abcdefgh ;
+    assert.result a b c d e f g h i : chars abcdefghi ;
+    assert.result a b c d e f g h i j : chars abcdefghij ;
+    assert.result a b c d e f g h i j k : chars abcdefghijk ;
+    
+    assert.result a//b/c/d : join a "" b c d : / ;
+    assert.result abcd : join  a "" b c d ;
+    
+    assert.result a b c : words "a b	c" ;
+    
+    assert.true is-whitespace "     	" ;
+    assert.false is-whitespace "  a b c	" ;
+    assert.true is-whitespace "" ;
+    assert.true is-whitespace ;
+}

Added: boost-jam/boost-build/branches/upstream/current/util/utility.jam
===================================================================
--- boost-jam/boost-build/branches/upstream/current/util/utility.jam	2005-12-22 13:14:52 UTC (rev 13934)
+++ boost-jam/boost-build/branches/upstream/current/util/utility.jam	2005-12-22 14:00:13 UTC (rev 13935)
@@ -0,0 +1,141 @@
+#  (C) Copyright David Abrahams 2001. Permission to copy, use, modify, sell and
+#  distribute this software is granted provided this copyright notice appears in
+#  all copies. This software is provided "as is" without express or implied
+#  warranty, and with no claim as to its suitability for any purpose.
+
+import "class" : is-instance ;
+import errors ;
+
+rule ungrist ( names * )
+{
+    local result ;
+    for local name in $(names)
+    {
+        local stripped = [ MATCH ^<(.*)>$ : $(name) ] ;
+        if ! $(stripped)
+        {
+            errors.error "in ungrist" $(names) : $(name) is not of the form <.*> ;
+        }
+        result += $(stripped) ;
+    }
+    return $(result) ;
+}
+
+# Return the file of the caller of the rule that called caller-file.
+rule caller-file ( )
+{
+    local bt = [ BACKTRACE ] ;
+    return $(bt[9]) ;
+}
+
+# Returns the textual representation of argument. If it is a class
+# instance, class its 'str' method. Otherwise, returns the argument.
+rule str ( value )
+{
+    if [ is-instance $(value) ] 
+    {
+        return [ $(value).str ] ;
+    }
+    else
+    {
+        return $(value) ;
+    }            
+}
+
+# Tests if 'a' is equal to 'b'. If 'a' is a class instance,
+# calls its 'equal' method. Uses ordinary jam's comparison otherwise.
+rule equal ( a b )
+{
+    if [ is-instance $(a) ] 
+    {
+        return [ $(a).equal $(b) ] ;
+    }
+    else
+    {
+        if $(a) = $(b) 
+        {
+            return true ;
+        }
+    }
+}
+
+# Tests if 'a' is less than 'b'. If 'a' is a class instance, 
+# calls its 'less' method. Uses ordinary jam's comparison otherwise.
+rule less ( a b )
+{
+    if [ is-instance $(a) ]
+    {
+        return [ $(a).less $(b) ] ;
+    }
+    else
+    {
+        if $(a) < $(b)
+        {
+            return true ;
+        }
+    }
+}
+
+# For all elements of 'list' which do not already have 'suffix',
+# add 'suffix'.
+rule apply-default-suffix ( suffix : list * )
+{
+    local result ;
+    for local i in $(list)
+    {
+        if $(i:S) = $(suffix)
+        {
+            result += $(i) ;
+        }
+        else
+        {
+            result += $(i)$(suffix) ;
+        }        
+    }
+    return $(result) ;    
+}
+
+
+local rule __test__ ( )
+{
+    import assert ;
+    import "class" : new ;
+    assert.result foo bar : ungrist <foo> <bar> ;
+
+    assert.result 123 : str 123 ;
+
+    class test-class__ 
+    {
+        rule __init__ ( )
+        {            
+        }
+        
+        rule str ( )
+        {
+            return "str-test-class" ;
+        }
+
+        rule less ( a )
+        {
+            return "yes, of course!" ;
+        }
+
+        rule equal ( a )
+        {
+            return "not sure" ;
+        }
+    }
+
+    assert.result "str-test-class" : str [ new test-class__ ] ;
+    assert.true less 1 2 ;
+    assert.false less 2 1 ;
+    assert.result "yes, of course!" : less [ new test-class__ ] 1 ;
+    assert.true equal 1 1 ;
+    assert.false equal 1 2 ;
+    assert.result "not sure" : equal [ new test-class__ ] 1 ;
+    
+    assert.result foo.lib foo.lib : apply-default-suffix .lib : foo.lib foo.lib ;
+}
+
+
+




More information about the pkg-boost-commits mailing list