Boost logo

Boost-Commit :

From: bdawes_at_[hidden]
Date: 2008-07-15 09:39:03


Author: bemandawes
Date: 2008-07-15 09:38:59 EDT (Tue, 15 Jul 2008)
New Revision: 47441
URL: http://svn.boost.org/trac/boost/changeset/47441

Log:
Merge trunk
Added:
   branches/release/tools/jam/test/builtin_normalize_path.jam
      - copied unchanged from r47440, /trunk/tools/jam/test/builtin_normalize_path.jam
Properties modified:
   branches/release/tools/jam/src/ (props changed)
   branches/release/tools/jam/src/Jambase (contents, props changed)
   branches/release/tools/jam/src/boehm_gc/config.sub (props changed)
   branches/release/tools/jam/src/boost-jam.spec (contents, props changed)
   branches/release/tools/jam/src/build_vms.com (props changed)
   branches/release/tools/jam/src/debian/changelog (props changed)
   branches/release/tools/jam/src/debian/control (props changed)
   branches/release/tools/jam/src/debian/copyright (props changed)
   branches/release/tools/jam/src/debian/jam.man.sgml (props changed)
   branches/release/tools/jam/src/debian/rules (props changed)
   branches/release/tools/jam/src/jamgram.y (props changed)
   branches/release/tools/jam/src/jamgram.yy (props changed)
Text files modified:
   branches/release/tools/jam/doc/bjam.qbk | 12
   branches/release/tools/jam/src/Jambase | 277 +++++++++++------------
   branches/release/tools/jam/src/boost-jam.spec | 128 +++++-----
   branches/release/tools/jam/src/build.bat | 5
   branches/release/tools/jam/src/build.jam | 2
   branches/release/tools/jam/src/builtins.c | 469 ++++++++++++++++++++++++---------------
   branches/release/tools/jam/src/compile.c | 16
   branches/release/tools/jam/src/execnt.c | 61 ++--
   branches/release/tools/jam/src/execunix.c | 20 +
   branches/release/tools/jam/src/expand.c | 7
   branches/release/tools/jam/src/filent.c | 25 +
   branches/release/tools/jam/src/filesys.c | 1
   branches/release/tools/jam/src/filesys.h | 5
   branches/release/tools/jam/src/hcache.c | 8
   branches/release/tools/jam/src/jambase.c | 111 ++++----
   branches/release/tools/jam/src/lists.c | 114 +++------
   branches/release/tools/jam/src/make.c | 3
   branches/release/tools/jam/src/make1.c | 5
   branches/release/tools/jam/src/modules/property-set.c | 33 +-
   branches/release/tools/jam/src/native.c | 10
   branches/release/tools/jam/src/patchlevel.h | 6
   branches/release/tools/jam/src/rules.c | 5
   branches/release/tools/jam/src/search.c | 15
   branches/release/tools/jam/src/search.h | 2
   branches/release/tools/jam/test/action_status.jam | 11
   branches/release/tools/jam/test/actions_quietly.jam | 4
   branches/release/tools/jam/test/builtin_shell.jam | 30 +
   branches/release/tools/jam/test/option_d2.jam | 2
   branches/release/tools/jam/test/option_l.jam | 3
   branches/release/tools/jam/test/option_n.jam | 2
   branches/release/tools/jam/test/parallel_actions.jam | 2
   branches/release/tools/jam/test/parallel_multifile_actions.jam | 6
   branches/release/tools/jam/test/test.jam | 9
   33 files changed, 771 insertions(+), 638 deletions(-)

Modified: branches/release/tools/jam/doc/bjam.qbk
==============================================================================
--- branches/release/tools/jam/doc/bjam.qbk (original)
+++ branches/release/tools/jam/doc/bjam.qbk 2008-07-15 09:38:59 EDT (Tue, 15 Jul 2008)
@@ -1,6 +1,6 @@
 [article Boost.Jam
     [quickbook 1.3]
- [version: 3.1.16]
+ [version: 3.1.17]
     [authors [Rivera, Rene], [Abrahams, David], [Prus, Vladimir]]
     [copyright 2003 2004 2005 2006 2007 Rene Rivera, David Abrahams, Vladimir Prus]
     [category tool-build]
@@ -21,7 +21,7 @@
 
 [/ Shortcuts ]
 
-[def :version: 3.1.16]
+[def :version: 3.1.17]
 
 [/ Images ]
 
@@ -116,7 +116,7 @@
 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:
+The supported toolsets, and whether they are auto-detected, are:
 
 [table Supported Toolsets
 
@@ -758,7 +758,7 @@
 rule DEPENDS ( /targets1/ * : /targets2/ * )
 ]
 
-Builds a direct dependency: makes each of /targets1/ depend on each of /targets2/. Generally, /targets1/ will be rebuilt if /targets2/ are themselves rebuilt are or are newer than /targets1/.
+Builds a direct dependency: makes each of /targets1/ depend on each of /targets2/. Generally, /targets1/ will be rebuilt if /targets2/ are themselves rebuilt or are newer than /targets1/.
 
 [endsect]
 
@@ -954,7 +954,7 @@
 # It clears the list of targets to update, and
 # Causes the specified targets to be updated.
 
-If no target was specified with the =UPDATE= 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:
+If no target was specified with the =UPDATE= rule, no targets will be updated. To support changing of the update list in more useful ways, the rule also returns the targets previously in the update list. This makes it possible to add targets as such:
 
 [pre
 local previous-updates = \[ UPDATE \] ;
@@ -1773,7 +1773,7 @@
 * "Grist" is just a string prefix of the form </characters/>. It is used in Jam to create unique target names based on simpler names. For example, the file name "=test.exe=" 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 "test.exe" 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:
 
    # The location of targets cannot always be derived solely from what the user puts in a Jamfile, but sometimes depends also on the binding process. Some mechanism to distinctly identify targets with the same name is still needed.
- # Grist allows us to use a uniform abstract identifier for each built target, regardless of target file location (as allowed by setting ALL_LOCATE_TARGET.
+ # Grist allows us to use a uniform abstract identifier for each built target, regardless of target file location (as allowed by setting ALL_LOCATE_TARGET).
 
 * When grist is extracted from a name with $(var:G), the result includes the leading and trailing angle brackets. When grist is added to a name with $(var:G=expr), existing grist is first stripped. Then, if expr is non-empty, leading <s and trailing >s are added if necessary to form an expression of the form <expr2>; <expr2> is then prepended.
 

Modified: branches/release/tools/jam/src/Jambase
==============================================================================
--- branches/release/tools/jam/src/Jambase (original)
+++ branches/release/tools/jam/src/Jambase 2008-07-15 09:38:59 EDT (Tue, 15 Jul 2008)
@@ -18,9 +18,10 @@
 }
 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.
+
+# 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 + )
 {
@@ -33,6 +34,7 @@
     return $(globs) ;
 }
 
+
 # This global will hold the location of the user's boost-build.jam file.
 .boost-build-file = ;
 
@@ -42,16 +44,16 @@
 # 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.
+# On Unix only, when BOOST_BUILD_PATH is not supplied by the user, set it to a
+# sensible default value. This allows Boost.Build to work without any
+# environment variables, which is good in itself and also required by the Debian
+# Policy.
 if ! $(BOOST_BUILD_PATH) && $(UNIX)
 {
     BOOST_BUILD_PATH = /usr/share/boost-build ;
 }
 
-
+
 rule _poke ( module-name ? : variables + : value * )
 {
     module $(<)
@@ -60,41 +62,37 @@
     }
 }
 
-# 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.
+
+# 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 "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.
- #
+
+ # 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) ;
-
- # We might have just modified the *global* value of BOOST_BUILD_PATH.
- # The code that loads the rest of Boost.Build, in particular the
- # site-config.jam and user-config.jam files uses os.environ, so we need to
- # update the value there.
+
+ # We might have just modified the *global* value of BOOST_BUILD_PATH. The
+ # code that loads the rest of Boost.Build, in particular the site-config.jam
+ # and user-config.jam configuration files uses os.environ, so we need to
+ # update the value there.
     _poke .ENVIRON : BOOST_BUILD_PATH : $(BOOST_BUILD_PATH) ;
-
+
     # Try to find the build system bootstrap file 'bootstrap.jam'.
- #
- local bootstrap-file =
- [ GLOB $(BOOST_BUILD_PATH) : 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
- #
+
+ # There is no bootstrap.jam we can find, exit with an error.
     if ! $(.bootstrap-file)
     {
         ECHO "Unable to load Boost.Build: could not find build system." ;
@@ -108,44 +106,43 @@
         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) ] ;
+ 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
+ || $(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.
+ # 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.
-
+ # 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
+ # Another temporary measure so Jam works with Boost.Build v1.
         [ GLOB $(search-path) : boost-build.jam ] ;
-
+
     .boost-build-file = $(boost-build-files[1]) ;
-
- # There is no boost-build.jam we can find, exit with an error, and information.
- #
+
+ # 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 " ;
@@ -158,23 +155,21 @@
         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'." ;
     }
-
- if [ MATCH .*(--debug-configuration).* : $(ARGV) ]
+
+ if [ MATCH .*(--debug-configuration).* : $(ARGV) ]
     {
- ECHO "notice: found boost-build.jam at"
- [ NORMALIZE_PATH $(.boost-build-file) ] ;
+ ECHO "notice: found boost-build.jam at"
+ [ NORMALIZE_PATH $(.boost-build-file) ] ;
     }
-
+
     # 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.
- #
+ # We also set it up so we can tell whether 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" ;
@@ -211,7 +206,7 @@
 # 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) - 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.
@@ -227,14 +222,14 @@
 #
 # all - parent of first, shell, files, lib, exe
 # first - first dependent of 'all', for potential initialization
-# shell - parent of all Shell targets
+# 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:
 #
@@ -314,7 +309,7 @@
 # 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
+# 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
 #
@@ -347,35 +342,35 @@
     #
     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
     #
@@ -469,7 +464,7 @@
     C++FLAGS ?= $(CCFLAGS) ;
     LINK ?= $(CC) ;
     LINKFLAGS ?= $(CCFLAGS) ;
- LINKLIBS ?=
+ LINKLIBS ?=
                 \"$(VISUALC16)\\lib\\mlibce.lib\"
                 \"$(VISUALC16)\\lib\\oldnames.lib\"
                 ;
@@ -582,7 +577,7 @@
     else if $(TOOLSET) = MINGW
     {
         ECHO "Compiler is GCC with Mingw" ;
-
+
         AR ?= ar -ru ;
         CC ?= gcc ;
         CCFLAGS ?= "" ;
@@ -600,7 +595,7 @@
     else if $(TOOLSET) = LCC
     {
         ECHO "Compiler is Win32-LCC" ;
-
+
         AR ?= lcclib ;
         CC ?= lcc ;
         CCFLAGS ?= "" ;
@@ -616,7 +611,7 @@
     {
 #
 # XXX: We need better comments here !!
-#
+#
     EXIT On NT, set BCCROOT, MSVCNT, MINGW or MSVC to the root of the
         Borland or Microsoft directories. ;
     }
@@ -627,18 +622,18 @@
     # 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
@@ -650,12 +645,12 @@
         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
     #
@@ -698,7 +693,7 @@
     SUFLIB ?= .lib ;
     SUFOBJ ?= .obj ;
     SUFEXE ?= .exe ;
-
+
     if $(TOOLSET) = WATCOM
     {
        AR ?= wlib ;
@@ -769,7 +764,7 @@
     SUFLIB ?= .olb ;
     SUFOBJ ?= .obj ;
 
- switch $(OS)
+ switch $(OS)
     {
     case OPENVMS : CCFLAGS ?= /stand=vaxc ;
     case VMS : LINKLIBS ?= sys$library:vaxcrtl.olb/lib ;
@@ -778,7 +773,7 @@
 else if $(MAC)
 {
     local OPT ;
-
+
     CW ?= "{CW}" ;
 
     MACHDRS ?=
@@ -790,19 +785,19 @@
         "$(CW):MacOS Support:Universal:Libraries:StubLibraries:Interfacelib"
         "$(CW):MacOS Support:Universal:Libraries:StubLibraries:Mathlib" ;
 
- MPWLIBS ?=
+ 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 ?=
+ 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 ?=
+
+ 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 SIOUX.PPC.Lib"
         "$(CW):MSL:MSL_C:MSL_MacOS:Lib:PPC:MSL C.PPC.Lib" ;
 
     C++ ?= mwcppc ;
@@ -814,15 +809,15 @@
     DOTDOT ?= "::" ;
     HDRS ?= $(MACHDRS) $(MPWHDRS) ;
     LINK ?= mwlinkppc ;
- LINKFLAGS ?= -mpwtool -warn ;
- LINKLIBS ?= $(MACLIBS) $(MPWLIBS) ;
+ LINKFLAGS ?= -mpwtool -warn ;
+ LINKLIBS ?= $(MACLIBS) $(MPWLIBS) ;
     MKDIR ?= newfolder ;
     MV ?= rename -y ;
     NOARSCAN ?= true ;
     OPTIM ?= ;
     RM ?= delete -y ;
     SLASH ?= ":" ;
- STDHDRS ?= ;
+ STDHDRS ?= ;
     SUFLIB ?= .lib ;
     SUFOBJ ?= .o ;
 }
@@ -842,7 +837,7 @@
     NOARSCAN ?= true ;
     STDHDRS ?= /boot/develop/headers/posix ;
 }
-else if $(OS) = BEOS
+else if $(OS) = BEOS
 {
     BINDIR ?= /boot/apps ;
     CC ?= gcc ;
@@ -865,7 +860,7 @@
     CC ?= gcc ;
     YACC ?= "bison -y" ;
 
- case CYGWIN :
+ case CYGWIN :
     CC ?= gcc ;
     CCFLAGS += -D__cygwin__ ;
     LEX ?= flex ;
@@ -895,12 +890,12 @@
     C++ ?= gcc ;
     CCFLAGS += -D_POSIX_SOURCE ;
     HDRS += /usr/include ;
- RANLIB ?= "" ;
+ RANLIB ?= "" ;
     NOARSCAN ?= true ;
     NOARUPDATE ?= true ;
 
     case MVS :
- RANLIB ?= "" ;
+ RANLIB ?= "" ;
 
     case NEXT :
     AR ?= libtool -o ;
@@ -1017,7 +1012,7 @@
     YACCFILES ?= ;
     YACCFLAGS ?= ;
 
- HDRPATTERN =
+ HDRPATTERN =
             "^[ ]*#[ ]*include[ ]*[<\"]([^\">]*)[\">].*$" ;
 
     OSFULL = $(OS)$(OSVER)$(OSPLAT) $(OS)$(OSPLAT) $(OS)$(OSVER) $(OS) ;
@@ -1137,7 +1132,7 @@
     DEPENDS $(<) : $(>) ;
 }
 
-rule GenFile
+rule GenFile
 {
     local _t = [ FGristSourceFiles $(<) ] ;
     local _s = [ FAppendSuffix $(>[1]) : $(SUFEXE) ] ;
@@ -1188,11 +1183,11 @@
 
     local s ;
 
- if $(HDRGRIST)
- {
+ if $(HDRGRIST)
+ {
         s = $(>:G=$(HDRGRIST)) ;
- } else {
- s = $(>) ;
+ } else {
+ s = $(>) ;
     }
 
     INCLUDES $(<) : $(s) ;
@@ -1236,14 +1231,14 @@
         Install $(tt) : $(i) ;
         Chmod $(tt) ;
 
- if $(OWNER) && $(CHOWN)
- {
+ if $(OWNER) && $(CHOWN)
+ {
         Chown $(tt) ;
         OWNER on $(tt) = $(OWNER) ;
         }
 
- if $(GROUP) && $(CHGRP)
- {
+ if $(GROUP) && $(CHGRP)
+ {
         Chgrp $(tt) ;
         GROUP on $(tt) = $(GROUP) ;
         }
@@ -1344,11 +1339,11 @@
         MakeLocate $(_l) $(_l)($(_s:BS)) : $(LOCATE_TARGET) ;
     }
 
- if $(NOARSCAN)
- {
+ 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.
+ # on-disk object files.
 
         DEPENDS $(_l) : $(_s) ;
     }
@@ -1446,12 +1441,12 @@
 
     NOUPDATE $(<) ;
 
- if $(<) != $(DOT) && ! $($(<)-mkdir)
+ if $(<) != $(DOT) && ! $($(<)-mkdir)
     {
         local s ;
 
         # Cheesy gate to prevent multiple invocations on same dir
- # MkDir1 has the actions
+ # MkDir1 has the actions
         # Arrange for jam dirs
 
         $(<)-mkdir = true ;
@@ -1508,7 +1503,7 @@
     # 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
+ # 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.
 
@@ -1603,17 +1598,17 @@
     #
     # SubDir TOP d1 [ ... ]
     #
- # This introduces a Jamfile that is part of a project tree
+ # 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
+ # 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
+ # 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]))
     {
@@ -1703,7 +1698,7 @@
     }
 
     _s = [ FDirName $(<[2-]) ] ;
-
+
     include $(JAMFILE:D=$(_s):R=$($(<[1]))) ;
 }
 
@@ -1761,13 +1756,13 @@
     return $(_g) ;
 }
 
-rule FGristFiles
+rule FGristFiles
 {
     if ! $(SOURCE_GRIST)
     {
         return $(<) ;
     }
- else
+ else
     {
         return $(<:G=$(SOURCE_GRIST)) ;
     }
@@ -1775,7 +1770,7 @@
 
 rule FGristSourceFiles
 {
- # Produce source file name name with grist in it,
+ # Produce source file name name with grist in it,
     # if SOURCE_GRIST is set.
 
     # Leave header files alone, because they have a global
@@ -1785,7 +1780,7 @@
     {
         return $(<) ;
     }
- else
+ else
     {
         local _i _o ;
 
@@ -1826,10 +1821,10 @@
     # path (using ../../ etc) back to that root directory.
     # Sets result in $(<)
 
- if ! $(<[1])
+ if ! $(<[1])
     {
         _d = $(DOT) ;
- }
+ }
     else
     {
         _d = $(DOTDOT) ;
@@ -1877,7 +1872,7 @@
     else if $(MAC)
     {
         _s = $(DOT) ;
-
+
         for _i in $(<)
         {
             _s = $(_i:R=$(_s)) ;
@@ -1885,7 +1880,7 @@
     }
     else
     {
- _s = $(<[1]) ;
+ _s = $(<[1]) ;
 
         for _i in $(<[2-])
         {
@@ -1940,7 +1935,7 @@
 rule FAppendSuffix
 {
        # E.g., "FAppendSuffix yacc lex foo.bat : $(SUFEXE) ;"
- # returns (yacc,lex,foo.bat) on Unix and
+ # returns (yacc,lex,foo.bat) on Unix and
        # (yacc.exe,lex.exe,foo.bat) on NT.
 
     if $(>)
@@ -1968,7 +1963,7 @@
 
 rule unmakeDir
 {
- if $(>[1]:D) && $(>[1]:D) != $(>[1]) && $(>[1]:D) != \\\\
+ if $(>[1]:D) && $(>[1]:D) != $(>[1]) && $(>[1]:D) != \\\\
     {
         unmakeDir $(<) : $(>[1]:D) $(>[1]:BS) $(>[2-]) ;
     }
@@ -1982,10 +1977,10 @@
 rule FConvertToSlashes
 {
   local _d, _s, _i ;
-
+
   unmakeDir _d : $(<) ;
-
- _s = $(_d[1]) ;
+
+ _s = $(_d[1]) ;
   for _i in $(_d[2-])
   {
     _s = $(_s)/$(_i) ;
@@ -2064,7 +2059,7 @@
 
 actions Install
 {
- $(CP) $(>) $(<)
+ $(CP) $(>) $(<)
 }
 
 actions Lex
@@ -2079,7 +2074,7 @@
 
 actions Link bind NEEDLIBS
 {
- $(LINK) $(LINKFLAGS) -o $(<) $(UNDEFS) $(>) $(NEEDLIBS) $(LINKLIBS)
+ $(LINK) $(LINKFLAGS) -o $(<) $(UNDEFS) $(>) $(NEEDLIBS) $(LINKLIBS)
 }
 
 actions MkDir1
@@ -2252,7 +2247,7 @@
   {
     actions together piecemeal Archive
     {
- $(AR) $(<) +-$(>)
+ $(AR) $(<) +-$(>)
     }
 
     actions Cc
@@ -2279,7 +2274,7 @@
   {
     actions together piecemeal Archive
     {
- $(AR) /out:$(<) $(>)
+ $(AR) /out:$(<) $(>)
     }
 
     actions Cc
@@ -2303,13 +2298,13 @@
 # OS2 specific actions
 #
 
-else if $(OS2)
+else if $(OS2)
 {
   if $(TOOLSET) = WATCOM
   {
     actions together piecemeal Archive
     {
- $(AR) $(<) +-$(>)
+ $(AR) $(<) +-$(>)
     }
 
     actions Cc
@@ -2357,19 +2352,19 @@
 
 else if $(VMS)
 {
- actions updated together piecemeal Archive
+ actions updated together piecemeal Archive
     {
     lib/replace $(<) $(>[1]) ,$(>[2-])
     }
 
     actions Cc
- {
- $(CC)/obj=$(<) $(CCFLAGS) $(OPTIM) $(SLASHINC) $(>)
+ {
+ $(CC)/obj=$(<) $(CCFLAGS) $(OPTIM) $(SLASHINC) $(>)
     }
 
     actions C++
- {
- $(C++)/obj=$(<) $(C++FLAGS) $(OPTIM) $(SLASHINC) $(>)
+ {
+ $(C++)/obj=$(<) $(C++FLAGS) $(OPTIM) $(SLASHINC) $(>)
     }
 
     actions piecemeal together existing Clean
@@ -2409,7 +2404,7 @@
 
 else if $(MAC)
 {
- actions together Archive
+ actions together Archive
     {
     $(LINK) -library -o $(<) $(>)
     }
@@ -2417,13 +2412,13 @@
     actions Cc
     {
     set -e MWCincludes $(MACINC)
- $(CC) -o $(<) $(CCFLAGS) $(OPTIM) $(>)
+ $(CC) -o $(<) $(CCFLAGS) $(OPTIM) $(>)
     }
 
     actions C++
- {
+ {
     set -e MWCincludes $(MACINC)
- $(CC) -o $(<) $(C++FLAGS) $(OPTIM) $(>)
+ $(CC) -o $(<) $(C++FLAGS) $(OPTIM) $(>)
     }
 
     actions Link bind NEEDLIBS

Modified: branches/release/tools/jam/src/boost-jam.spec
==============================================================================
--- branches/release/tools/jam/src/boost-jam.spec (original)
+++ branches/release/tools/jam/src/boost-jam.spec 2008-07-15 09:38:59 EDT (Tue, 15 Jul 2008)
@@ -1,64 +1,64 @@
-Name: boost-jam
-Version: 3.1.16
-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_[hidden]>
-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-2006 David Abrahams.
- Copyright 2002-2006 Rene Rivera.
- Copyright 2003-2006 Vladimir Prus.
-
- 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
-cp -R *.html *.png *.css LICENSE*.txt images jam $RPM_BUILD_ROOT%{_docdir}/%{name}-%{version}
-
-find $RPM_BUILD_ROOT -name CVS -type d -exec rm -r {} \;
-
-%files
-%defattr(-,root,root)
-%attr(755,root,root) /usr/bin/*
-%doc %{_docdir}/%{name}-%{version}
-
-
-%clean
-rm -rf $RPM_BUILD_ROOT
+Name: boost-jam
+Version: 3.1.17
+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_[hidden]>
+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-2006 David Abrahams.
+ Copyright 2002-2006 Rene Rivera.
+ Copyright 2003-2006 Vladimir Prus.
+
+ 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
+cp -R *.html *.png *.css LICENSE*.txt images jam $RPM_BUILD_ROOT%{_docdir}/%{name}-%{version}
+
+find $RPM_BUILD_ROOT -name CVS -type d -exec rm -r {} \;
+
+%files
+%defattr(-,root,root)
+%attr(755,root,root) /usr/bin/*
+%doc %{_docdir}/%{name}-%{version}
+
+
+%clean
+rm -rf $RPM_BUILD_ROOT

Modified: branches/release/tools/jam/src/build.bat
==============================================================================
--- branches/release/tools/jam/src/build.bat (original)
+++ branches/release/tools/jam/src/build.bat 2008-07-15 09:38:59 EDT (Tue, 15 Jul 2008)
@@ -20,7 +20,8 @@
 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, vc8
+ECHO ### Toolsets supported by this script are: borland, como, gcc, gcc-nocygwin,
+ECHO ### intel-win32, metrowerks, mingw, msvc, vc7, vc8, vc9
 ECHO ###
 set _error_=
 endlocal
@@ -40,7 +41,7 @@
 
 
 :Test_Option
-REM Tests wether the given string is in the form of an option: "--*"
+REM Tests whether the given string is in the form of an option: "--*"
 setlocal & endlocal
 setlocal
 set test=%1

Modified: branches/release/tools/jam/src/build.jam
==============================================================================
--- branches/release/tools/jam/src/build.jam (original)
+++ branches/release/tools/jam/src/build.jam 2008-07-15 09:38:59 EDT (Tue, 15 Jul 2008)
@@ -13,7 +13,7 @@
 ./ ?= "" ;
 
 # Info about what we are building.
-_VERSION_ = 3 1 16 ;
+_VERSION_ = 3 1 17 ;
 NAME = boost-jam ;
 VERSION = $(_VERSION_:J=$(.)) ;
 RELEASE = 1 ;

Modified: branches/release/tools/jam/src/builtins.c
==============================================================================
--- branches/release/tools/jam/src/builtins.c (original)
+++ branches/release/tools/jam/src/builtins.c 2008-07-15 09:38:59 EDT (Tue, 15 Jul 2008)
@@ -66,7 +66,7 @@
 RULE* bind_builtin( char* name, LIST*(*f)(PARSE*, FRAME*), int flags, char** args )
 {
     argument_list* arg_list = 0;
-
+
     if ( args )
     {
         arg_list = args_new();
@@ -130,7 +130,7 @@
         bind_builtin( "REBUILDS" ,
                       builtin_rebuilds, 0, args );
     }
-
+
     duplicate_rule( "Leaves" ,
       bind_builtin( "LEAVES" ,
                     builtin_flags, T_FLAG_LEAVES, 0 ) );
@@ -174,7 +174,7 @@
                     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 );
@@ -315,7 +315,7 @@
 
 #ifdef HAVE_PYTHON
       {
- char * args[] = { "python-module", ":", "function", ":",
+ char * args[] = { "python-module", ":", "function", ":",
                             "jam-module", ":", "rule-name", 0 };
           bind_builtin( "PYTHON_IMPORT_RULE",
               builtin_python_import_rule, 0, args );
@@ -410,8 +410,8 @@
 /*
  * 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
+ * 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.
  */
 
@@ -483,7 +483,7 @@
 /*
  * builtin_echo() - ECHO rule
  *
- * The ECHO builtin rule echoes the targets to the user. No other
+ * The ECHO builtin rule echoes the targets to the user. No other
  * actions are taken.
  */
 
@@ -494,6 +494,7 @@
 {
         list_print( lol_get( frame->args, 0 ) );
         printf( "\n" );
+ fflush( stdout );
         return L0;
 }
 
@@ -559,7 +560,8 @@
         *p = tolower(*p);
     }
 }
-
+
+
 static void
 builtin_glob_back(
     void *closure,
@@ -568,12 +570,12 @@
     time_t time )
 {
     PROFILE_ENTER(BUILTIN_GLOB_BACK);
-
+
     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. */
 
@@ -607,19 +609,19 @@
             break;
         }
     }
-
+
     string_free( buf );
-
+
     PROFILE_EXIT(BUILTIN_GLOB_BACK);
 }
 
 static LIST* downcase_list( LIST *in )
 {
     LIST* result = 0;
-
+
     string s[1];
     string_new( s );
-
+
     while (in)
     {
         string_copy( s, in->string );
@@ -627,7 +629,7 @@
         result = list_append( result, list_new( 0, newstr( s->value ) ) );
         in = in->next;
     }
-
+
     string_free( s );
     return result;
 }
@@ -639,16 +641,16 @@
 {
     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
+# else
        = lol_get( frame->args, 2 );
 # endif
 
@@ -656,7 +658,7 @@
     {
         globbing.patterns = downcase_list( r );
     }
-
+
     for( ; l; l = list_next( l ) )
         file_dirscan( l->string, builtin_glob_back, &globbing );
 
@@ -686,9 +688,10 @@
     if (time > 0)
         return list_new(list, newstr(file));
     else
- return list;
+ return list;
 }
 
+
 LIST* glob1(char* dirname, char* pattern)
 {
     LIST* plist = list_new(L0, pattern);
@@ -696,11 +699,11 @@
 
     globbing.results = L0;
     globbing.patterns = plist;
-
+
     globbing.case_insensitive
 # if defined( OS_NT ) || defined( OS_CYGWIN )
        = plist; /* always case-insensitive if any files can be found */
-# else
+# else
        = L0;
 # endif
 
@@ -708,7 +711,7 @@
     {
         globbing.patterns = downcase_list( plist );
     }
-
+
     file_dirscan( dirname, builtin_glob_back, &globbing );
 
     if ( globbing.case_insensitive )
@@ -731,13 +734,13 @@
     {
         /* No metacharacters. Check if the path exists. */
         result = append_if_exists(result, pattern);
- }
+ }
     else
     {
         /* Have metacharacters in the pattern. Split into dir/name */
         PATHNAME path[1];
- path_parse(pattern, path);
-
+ path_parse(pattern, path);
+
         if (path->f_dir.ptr)
         {
             LIST* dirs = L0;
@@ -746,7 +749,7 @@
             string_new(dirname);
             string_new(basename);
 
- string_append_range(dirname, path->f_dir.ptr,
+ string_append_range(dirname, path->f_dir.ptr,
                                 path->f_dir.ptr + path->f_dir.len);
 
             path->f_grist.ptr = 0;
@@ -763,12 +766,12 @@
             {
                 dirs = list_new(dirs, dirname->value);
             }
-
+
             if (has_wildcards(basename->value))
             {
                 for(; dirs; dirs = dirs->next)
                 {
- result = list_append(result,
+ result = list_append(result,
                                          glob1(dirs->string, basename->value));
                 }
             }
@@ -779,9 +782,9 @@
 
                 /** No wildcard in basename. */
                 for(; dirs; dirs = dirs->next)
- {
+ {
                     path->f_dir.ptr = dirs->string;
- path->f_dir.len = strlen(dirs->string);
+ path->f_dir.len = strlen(dirs->string);
                     path_build(path, file_string, 0);
 
                     result = append_if_exists(result, file_string->value);
@@ -805,6 +808,7 @@
     return result;
 }
 
+
 LIST *
 builtin_glob_recursive(
     PARSE *parse,
@@ -821,6 +825,7 @@
     return result;
 }
 
+
 /*
  * builtin_match() - MATCH rule, regexp matching
  */
@@ -832,7 +837,7 @@
 {
         LIST *l, *r;
         LIST *result = 0;
-
+
         string buf[1];
         string_new(buf);
 
@@ -873,28 +878,30 @@
         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 */
+ /* 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
@@ -926,6 +933,7 @@
     return result;
 }
 
+
 /* builtin_varnames() - VARNAMES ( MODULE ? )
  *
  * Returns a list of the variable names in the given MODULE. If
@@ -933,6 +941,7 @@
  * global module.
  */
 
+
 /* helper function for builtin_varnames(), below. Used with
  * hashenumerate, will prepend the key of each element to a list
  */
@@ -943,6 +952,7 @@
     *result = list_new( *result, copystr( *(char**)np ) );
 }
 
+
 static struct hash *get_running_module_vars()
 {
     struct hash *dummy, *vars = NULL;
@@ -954,6 +964,7 @@
     return vars;
 }
 
+
 LIST *
 builtin_varnames(
     PARSE *parse,
@@ -965,8 +976,8 @@
 
     /* The running module _always_ has its 'variables' member set to NULL
      * due to the way enter_module and var_hash_swap work */
- struct hash *vars =
- source_module == frame->module ?
+ struct hash *vars =
+ source_module == frame->module ?
             get_running_module_vars() : source_module->variables;
 
     if ( vars )
@@ -974,6 +985,7 @@
     return result;
 }
 
+
 /*
  * builtin_delete_module() - MODULE ?
  *
@@ -992,28 +1004,27 @@
     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
+ * 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 *
@@ -1029,9 +1040,9 @@
 
     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 )
@@ -1039,20 +1050,20 @@
     {
         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 );
@@ -1086,21 +1097,21 @@
     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
  */
@@ -1125,6 +1136,7 @@
     }
 }
 
+
 void print_source_line( PARSE* p )
 {
     char* file;
@@ -1137,6 +1149,7 @@
         printf( "%s:%d:", file, line);
 }
 
+
 /* Print a single line of error backtrace for the given frame */
 void backtrace_line( FRAME *frame )
 {
@@ -1151,6 +1164,7 @@
     }
 }
 
+
 /* Print the entire backtrace from the given frame to the Jambase
  * which invoked it.
  */
@@ -1163,6 +1177,7 @@
     }
 }
 
+
 /* 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
@@ -1189,6 +1204,7 @@
     return result;
 }
 
+
 /*
  * builtin_caller_module() - CALLER_MODULE ( levels ? )
  *
@@ -1216,19 +1232,20 @@
     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.
  *
@@ -1240,10 +1257,11 @@
     return pwd();
 }
 
+
 /*
  * Adds targets to the list of target that jam will attempt to update.
  */
-LIST*
+LIST*
 builtin_update( PARSE *parse, FRAME *frame)
 {
     LIST* result = list_copy( L0, targets_to_update() );
@@ -1254,6 +1272,7 @@
     return result;
 }
 
+
 LIST*
 builtin_search_for_target( PARSE *parse, FRAME *frame )
 {
@@ -1264,6 +1283,7 @@
     return list_new( L0, t->name );
 }
 
+
 LIST *builtin_import_module( PARSE *parse, FRAME *frame )
 {
     LIST* arg1 = lol_get( frame->args, 0 );
@@ -1285,6 +1305,7 @@
     return imported_modules(source_module);
 }
 
+
 LIST *builtin_instance( PARSE *parse, FRAME *frame )
 {
     LIST* arg1 = lol_get( frame->args, 0 );
@@ -1297,6 +1318,7 @@
     return L0;
 }
 
+
 LIST*
 builtin_sort( PARSE *parse, FRAME *frame )
 {
@@ -1305,113 +1327,131 @@
     return list_sort(arg1);
 }
 
+
 LIST *builtin_normalize_path( PARSE *parse, FRAME *frame )
 {
     LIST* arg = 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.
+ /* First, we iterate over all '/'-separated elements, starting from the end
+ of string. If we see a '..', we remove a previous path elements. If we
+ see '.', we remove it. The removal is done by overwriting data using '\1'
+ in the string. After the whole string has been processed, we do a second
+ pass, removing all the entered '\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 = arg->string[0] == '/';
- char* result;
 
- /* Make a copy of input: we should not change it. */
+ string in[1];
+ string out[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 = 0;
+ char * result = 0;
+
+ /* Make a copy of input: we should not change it. Prepend a '/' before it as
+ a guard for the algorithm later on and remember whether it was originally
+ rooted or not. */
+
     string_new(in);
- if (!rooted)
- string_push_back(in, '/');
- while (arg)
- {
- string_append(in, arg->string);
- arg = list_next(arg);
- if (arg)
- string_append(in, "/");
+ string_push_back(in, '/');
+ for (; arg; arg = list_next(arg) )
+ {
+ if (arg->string[0] != '\0')
+ {
+ if (in->size == 1)
+ rooted = ( (arg->string[0] == '/' ) || (arg->string[0] == '\\') );
+ else
+ string_append(in, "/");
+ string_append(in, arg->string);
+ }
     }
 
- /* Convert \ into /. On windows, paths using / and \ are equivalent,
- and we want this function to obtain canonic representation. */
- for (current = in->value, end = in->value + in->size;
- current < end; ++current)
+ /* Convert \ into /. On Windows, paths using / and \ are equivalent, and we
+ want this function to obtain a canonic representation. */
+
+ for (current = in->value, end = in->value + in->size;
+ current < end; ++current)
         if (*current == '\\')
             *current = '/';
 
-
- end = in->value + in->size - 1;
- current = end;
-
- for(;end >= in->value;) {
+ /* Now we remove any extra path elements by overwriting them with '\1'
+ characters and cound how many more unused '..' path elements there are
+ remaining. Note that each remaining path element with always starts with
+ a '/' character. */
+
+ for (end = in->value + in->size - 1; end >= in->value; )
+ {
         /* Set 'current' to the next occurence of '/', which always exists. */
- for(current = end; *current != '/'; --current)
+ 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. */
+
+ if (current == end)
+ {
+ /* Found a trailing or duplicate '/'. Remove it. */
             *current = '\1';
- } else if (end - current == 1 && strncmp(current, "/.", 2) == 0) {
- /* Found '/.'. Drop them all. */
+ }
+ else if (end - current == 1 && *(current+1) == '.')
+ {
+ /* Found '/.'. Remove them all. */
             *current = '\1';
- *(current+1) = '\1';
- } else if (end - current == 2 && strncmp(current, "/..", 3) == 0) {
- /* Found '/..' */
+ *(current+1) = '\1';
+ }
+ else if (end - current == 2 && *(current+1) == '.' && *(current+2) == '.')
+ {
+ /* Found '/..'. Remove them all. */
             *current = '\1';
- *(current+1) = '\1';
- *(current+2) = '\1';
+ *(current+1) = '\1';
+ *(current+2) = '\1';
             ++dotdots;
- } else if (dotdots) {
- char* p = current;
+ }
+ else if (dotdots)
+ {
             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';
- }
-
+
+ /* Now we know that we need to add exactly dotdots '..' path elements to the
+ front and that our string is either empty or has a '/' as its first
+ significant character. If we have any dotdots remaining then the passed
+ path must not have been rooted or else it is invalid we return an empty
+ list. */
+
+ if (dotdots)
+ {
+ if (rooted) return L0;
+ do
+ string_append(out, "/..");
+ while (--dotdots);
+ }
+
+ /* Now we actually remove all the path characters marked for removal. */
+
     for (current = in->value; *current; ++current)
         if (*current != '\1')
             string_push_back(out, *current);
 
-
- result = newstr(out->size ? out->value : (rooted ? "/" : "."));
- string_free(in);
+ /* Here we know that our string contains no '\1' characters and is either
+ empty or has a '/' as its initial character. If the original path was not
+ rooted and we have a non-empty path we need to drop the initial '/'. If
+ the original path was rooted and we have an empty path we need to add
+ back the '/'. */
+
+ result = newstr( out->size ? out->value + !rooted : (rooted ? "/" : "."));
+
     string_free(out);
+ string_free(in);
 
     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 );
+ LIST* module_name = lol_get( frame->args, 0 );
+ LIST* rule_name = lol_get( frame->args, 1 );
 
     module_t* module = bindmodule(module_name->string);
 
@@ -1424,19 +1464,20 @@
     else
     {
         backtrace_line( frame->prev );
- printf( "error: no native rule \"%s\" defined in module \"%s\"\n",
+ printf( "error: no native rule \"%s\" defined in module \"%s\"\n",
                 n.name, module->name);
         backtrace( frame->prev );
         exit(1);
     }
- return L0;
+ return L0;
 }
 
+
 LIST *builtin_has_native_rule( PARSE *parse, FRAME *frame )
 {
- LIST* module_name = lol_get( frame->args, 0 );
- LIST* rule_name = lol_get( frame->args, 1 );
- LIST* version = lol_get( frame->args, 2 );
+ LIST* module_name = lol_get( frame->args, 0 );
+ LIST* rule_name = lol_get( frame->args, 1 );
+ LIST* version = lol_get( frame->args, 2 );
 
     module_t* module = bindmodule(module_name->string);
 
@@ -1448,14 +1489,14 @@
         if (np->version == expected_version)
             return list_new(0, newstr("true"));
     }
- return L0;
+ return L0;
 }
 
 
 LIST *builtin_user_module( PARSE *parse, FRAME *frame )
 {
- LIST* module_name = lol_get( frame->args, 0 );
- for(; module_name; module_name = module_name->next)
+ LIST* module_name = lol_get( frame->args, 0 );
+ for(; module_name; module_name = module_name->next)
     {
         module_t* m = bindmodule( module_name->string);
         m->user_module = 1;
@@ -1466,7 +1507,7 @@
 LIST *builtin_nearest_user_location( PARSE *parse, FRAME *frame )
 {
     LIST* result = 0;
- FRAME* nearest_user_frame =
+ FRAME* nearest_user_frame =
         frame->module->user_module ? frame : frame->prev_user;
 
     if (nearest_user_frame)
@@ -1502,10 +1543,10 @@
 LIST *builtin_python_import_rule( PARSE *parse, FRAME *frame )
 {
     static int first_time = 1;
- char* python_module = lol_get( frame->args, 0 )->string;
- char* python_function = lol_get( frame->args, 1 )->string;
- char* jam_module = lol_get( frame->args, 2 )->string;
- char* jam_rule = lol_get( frame->args, 3 )->string;
+ char* python_module = lol_get( frame->args, 0 )->string;
+ char* python_function = lol_get( frame->args, 1 )->string;
+ char* jam_module = lol_get( frame->args, 2 )->string;
+ char* jam_rule = lol_get( frame->args, 3 )->string;
 
    PyObject *pName, *pModule, *pDict, *pFunc;
 
@@ -1525,9 +1566,9 @@
            exit_module( outer_module );
            enter_module( root_module());
        }
-
+
        extra = var_get("EXTRA_PYTHONPATH");
-
+
        if ( outer_module != root_module())
        {
             exit_module( root_module());
@@ -1541,14 +1582,14 @@
            string_append(buf, "import sys\nsys.path.append(\"");
            string_append(buf, extra->string);
            string_append(buf, "\")\n");
- PyRun_SimpleString(buf->value);
- string_free(buf);
- }
+ PyRun_SimpleString(buf->value);
+ string_free(buf);
+ }
    }
 
 
    pName = PyString_FromString(python_module);
-
+
    pModule = PyImport_Import(pName);
    Py_DECREF(pName);
 
@@ -1587,7 +1628,7 @@
 {
     LIST* l = L0;
     lol_init( lol );
-
+
     while ( elements && *elements )
     {
         if ( !strcmp( *elements, ":" ) )
@@ -1601,7 +1642,7 @@
         }
         ++elements;
     }
-
+
     if ( l != L0 )
         lol_add( lol, l );
 }
@@ -1619,7 +1660,7 @@
     LIST *result;
     PARSE *p;
     char* rulename;
-
+
     /* Build up the list of arg lists */
 
     frame_init( inner );
@@ -1639,7 +1680,7 @@
             PyObject* a = PyTuple_GetItem(args, i);
             if (PyString_Check(a))
             {
- lol_add(inner->args,
+ lol_add(inner->args,
                         list_new(0, newstr(PyString_AsString(a))));
             }
             else if (PySequence_Check(a))
@@ -1661,7 +1702,7 @@
                     Py_DECREF(e);
                 }
                 lol_add(inner->args, l);
- }
+ }
         }
     }
 
@@ -1689,15 +1730,15 @@
 
     if (!PyArg_ParseTuple(args, "ssO:import_rule", &module, &rule, &func))
         return NULL;
-
+
     if (!PyCallable_Check(func))
     {
- PyErr_SetString(PyExc_RuntimeError,
+ PyErr_SetString(PyExc_RuntimeError,
                         "Non-callable object passed to bjam.import_rule");
         return NULL;
     }
-
- m = bindmodule(module);
+
+ m = bindmodule(*module ? module : 0);
     r = bindrule(rule, m);
 
     /* Make pFunc owned */
@@ -1715,7 +1756,7 @@
    - an action body
    - a list of variable that will be bound inside the action
    - integer flags.
- Defines an action on bjam side.
+ Defines an action on bjam side.
 */
 PyObject*
 bjam_define_action(PyObject* self, PyObject *args)
@@ -1729,17 +1770,17 @@
     int n;
     int i;
 
- if (!PyArg_ParseTuple(args, "ssO!i:define_action", &name, &body,
+ if (!PyArg_ParseTuple(args, "ssO!i:define_action", &name, &body,
                           &PyList_Type, &bindlist_python, &flags))
         return NULL;
-
+
     n = PyList_Size (bindlist_python);
     for (i = 0; i < n; ++i)
     {
         PyObject *next = PyList_GetItem(bindlist_python, i);
         if (!PyString_Check(next))
         {
- PyErr_SetString(PyExc_RuntimeError,
+ PyErr_SetString(PyExc_RuntimeError,
                             "bind list has non-string type");
             return NULL;
         }
@@ -1749,7 +1790,7 @@
     new_rule_actions(root_module(), name, newstr(body), bindlist, flags);
 
     Py_INCREF(Py_None);
- return Py_None;
+ return Py_None;
 }
 
 /* Returns the value of a variable in root Jam module. */
@@ -1789,7 +1830,7 @@
         char buf[32];
         get_source_line( f->procedure, &file, &line );
         sprintf( buf, "%d", line );
-
+
         /* PyTuple_SetItem steals reference. */
         PyTuple_SetItem(tuple, 0, PyString_FromString(file));
         PyTuple_SetItem(tuple, 1, PyString_FromString(buf));
@@ -1805,9 +1846,80 @@
 #endif
 
 #ifdef HAVE_POPEN
+
 #if defined(_MSC_VER) || defined(__BORLANDC__)
- #define popen _popen
+ #define popen windows_popen_wrapper
     #define pclose _pclose
+
+ /*
+ * This wrapper is a workaround for a funny _popen() feature on Windows
+ * where it eats external quotes in some cases. The bug seems to be related
+ * to the quote stripping functionality used by the Windows cmd.exe
+ * interpreter when its /S is not specified.
+ *
+ * Cleaned up quote from the cmd.exe help screen as displayed on Windows XP
+ * SP3:
+ *
+ * 1. If all of the following conditions are met, then quote characters on
+ * the command line are preserved:
+ *
+ * - no /S switch
+ * - exactly two quote characters
+ * - no special characters between the two quote characters, where
+ * special is one of: &<>()@^|
+ * - there are one or more whitespace characters between the two quote
+ * characters
+ * - the string between the two quote characters is the name of an
+ * executable file.
+ *
+ * 2. Otherwise, old behavior is to see if the first character is a quote
+ * character and if so, strip the leading character and remove the last
+ * quote character on the command line, preserving any text after the
+ * last quote character.
+ *
+ * This causes some commands containing quotes not to be executed correctly.
+ * For example:
+ *
+ * "\Long folder name\aaa.exe" --name="Jurko" --no-surname
+ *
+ * would get its outermost quotes stripped and would be executed as:
+ *
+ * \Long folder name\aaa.exe" --name="Jurko --no-surname
+ *
+ * which would report an error about '\Long' not being a valid command.
+ *
+ * cmd.exe help seems to indicate it would be enough to add an extra space
+ * character in front of the command to avoid this but this does not work,
+ * most likely due to the shell first stripping all leading whitespace
+ * characters from the command.
+ *
+ * Solution implemented here is to quote the whole command in case it
+ * contains any quote characters. Note thought this will not work correctly
+ * should Windows ever 'fix' this feature.
+ * (03.06.2008.) (Jurko)
+ */
+ static FILE * windows_popen_wrapper( char * command, char * mode )
+ {
+ int extra_command_quotes_needed = ( strchr( command, '"' ) != 0 );
+ string quoted_command;
+ FILE * result;
+
+ if ( extra_command_quotes_needed )
+ {
+ string_new( &quoted_command );
+ string_append( &quoted_command, "\"" );
+ string_append( &quoted_command, command );
+ string_append( &quoted_command, "\"" );
+ command = quoted_command.value;
+ }
+
+ result = _popen( command, "r" );
+
+ if ( extra_command_quotes_needed )
+ string_free( &quoted_command );
+
+ return result;
+ }
 #endif
 
 LIST *builtin_shell( PARSE *parse, FRAME *frame )
@@ -1821,7 +1933,7 @@
     int exit_status = -1;
     int exit_status_opt = 0;
     int no_output_opt = 0;
-
+
     /* Process the variable args options. */
     {
         int a = 1;
@@ -1840,14 +1952,17 @@
         }
     }
 
- string_new( &s );
-
- fflush(NULL);
+ /* The following fflush() call seems to be indicated as a workaround for
+ popen() bug on POSIX implementations realted to synhronizing input stream
+ positions for the called and the calling process. */
+ fflush( NULL );
 
- p = popen(command->string, "r");
+ p = popen( command->string, "r" );
     if ( p == NULL )
         return L0;
 
+ string_new( &s );
+
     while ( (ret = fread(buffer, sizeof(char), sizeof(buffer)-1, p)) > 0 )
     {
         buffer[ret] = 0;
@@ -1857,19 +1972,19 @@
         }
     }
 
- exit_status = pclose(p);
+ exit_status = pclose( p );
 
     /* The command output is returned first. */
     result = list_new( L0, newstr(s.value) );
     string_free(&s);
-
+
     /* The command exit result next. */
     if ( exit_status_opt )
     {
- sprintf (buffer, "%d", exit_status);
+ sprintf( buffer, "%d", exit_status );
         result = list_new( result, newstr( buffer ) );
     }
-
+
     return result;
 }
 

Modified: branches/release/tools/jam/src/compile.c
==============================================================================
--- branches/release/tools/jam/src/compile.c (original)
+++ branches/release/tools/jam/src/compile.c 2008-07-15 09:38:59 EDT (Tue, 15 Jul 2008)
@@ -372,8 +372,9 @@
 
         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 );
+ action. Therefore, pass 0 as third argument.
+ If the name resolves to directory, let it error out. */
+ t->boundname = search( t->name, &t->time, 0, 0 );
         popsettings( t->settings );
 
         parse_file( t->boundname, frame );
@@ -1117,13 +1118,12 @@
 }
 
 /*
- * 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'.
+ * Call the given rule with the specified parameters. The parameters should be
+ * of type LIST* and end with a NULL pointer. This differs from 'evaluate_rule'
+ * in that frame for the called rule is prepared inside 'call_rule'.
  *
- * This function is usefull when builtin rule (in C) wants to
- * call another rule, which might be implemented in Jam.
+ * This function is useful when a builtin rule (in C) wants to call another
+ * rule which might be implemented in Jam.
  */
 LIST *call_rule( char *rulename, FRAME* caller_frame, ...)
 {

Modified: branches/release/tools/jam/src/execnt.c
==============================================================================
--- branches/release/tools/jam/src/execnt.c (original)
+++ branches/release/tools/jam/src/execnt.c 2008-07-15 09:38:59 EDT (Tue, 15 Jul 2008)
@@ -479,12 +479,12 @@
     /* wait for a command to complete, while snarfing up any output */
     do
     {
+ /* check for a complete command, briefly */
+ i = try_wait(500);
         /* read in the output of all running commands */
         read_output();
         /* close out pending debug style dialogs */
         close_alerts();
- /* check for a complete command, briefly */
- if ( i < 0 ) i = try_wait(500);
         /* check if a command ran out of time */
         if ( i < 0 ) i = try_kill_one();
     }
@@ -499,7 +499,7 @@
         /* the time data for the command */
         record_times(cmdtab[i].pi.hProcess, &time);
 
- /* Clear the temp file */
+ /* clear the temp file */
         if ( cmdtab[i].tempfile_bat )
         {
             unlink( cmdtab[ i ].tempfile_bat );
@@ -507,6 +507,9 @@
             cmdtab[i].tempfile_bat = NULL;
         }
 
+ /* find out the process exit code */
+ GetExitCodeProcess( cmdtab[i].pi.hProcess, &cmdtab[i].exitcode );
+
         /* the dispossition of the command */
         if( intr )
             rstat = EXEC_CMD_INTR;
@@ -884,43 +887,39 @@
     }
 }
 
-/* waits for a single child process command to complete, or the
- timeout, whichever is first. returns the index of the completed
- command, or -1. */
+/* Waits for a single child process command to complete, or the timeout,
+ whichever comes first. Returns the index of the completed command in the
+ cmdtab array, or -1. */
 static int try_wait(int timeoutMillis)
 {
- int i, num_active, waiting;
+ int i;
+ int num_active;
+ int wait_api_result;
     HANDLE active_handles[MAXJOBS];
     int active_procs[MAXJOBS];
 
- for ( waiting = 1; waiting; )
+ /* prepare a list of all active processes to wait for */
+ for ( num_active = 0, i = 0; i < globs.jobs; ++i )
     {
- /* find the first completed child process */
- for ( num_active = 0, i = 0; i < globs.jobs; ++i )
+ if ( cmdtab[i].pi.hProcess )
         {
- /* if we have an already dead process, return it. */
- cmdtab[i].exitcode = 0;
- if ( GetExitCodeProcess( cmdtab[i].pi.hProcess, &cmdtab[i].exitcode ) )
- {
- if ( STILL_ACTIVE != cmdtab[i].exitcode )
- {
- return i;
- }
- }
- /* it's running, add it to the list to watch for */
             active_handles[num_active] = cmdtab[i].pi.hProcess;
             active_procs[num_active] = i;
- num_active += 1;
- }
-
- /* wait for a child to complete, or for our timeout window to expire */
- if ( waiting )
- {
- WaitForMultipleObjects( num_active, active_handles, FALSE, timeoutMillis );
- waiting = 0;
+ ++num_active;
         }
     }
-
+
+ /* wait for a child to complete, or for our timeout window to expire */
+ wait_api_result = WaitForMultipleObjects( num_active, active_handles,
+ FALSE, timeoutMillis );
+ if ( ( WAIT_OBJECT_0 <= wait_api_result ) &&
+ ( wait_api_result < WAIT_OBJECT_0 + num_active ) )
+ {
+ /* terminated process detected - return its index */
+ return active_procs[ wait_api_result - WAIT_OBJECT_0 ];
+ }
+
+ /* timeout */
     return -1;
 }
 
@@ -941,9 +940,7 @@
                 close_alert(cmdtab[i].pi.hProcess);
                 /* we have a "runaway" job, kill it */
                 kill_process_tree(0,cmdtab[i].pi.hProcess);
- /* and return it as complete, with the failure code */
- GetExitCodeProcess( cmdtab[i].pi.hProcess, &cmdtab[i].exitcode );
- /* mark it as a timeout */
+ /* and return it marked as a timeout */
                 cmdtab[i].exit_reason = EXIT_TIMEOUT;
                 return i;
             }

Modified: branches/release/tools/jam/src/execunix.c
==============================================================================
--- branches/release/tools/jam/src/execunix.c (original)
+++ branches/release/tools/jam/src/execunix.c 2008-07-15 09:38:59 EDT (Tue, 15 Jul 2008)
@@ -25,6 +25,10 @@
 # ifdef USE_EXECUNIX
 # include <sys/times.h>
 
+# if defined(__APPLE__)
+# define NO_VFORK
+# endif
+
 # ifdef NO_VFORK
 # define vfork() fork()
 # endif
@@ -211,6 +215,8 @@
 
         if ((cmdtab[slot].pid = vfork()) == 0)
            {
+ int pid = getpid();
+
             close(out[0]);
             close(err[0]);
 
@@ -239,17 +245,19 @@
                 r_limit.rlim_max = globs.timeout;
                 setrlimit(RLIMIT_CPU, &r_limit);
             }
- setpgid(cmdtab[slot].pid, cmdtab[slot].pid);
-
- execvp( argv[0], argv );
- _exit(127);
- }
+ setpgid(pid,pid);
+ execvp( argv[0], argv );
+ perror( "execvp" );
+ _exit(127);
+ }
         else if( cmdtab[slot].pid == -1 )
         {
             perror( "vfork" );
             exit( EXITBAD );
         }
 
+ setpgid(cmdtab[slot].pid, cmdtab[slot].pid);
+
         /* close write end of pipes */
         close(out[1]);
         close(err[1]);
@@ -458,7 +466,7 @@
                 if (FD_ISSET(cmdtab[i].fd[OUT], &fds))
                     out = read_descriptor(i, OUT);
 
- if (FD_ISSET(cmdtab[i].fd[ERR], &fds))
+ if ((globs.pipe_action != 0) && (FD_ISSET(cmdtab[i].fd[ERR], &fds)))
                     err = read_descriptor(i, ERR);
 
                 /* if feof on either descriptor, then we're done */

Modified: branches/release/tools/jam/src/expand.c
==============================================================================
--- branches/release/tools/jam/src/expand.c (original)
+++ branches/release/tools/jam/src/expand.c 2008-07-15 09:38:59 EDT (Tue, 15 Jul 2008)
@@ -749,7 +749,12 @@
     assert(l != 0);
     assert(list_next(l) == 0);
     # ifdef OS_CYGWIN
- assert( !strcmp( l->string, "c:\\foo\\bar" ) );
+ /* On some installations of cygwin the drive letter is expanded to other case. */
+ /* This has been reported to be the case if cygwin has been installed to C:\ */
+ /* as opposed to C:\cygwin */
+ /* Since case of the drive letter will not matter, we allow for both. */
+ assert( 0 == strcmp( l->string, "c:\\foo\\bar" )
+ || 0 == strcmp( l->string, "C:\\foo\\bar") );
     # else
     assert( !strcmp( l->string, cygpath ) );
     # endif

Modified: branches/release/tools/jam/src/filent.c
==============================================================================
--- branches/release/tools/jam/src/filent.c (original)
+++ branches/release/tools/jam/src/filent.c 2008-07-15 09:38:59 EDT (Tue, 15 Jul 2008)
@@ -87,18 +87,33 @@
         int ret;
         struct _finddata_t finfo[1];
         LIST* files = L0;
+ int d_length = strlen( d->name );
 
         memset( (char *)&f, '\0', sizeof( f ) );
         
         f.f_dir.ptr = d->name;
- f.f_dir.len = strlen(d->name);
-
+ f.f_dir.len = d_length;
+
         /* Now enter contents of directory */
 
- string_copy( filespec, *d->name ? d->name : "." );
- string_append( filespec, "/*" );
+ /* Prepare file search specification for the findfirst() API. */
+ if ( d_length == 0 )
+ string_copy( filespec, ".\\*" );
+ else
+ {
+ /*
+ * We can not simply assume the given folder name will never include
+ * its trailing path separator or otherwise we would not support the
+ * Windows root folder specified without its drive letter, i.e. '\'.
+ */
+ char trailingChar = d->name[ d_length - 1 ] ;
+ string_copy( filespec, d->name );
+ if ( ( trailingChar != '\\' ) && ( trailingChar != '/' ) )
+ string_append( filespec, "\\" );
+ string_append( filespec, "*" );
+ }
 
- if( DEBUG_BINDSCAN )
+ if ( DEBUG_BINDSCAN )
             printf( "scan directory %s\n", dir );
 
         # if defined(__BORLANDC__) && __BORLANDC__ < 0x550

Modified: branches/release/tools/jam/src/filesys.c
==============================================================================
--- branches/release/tools/jam/src/filesys.c (original)
+++ branches/release/tools/jam/src/filesys.c 2008-07-15 09:38:59 EDT (Tue, 15 Jul 2008)
@@ -19,6 +19,7 @@
             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 );
+ printf( "\n" );
     }
         
     /* Start with the grist. If the current grist isn't */

Modified: branches/release/tools/jam/src/filesys.h
==============================================================================
--- branches/release/tools/jam/src/filesys.h (original)
+++ branches/release/tools/jam/src/filesys.h 2008-07-15 09:38:59 EDT (Tue, 15 Jul 2008)
@@ -41,8 +41,13 @@
 } ;
 typedef struct file_info_t file_info_t ;
 
+/* Creates a pointer to information about file
+ 'filename', creating it as necessary. If
+ created, the structure will be default initialized. */
 file_info_t * file_info(char * filename);
 
+/* Returns information about a file, queries the OS
+ if needed. */
 file_info_t * file_query(char * filename);
 
 void file_done();

Modified: branches/release/tools/jam/src/hcache.c
==============================================================================
--- branches/release/tools/jam/src/hcache.c (original)
+++ branches/release/tools/jam/src/hcache.c 2008-07-15 09:38:59 EDT (Tue, 15 Jul 2008)
@@ -80,9 +80,11 @@
             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 );
+ /* Don't expect cache file to be generated, so pass 0
+ as third argument to search.
+ Expect the location to be specified via LOCATE,
+ so pass 0 as fourth arugment. */
+ t->boundname = search( t->name, &t->time, 0, 0 );
             popsettings( t->settings );
 
             if (hcachevar) {

Modified: branches/release/tools/jam/src/jambase.c
==============================================================================
--- branches/release/tools/jam/src/jambase.c (original)
+++ branches/release/tools/jam/src/jambase.c 2008-07-15 09:38:59 EDT (Tue, 15 Jul 2008)
@@ -34,7 +34,7 @@
 "{\n",
 "if $(.bootstrap-file)\n",
 "{\n",
-"EXIT \"Error: Illegal attempt to re-bootstrap the build system by invoking\" ;\n",
+"ECHO \"Error: Illegal attempt to re-bootstrap the build system by invoking\" ;\n",
 "ECHO ;\n",
 "ECHO \" 'boost-build\" $(dir) \";'\" ;\n",
 "ECHO ;\n",
@@ -42,8 +42,7 @@
 "}\n",
 "BOOST_BUILD_PATH = $(dir:R=$(.boost-build-file:D)) $(BOOST_BUILD_PATH) ;\n",
 "_poke .ENVIRON : BOOST_BUILD_PATH : $(BOOST_BUILD_PATH) ;\n",
-"local bootstrap-file =\n",
-"[ GLOB $(BOOST_BUILD_PATH) : bootstrap.jam ] ;\n",
+"local bootstrap-file = [ GLOB $(BOOST_BUILD_PATH) : bootstrap.jam ] ;\n",
 ".bootstrap-file = $(bootstrap-file[1]) ;\n",
 "if ! $(.bootstrap-file)\n",
 "{\n",
@@ -60,13 +59,13 @@
 "}\n",
 "if [ MATCH .*(--debug-configuration).* : $(ARGV) ]\n",
 "{\n",
-"ECHO \"notice: loading Boost.Build from\" \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",
+"|| $(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",
@@ -88,9 +87,9 @@
 "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",
-"if [ MATCH .*(--debug-configuration).* : $(ARGV) ] \n",
+"if [ MATCH .*(--debug-configuration).* : $(ARGV) ]\n",
 "{\n",
-"ECHO \"notice: found boost-build.jam at\" \n",
+"ECHO \"notice: found boost-build.jam at\"\n",
 "[ NORMALIZE_PATH $(.boost-build-file) ] ;\n",
 "}\n",
 "include $(.boost-build-file) ;\n",
@@ -217,7 +216,7 @@
 "C++FLAGS ?= $(CCFLAGS) ;\n",
 "LINK ?= $(CC) ;\n",
 "LINKFLAGS ?= $(CCFLAGS) ;\n",
-"LINKLIBS ?= \n",
+"LINKLIBS ?=\n",
 "\\\"$(VISUALC16)\\\\lib\\\\mlibce.lib\\\"\n",
 "\\\"$(VISUALC16)\\\\lib\\\\oldnames.lib\\\"\n",
 ";\n",
@@ -478,7 +477,7 @@
 "SUFEXE ?= .exe ;\n",
 "SUFLIB ?= .olb ;\n",
 "SUFOBJ ?= .obj ;\n",
-"switch $(OS) \n",
+"switch $(OS)\n",
 "{\n",
 "case OPENVMS : CCFLAGS ?= /stand=vaxc ;\n",
 "case VMS : LINKLIBS ?= sys$library:vaxcrtl.olb/lib ;\n",
@@ -495,16 +494,16 @@
 "MACLIBS ?=\n",
 "\"$(CW):MacOS Support:Universal:Libraries:StubLibraries:Interfacelib\"\n",
 "\"$(CW):MacOS Support:Universal:Libraries:StubLibraries:Mathlib\" ;\n",
-"MPWLIBS ?= \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",
+"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",
+"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 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",
@@ -515,15 +514,15 @@
 "DOTDOT ?= \"::\" ;\n",
 "HDRS ?= $(MACHDRS) $(MPWHDRS) ;\n",
 "LINK ?= mwlinkppc ;\n",
-"LINKFLAGS ?= -mpwtool -warn ; \n",
-"LINKLIBS ?= $(MACLIBS) $(MPWLIBS) ; \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",
+"STDHDRS ?= ;\n",
 "SUFLIB ?= .lib ;\n",
 "SUFOBJ ?= .o ;\n",
 "}\n",
@@ -543,7 +542,7 @@
 "NOARSCAN ?= true ;\n",
 "STDHDRS ?= /boot/develop/headers/posix ;\n",
 "}\n",
-"else if $(OS) = BEOS \n",
+"else if $(OS) = BEOS\n",
 "{\n",
 "BINDIR ?= /boot/apps ;\n",
 "CC ?= gcc ;\n",
@@ -564,7 +563,7 @@
 "case AMIGA :\n",
 "CC ?= gcc ;\n",
 "YACC ?= \"bison -y\" ;\n",
-"case CYGWIN : \n",
+"case CYGWIN :\n",
 "CC ?= gcc ;\n",
 "CCFLAGS += -D__cygwin__ ;\n",
 "LEX ?= flex ;\n",
@@ -589,11 +588,11 @@
 "C++ ?= gcc ;\n",
 "CCFLAGS += -D_POSIX_SOURCE ;\n",
 "HDRS += /usr/include ;\n",
-"RANLIB ?= \"\" ; \n",
+"RANLIB ?= \"\" ;\n",
 "NOARSCAN ?= true ;\n",
 "NOARUPDATE ?= true ;\n",
 "case MVS :\n",
-"RANLIB ?= \"\" ; \n",
+"RANLIB ?= \"\" ;\n",
 "case NEXT :\n",
 "AR ?= libtool -o ;\n",
 "RANLIB ?= \"\" ;\n",
@@ -691,7 +690,7 @@
 "YACC ?= ;\n",
 "YACCFILES ?= ;\n",
 "YACCFLAGS ?= ;\n",
-"HDRPATTERN = \n",
+"HDRPATTERN =\n",
 "\"^[ ]*#[ ]*include[ ]*[<\\\"]([^\\\">]*)[\\\">].*$\" ;\n",
 "OSFULL = $(OS)$(OSVER)$(OSPLAT) $(OS)$(OSPLAT) $(OS)$(OSVER) $(OS) ;\n",
 "DEPENDS all : shell files lib exe obj ;\n",
@@ -777,7 +776,7 @@
 "{\n",
 "DEPENDS $(<) : $(>) ;\n",
 "}\n",
-"rule GenFile \n",
+"rule GenFile\n",
 "{\n",
 "local _t = [ FGristSourceFiles $(<) ] ;\n",
 "local _s = [ FAppendSuffix $(>[1]) : $(SUFEXE) ] ;\n",
@@ -803,11 +802,11 @@
 "rule HdrRule\n",
 "{\n",
 "local s ;\n",
-"if $(HDRGRIST) \n",
-"{ \n",
+"if $(HDRGRIST)\n",
+"{\n",
 "s = $(>:G=$(HDRGRIST)) ;\n",
-"} else { \n",
-"s = $(>) ; \n",
+"} else {\n",
+"s = $(>) ;\n",
 "}\n",
 "INCLUDES $(<) : $(s) ;\n",
 "SEARCH on $(s) = $(HDRSEARCH) ;\n",
@@ -831,13 +830,13 @@
 "Depends $(tt) : $(i) ;\n",
 "Install $(tt) : $(i) ;\n",
 "Chmod $(tt) ;\n",
-"if $(OWNER) && $(CHOWN) \n",
-"{ \n",
+"if $(OWNER) && $(CHOWN)\n",
+"{\n",
 "Chown $(tt) ;\n",
 "OWNER on $(tt) = $(OWNER) ;\n",
 "}\n",
-"if $(GROUP) && $(CHGRP) \n",
-"{ \n",
+"if $(GROUP) && $(CHGRP)\n",
+"{\n",
 "Chgrp $(tt) ;\n",
 "GROUP on $(tt) = $(GROUP) ;\n",
 "}\n",
@@ -910,8 +909,8 @@
 "{\n",
 "MakeLocate $(_l) $(_l)($(_s:BS)) : $(LOCATE_TARGET) ;\n",
 "}\n",
-"if $(NOARSCAN) \n",
-"{ \n",
+"if $(NOARSCAN)\n",
+"{\n",
 "DEPENDS $(_l) : $(_s) ;\n",
 "}\n",
 "else\n",
@@ -972,7 +971,7 @@
 "rule MkDir\n",
 "{\n",
 "NOUPDATE $(<) ;\n",
-"if $(<) != $(DOT) && ! $($(<)-mkdir) \n",
+"if $(<) != $(DOT) && ! $($(<)-mkdir)\n",
 "{\n",
 "local s ;\n",
 "$(<)-mkdir = true ;\n",
@@ -1157,13 +1156,13 @@
 "}\n",
 "return $(_g) ;\n",
 "}\n",
-"rule FGristFiles \n",
+"rule FGristFiles\n",
 "{\n",
 "if ! $(SOURCE_GRIST)\n",
 "{\n",
 "return $(<) ;\n",
 "}\n",
-"else \n",
+"else\n",
 "{\n",
 "return $(<:G=$(SOURCE_GRIST)) ;\n",
 "}\n",
@@ -1174,7 +1173,7 @@
 "{\n",
 "return $(<) ;\n",
 "}\n",
-"else \n",
+"else\n",
 "{\n",
 "local _i _o ;\n",
 "for _i in $(<)\n",
@@ -1201,10 +1200,10 @@
 "rule FSubDir\n",
 "{\n",
 "local _i _d ;\n",
-"if ! $(<[1]) \n",
+"if ! $(<[1])\n",
 "{\n",
 "_d = $(DOT) ;\n",
-"} \n",
+"}\n",
 "else\n",
 "{\n",
 "_d = $(DOTDOT) ;\n",
@@ -1245,7 +1244,7 @@
 "}\n",
 "else\n",
 "{\n",
-"_s = $(<[1]) ; \n",
+"_s = $(<[1]) ;\n",
 "for _i in $(<[2-])\n",
 "{\n",
 "_s = $(_i:R=$(_s)) ;\n",
@@ -1301,7 +1300,7 @@
 "}\n",
 "rule unmakeDir\n",
 "{\n",
-"if $(>[1]:D) && $(>[1]:D) != $(>[1]) && $(>[1]:D) != \\\\\\\\ \n",
+"if $(>[1]:D) && $(>[1]:D) != $(>[1]) && $(>[1]:D) != \\\\\\\\\n",
 "{\n",
 "unmakeDir $(<) : $(>[1]:D) $(>[1]:BS) $(>[2-]) ;\n",
 "}\n",
@@ -1314,7 +1313,7 @@
 "{\n",
 "local _d, _s, _i ;\n",
 "unmakeDir _d : $(<) ;\n",
-"_s = $(_d[1]) ; \n",
+"_s = $(_d[1]) ;\n",
 "for _i in $(_d[2-])\n",
 "{\n",
 "_s = $(_s)/$(_i) ;\n",
@@ -1371,7 +1370,7 @@
 "}\n",
 "actions Install\n",
 "{\n",
-"$(CP) $(>) $(<) \n",
+"$(CP) $(>) $(<)\n",
 "}\n",
 "actions Lex\n",
 "{\n",
@@ -1383,7 +1382,7 @@
 "}\n",
 "actions Link bind NEEDLIBS\n",
 "{\n",
-"$(LINK) $(LINKFLAGS) -o $(<) $(UNDEFS) $(>) $(NEEDLIBS) $(LINKLIBS) \n",
+"$(LINK) $(LINKFLAGS) -o $(<) $(UNDEFS) $(>) $(NEEDLIBS) $(LINKLIBS)\n",
 "}\n",
 "actions MkDir1\n",
 "{\n",
@@ -1520,7 +1519,7 @@
 "{\n",
 "actions together piecemeal Archive\n",
 "{\n",
-"$(AR) $(<) +-$(>) \n",
+"$(AR) $(<) +-$(>)\n",
 "}\n",
 "actions Cc\n",
 "{\n",
@@ -1543,7 +1542,7 @@
 "{\n",
 "actions together piecemeal Archive\n",
 "{\n",
-"$(AR) /out:$(<) $(>) \n",
+"$(AR) /out:$(<) $(>)\n",
 "}\n",
 "actions Cc\n",
 "{\n",
@@ -1559,13 +1558,13 @@
 "}\n",
 "}\n",
 "}\n",
-"else if $(OS2) \n",
+"else if $(OS2)\n",
 "{\n",
 "if $(TOOLSET) = WATCOM\n",
 "{\n",
 "actions together piecemeal Archive\n",
 "{\n",
-"$(AR) $(<) +-$(>) \n",
+"$(AR) $(<) +-$(>)\n",
 "}\n",
 "actions Cc\n",
 "{\n",
@@ -1602,17 +1601,17 @@
 "}\n",
 "else if $(VMS)\n",
 "{\n",
-"actions updated together piecemeal Archive \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",
+"$(CC)/obj=$(<) $(CCFLAGS) $(OPTIM) $(SLASHINC) $(>)\n",
 "}\n",
 "actions C++\n",
-"{ \n",
-"$(C++)/obj=$(<) $(C++FLAGS) $(OPTIM) $(SLASHINC) $(>) \n",
+"{\n",
+"$(C++)/obj=$(<) $(C++FLAGS) $(OPTIM) $(SLASHINC) $(>)\n",
 "}\n",
 "actions piecemeal together existing Clean\n",
 "{\n",
@@ -1641,19 +1640,19 @@
 "}\n",
 "else if $(MAC)\n",
 "{\n",
-"actions together Archive \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",
+"$(CC) -o $(<) $(CCFLAGS) $(OPTIM) $(>)\n",
 "}\n",
 "actions C++\n",
-"{ \n",
+"{\n",
 "set -e MWCincludes $(MACINC)\n",
-"$(CC) -o $(<) $(C++FLAGS) $(OPTIM) $(>) \n",
+"$(CC) -o $(<) $(C++FLAGS) $(OPTIM) $(>)\n",
 "}\n",
 "actions Link bind NEEDLIBS\n",
 "{\n",

Modified: branches/release/tools/jam/src/lists.c
==============================================================================
--- branches/release/tools/jam/src/lists.c (original)
+++ branches/release/tools/jam/src/lists.c 2008-07-15 09:38:59 EDT (Tue, 15 Jul 2008)
@@ -13,12 +13,12 @@
  *
  * 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
+ * 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
+ * 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()
@@ -32,7 +32,7 @@
  */
 
 LIST *
-list_append(
+list_append(
         LIST *l,
         LIST *nl )
 {
@@ -59,7 +59,7 @@
  */
 
 LIST *
-list_new(
+list_new(
         LIST *head,
         char *string )
 {
@@ -102,7 +102,7 @@
  */
 
 LIST *
-list_copy(
+list_copy(
         LIST *l,
         LIST *nl )
 {
@@ -117,7 +117,7 @@
  */
 
 LIST *
-list_sublist(
+list_sublist(
         LIST *l,
         int start,
         int count )
@@ -133,82 +133,42 @@
         return nl;
 }
 
+static int str_ptr_compare(const void *va, const void *vb)
+{
+ char* a = *( (char**)va );
+ char* b = *( (char**)vb );
+ return strcmp(a, b);
+}
+
 LIST *
 list_sort(
     LIST *l)
 {
-
- LIST* first = 0;
- LIST* second = 0;
- LIST* merged = l;
- LIST* result;
+ int len, ii;
+ char** strings;
+ LIST* listp;
+ LIST* result = 0;
 
     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;
- }
+ len = list_length(l);
+ strings = (char**)BJAM_MALLOC( len * sizeof(char*) );
 
- if (merged != l)
- list_free( merged );
- merged = 0;
-
- if (second == 0) {
- result = first;
- break;
- }
+ listp = l;
+ for (ii = 0; ii < len; ++ii) {
+ strings[ii] = listp->string;
+ listp = listp->next;
+ }
 
-
- /* Merge lists 'first' and 'second' into 'merged' and free
- 'first'/'second'. */
- {
- LIST* f = first;
- LIST* s = second;
+ qsort(strings, len, sizeof(char*), str_ptr_compare);
 
- 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;
- }
+ for (ii = 0; ii < len; ++ii) {
+ result = list_append( result, list_new(0, strings[ii]) );
     }
 
+ BJAM_FREE(strings);
+
     return result;
 }
 
@@ -251,12 +211,12 @@
 void
 list_print( LIST *l )
 {
- LIST *p = 0;
+ LIST *p = 0;
         for( ; l; p = l, l = list_next( l ) )
- if ( p )
+ if ( p )
                 printf( "%s ", p->string );
         if ( p )
- printf( "%s", p->string );
+ printf( "%s", p->string );
 }
 
 /*
@@ -274,7 +234,7 @@
         return n;
 }
 
-int
+int
 list_in(LIST* l, char* value)
 {
     for(; l; l = l->next)
@@ -283,7 +243,7 @@
     return 0;
 }
 
-LIST *
+LIST *
 list_unique( LIST *sorted_list)
 {
     LIST* result = 0;
@@ -297,7 +257,7 @@
             last_added = sorted_list;
         }
     }
- return result;
+ return result;
 }
 
 
@@ -316,7 +276,7 @@
  */
 
 void
-lol_add(
+lol_add(
         LOL *lol,
         LIST *l )
 {
@@ -344,7 +304,7 @@
  */
 
 LIST *
-lol_get(
+lol_get(
         LOL *lol,
         int i )
 {

Modified: branches/release/tools/jam/src/make.c
==============================================================================
--- branches/release/tools/jam/src/make.c (original)
+++ branches/release/tools/jam/src/make.c 2008-07-15 09:38:59 EDT (Tue, 15 Jul 2008)
@@ -289,7 +289,8 @@
         if( t->binding == T_BIND_UNBOUND && !( t->flags & T_FLAG_NOTFILE ) )
         {
             char* another_target;
- t->boundname = search( t->name, &t->time, &another_target );
+ t->boundname = search( t->name, &t->time, &another_target,
+ (t->flags & T_FLAG_ISFILE));
             /* 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

Modified: branches/release/tools/jam/src/make1.c
==============================================================================
--- branches/release/tools/jam/src/make1.c (original)
+++ branches/release/tools/jam/src/make1.c 2008-07-15 09:38:59 EDT (Tue, 15 Jul 2008)
@@ -687,7 +687,7 @@
         FRAME frame[1];
         frame_init( frame );
 
- /* args * :: $(__ACTION_RULE__[2-]) */
+ /* args * :: $(__TIMING_RULE__[2-]) */
         lol_add( frame->args, list_copy( L0, timing_rule->next ) );
 
         /* target :: the name of the target */
@@ -1145,7 +1145,8 @@
             return;
 
         pushsettings( t->settings );
- t->boundname = search( t->name, &t->time, 0 );
+ t->boundname = search( t->name, &t->time, 0,
+ (t->flags & T_FLAG_ISFILE) );
         t->binding = t->time ? T_BIND_EXISTS : T_BIND_MISSING;
         popsettings( t->settings );
 }

Modified: branches/release/tools/jam/src/modules/property-set.c
==============================================================================
--- branches/release/tools/jam/src/modules/property-set.c (original)
+++ branches/release/tools/jam/src/modules/property-set.c 2008-07-15 09:38:59 EDT (Tue, 15 Jul 2008)
@@ -15,12 +15,12 @@
     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;
 }
@@ -28,22 +28,22 @@
 /*
 rule create ( raw-properties * )
 {
- raw-properties = [ sequence.unique
+ raw-properties = [ sequence.unique
         [ sequence.insertion-sort $(raw-properties) ] ] ;
-
+
     local key = $(raw-properties:J=-:E=) ;
-
- if ! $(.ps.$(key))
+
+ if ! $(.ps.$(key))
     {
         .ps.$(key) = [ new property-set $(raw-properties) ] ;
     }
- return $(.ps.$(key)) ;
+ return $(.ps.$(key)) ;
 }
 */
 
 LIST *property_set_create( PARSE *parse, FRAME *frame )
 {
- LIST* properties = lol_get( frame->args, 0 );
+ LIST* properties = lol_get( frame->args, 0 );
     LIST* sorted = 0;
     LIST* order_sensitive = 0;
     LIST* unique;
@@ -63,7 +63,7 @@
         }
         list_free(att);
     }
-
+
     sorted = list_sort(sorted);
     sorted = list_append(sorted, order_sensitive);
     unique = list_unique(sorted);
@@ -73,24 +73,24 @@
 
     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);
-
+ 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);
@@ -105,5 +105,4 @@
         char* args[] = { "raw-properties", "*", 0 };
         declare_native_rule("property-set", "create", args, property_set_create, 1);
     }
-
 }

Modified: branches/release/tools/jam/src/native.c
==============================================================================
--- branches/release/tools/jam/src/native.c (original)
+++ branches/release/tools/jam/src/native.c 2008-07-15 09:38:59 EDT (Tue, 15 Jul 2008)
@@ -9,15 +9,14 @@
 # define C0 (char *)0
 
 
-void declare_native_rule(char* module, char* rule, char** args,
+void declare_native_rule(char* module, char* rule, char** args,
                          LIST*(*f)(PARSE*, FRAME*), int version)
-
 {
     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;
@@ -25,14 +24,13 @@
         {
             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 );
+ n.procedure = parse_make( f, P0, P0, P0, C0, C0, 0 );
         n.version = version;
         hashenter(m->native_rules, (HASHDATA**)&np);
     }
 }
-

Modified: branches/release/tools/jam/src/patchlevel.h
==============================================================================
--- branches/release/tools/jam/src/patchlevel.h (original)
+++ branches/release/tools/jam/src/patchlevel.h 2008-07-15 09:38:59 EDT (Tue, 15 Jul 2008)
@@ -9,9 +9,9 @@
 
 #define VERSION_MAJOR 3
 #define VERSION_MINOR 1
-#define VERSION_PATCH 16
+#define VERSION_PATCH 17
 #define VERSION_MAJOR_SYM "03"
 #define VERSION_MINOR_SYM "1"
-#define VERSION_PATCH_SYM "16"
-#define VERSION "3.1.16"
+#define VERSION_PATCH_SYM "17"
+#define VERSION "3.1.17"
 #define JAMVERSYM "JAMVERSION=3.1"

Modified: branches/release/tools/jam/src/rules.c
==============================================================================
--- branches/release/tools/jam/src/rules.c (original)
+++ branches/release/tools/jam/src/rules.c 2008-07-15 09:38:59 EDT (Tue, 15 Jul 2008)
@@ -137,6 +137,9 @@
             targethash = hashinit( sizeof( TARGET ), "targets" );
 
     /* Perforce added const everywhere. No time to merge that change. */
+#ifdef NT
+ targetname = short_path_to_long_path( (char*)targetname );
+#endif
         t->name = (char*)targetname;
 
         if( hashenter( targethash, (HASHDATA **)&t ) )
@@ -165,7 +168,7 @@
                 /* 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 );
+ t->boundname = search( t->name, &t->time, 0, 0 );
                 popsettings(t->settings);
                 break;
             }

Modified: branches/release/tools/jam/src/search.c
==============================================================================
--- branches/release/tools/jam/src/search.c (original)
+++ branches/release/tools/jam/src/search.c 2008-07-15 09:38:59 EDT (Tue, 15 Jul 2008)
@@ -20,6 +20,7 @@
 # include "compile.h"
 # include "strings.h"
 # include "hash.h"
+# include "filesys.h"
 # include <string.h>
 
 typedef struct _binding {
@@ -89,7 +90,8 @@
 search(
     char *target,
     time_t *time,
- char **another_target
+ char **another_target,
+ int file
 )
 {
         PATHNAME f[1];
@@ -135,6 +137,7 @@
         while( varlist )
         {
             BINDING b, *ba = &b;
+ file_info_t *ff;
 
             f->f_root.ptr = varlist->string;
             f->f_root.len = strlen( varlist->string );
@@ -145,6 +148,7 @@
             if( DEBUG_SEARCH )
                 printf( "search %s: %s\n", target, buf->value );
 
+ ff = file_query(buf->value);
             timestamp( buf->value, time );
 
             b.binding = buf->value;
@@ -159,10 +163,13 @@
                 found = 1;
                 break;
             }
- else if( *time )
+ else if( ff && ff->time )
             {
- found = 1;
- break;
+ if (!file || ff->is_file)
+ {
+ found = 1;
+ break;
+ }
             }
 
             varlist = list_next( varlist );

Modified: branches/release/tools/jam/src/search.h
==============================================================================
--- branches/release/tools/jam/src/search.h (original)
+++ branches/release/tools/jam/src/search.h 2008-07-15 09:38:59 EDT (Tue, 15 Jul 2008)
@@ -8,4 +8,4 @@
  * search.h - find a target along $(SEARCH) or $(LOCATE)
  */
 
-char *search( char *target, time_t *time, char **another_target );
+char *search( char *target, time_t *time, char **another_target, int file );

Modified: branches/release/tools/jam/test/action_status.jam
==============================================================================
--- branches/release/tools/jam/test/action_status.jam (original)
+++ branches/release/tools/jam/test/action_status.jam 2008-07-15 09:38:59 EDT (Tue, 15 Jul 2008)
@@ -6,23 +6,22 @@
 {
     ECHO --- Testing \"actions status results\"... ;
 
- assert "" 0 : (==) : [ SHELL "$(ARGV[1]) -f action_status.jam -sBJAM_SUBTEST=1" : exit-status : no-output ] ;
+ assert "" 0 : (==) : [ SHELL "\"$(ARGV[1])\" -f action_status.jam -sBJAM_SUBTEST=1" : exit-status : no-output ] ;
     if $(NT)
     {
- assert "" 0 : (==) : [ SHELL "$(ARGV[1]) -f action_status.jam -sBJAM_SUBTEST=1 \"-sACTION=;\"" : exit-status : no-output ] ;
+ assert "" 0 : (==) : [ SHELL "\"$(ARGV[1])\" -f action_status.jam -sBJAM_SUBTEST=1 \"-sACTION=;\"" : exit-status : no-output ] ;
     }
- assert "" 0 : (!=) : [ SHELL "$(ARGV[1]) -f action_status.jam -sBJAM_SUBTEST=1 -sACTION=invalid" : exit-status : no-output ] ;
+ assert "" 0 : (!=) : [ SHELL "\"$(ARGV[1])\" -f action_status.jam -sBJAM_SUBTEST=1 -sACTION=invalid" : exit-status : no-output ] ;
 }
 else
 {
- #~ actions .a. { $(ACTION) }
     actions quietly .a. { $(ACTION) }
-
+
     rule .a.
     {
         DEPENDS $(<) : $(>) ;
     }
-
+
     NOTFILE subtest ;
     .a. subtest_a : subtest ;
     DEPENDS all : subtest_a ;

Modified: branches/release/tools/jam/test/actions_quietly.jam
==============================================================================
--- branches/release/tools/jam/test/actions_quietly.jam (original)
+++ branches/release/tools/jam/test/actions_quietly.jam 2008-07-15 09:38:59 EDT (Tue, 15 Jul 2008)
@@ -27,12 +27,12 @@
 [subtest_b] 1
 [subtest_b] 2
 ...updated 2 targets...
-" : (==) : [ SHELL "$(ARGV[1]) -f actions_quietly.jam -sBJAM_SUBTEST=1 -d2" ] ;
+" : (==) : [ SHELL "\"$(ARGV[1])\" -f actions_quietly.jam -sBJAM_SUBTEST=1 -d2" ] ;
 
     assert "...found 4 targets...
 ...updating 2 targets...
 ...updated 2 targets...
-" : (==) : [ SHELL "$(ARGV[1]) -f actions_quietly.jam -sBJAM_SUBTEST=1" ] ;
+" : (==) : [ SHELL "\"$(ARGV[1])\" -f actions_quietly.jam -sBJAM_SUBTEST=1" ] ;
 }
 else
 {

Modified: branches/release/tools/jam/test/builtin_shell.jam
==============================================================================
--- branches/release/tools/jam/test/builtin_shell.jam (original)
+++ branches/release/tools/jam/test/builtin_shell.jam 2008-07-15 09:38:59 EDT (Tue, 15 Jul 2008)
@@ -2,16 +2,30 @@
 #~ 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)
 
+# TODO: Here we should test for the Windows popen() command unquoting bug but
+# that test will have to wait until a better testing framework is implemented.
+# To reproduce the bug try executing any command with its first parameter quoted
+# and containing spaces and having at least one other quote in the command
+# string.
+#
+# For example:
+#
+# "\Long folder name\aaa.exe" --name="Jurko" --no-surname
+#
+# would get its outermost quotes stripped and would be executed as:
+#
+# \Long folder name\aaa.exe" --name="Jurko --no-surname
+
 ECHO --- Testing SHELL builtin... ;
 
 local c = "date" ;
 if $(NT) { c = "PATH" ; }
 
-assert "" : (!=) : [ SHELL $(c) ] ;
-assert "" : (==) : [ SHELL $(c) : no-output ] ;
-assert "" 0 : (!=) : [ SHELL $(c) : exit-status ] ;
-assert "" 0 : (==) : [ SHELL $(c) : no-output : exit-status ] ;
-assert "" : (!=) : [ COMMAND $(c) ] ;
-assert "" : (==) : [ COMMAND $(c) : no-output ] ;
-assert "" 0 : (!=) : [ COMMAND $(c) : exit-status ] ;
-assert "" 0 : (==) : [ COMMAND $(c) : no-output : exit-status ] ;
+assert "" : (!=) : [ SHELL $(c) ] ;
+assert "" : (==) : [ SHELL $(c) : no-output ] ;
+assert "" 0 : (!=) : [ SHELL $(c) : exit-status ] ;
+assert "" 0 : (==) : [ SHELL $(c) : no-output : exit-status ] ;
+assert "" : (!=) : [ COMMAND $(c) ] ;
+assert "" : (==) : [ COMMAND $(c) : no-output ] ;
+assert "" 0 : (!=) : [ COMMAND $(c) : exit-status ] ;
+assert "" 0 : (==) : [ COMMAND $(c) : no-output : exit-status ] ;

Modified: branches/release/tools/jam/test/option_d2.jam
==============================================================================
--- branches/release/tools/jam/test/option_d2.jam (original)
+++ branches/release/tools/jam/test/option_d2.jam 2008-07-15 09:38:59 EDT (Tue, 15 Jul 2008)
@@ -27,7 +27,7 @@
 [subtest_b] 1
 [subtest_b] 2
 ...updated 2 targets...
-" : (==) : [ SHELL "$(ARGV[1]) -f option_d2.jam -sBJAM_SUBTEST=1 -d2" ] ;
+" : (==) : [ SHELL "\"$(ARGV[1])\" -f option_d2.jam -sBJAM_SUBTEST=1 -d2" ] ;
 }
 else
 {

Modified: branches/release/tools/jam/test/option_l.jam
==============================================================================
--- branches/release/tools/jam/test/option_l.jam (original)
+++ branches/release/tools/jam/test/option_l.jam 2008-07-15 09:38:59 EDT (Tue, 15 Jul 2008)
@@ -5,6 +5,7 @@
 if ! $(BJAM_SUBTEST)
 {
     ECHO --- Testing -l option... ;
+
     assert "...found 2 targets...
 ...updating 1 target...
 .a. sleeper
@@ -17,7 +18,7 @@
 
 ...failed .a. sleeper...
 ...failed updating 1 target...
-" : (==) : [ SHELL "$(ARGV[1]) -f option_l.jam -sBJAM_SUBTEST=1 -l2" ] ;
+" : (==) : [ SHELL "\"$(ARGV[1])\" -f option_l.jam -sBJAM_SUBTEST=1 -l2" ] ;
 }
 else
 {

Modified: branches/release/tools/jam/test/option_n.jam
==============================================================================
--- branches/release/tools/jam/test/option_n.jam (original)
+++ branches/release/tools/jam/test/option_n.jam 2008-07-15 09:38:59 EDT (Tue, 15 Jul 2008)
@@ -21,7 +21,7 @@
 echo [subtest_b] 2
     
 ...updated 2 targets...
-" : (==) : [ SHELL "$(ARGV[1]) -f option_n.jam -sBJAM_SUBTEST=1 -n" ] ;
+" : (==) : [ SHELL "\"$(ARGV[1])\" -f option_n.jam -sBJAM_SUBTEST=1 -n" ] ;
 }
 else
 {

Modified: branches/release/tools/jam/test/parallel_actions.jam
==============================================================================
--- branches/release/tools/jam/test/parallel_actions.jam (original)
+++ branches/release/tools/jam/test/parallel_actions.jam 2008-07-15 09:38:59 EDT (Tue, 15 Jul 2008)
@@ -41,7 +41,7 @@
 [.b] 1
 [.b] 2
 ...updated 8 targets...
-" : (==) : [ SHELL "$(ARGV[1]) -f parallel_actions.jam -sBJAM_SUBTEST=1 -j4" ] ;
+" : (==) : [ SHELL "\"$(ARGV[1])\" -f parallel_actions.jam -sBJAM_SUBTEST=1 -j4" ] ;
 }
 else
 {

Modified: branches/release/tools/jam/test/parallel_multifile_actions.jam
==============================================================================
--- branches/release/tools/jam/test/parallel_multifile_actions.jam (original)
+++ branches/release/tools/jam/test/parallel_multifile_actions.jam 2008-07-15 09:38:59 EDT (Tue, 15 Jul 2008)
@@ -5,6 +5,7 @@
 if ! $(BJAM_SUBTEST)
 {
     ECHO --- Testing -jN parallel execution of multi-file actions... ;
+
     assert "...found 6 targets...
 ...updating 4 targets...
 .gen. g1.generated
@@ -15,7 +16,7 @@
 .use.2 u2.user
 004
 ...updated 4 targets...
-" : (==) : [ SHELL "$(ARGV[1]) -f parallel_multifile_actions.jam -sBJAM_SUBTEST=1 -j2" ] ;
+" : (==) : [ SHELL "\"$(ARGV[1])\" -f parallel_multifile_actions.jam -sBJAM_SUBTEST=1 -j2" ] ;
 }
 else
 {
@@ -41,7 +42,4 @@
     NOTFILE root ;
     DEPENDS g1.generated g2.generated : root ;
     DEPENDS all : u1.user u2.user ;
- #~ Work around... Remove when fixed...
- #~ DEPENDS g2.generated : g1.generated ;
- #~ INCLUDES g2.generated : g1.generated ;
 }

Modified: branches/release/tools/jam/test/test.jam
==============================================================================
--- branches/release/tools/jam/test/test.jam (original)
+++ branches/release/tools/jam/test/test.jam 2008-07-15 09:38:59 EDT (Tue, 15 Jul 2008)
@@ -5,16 +5,21 @@
 fail-count = 0 ;
 pass-count = 0 ;
 
+
 rule message ( message * )
 {
     local b = [ BACKTRACE ] ;
     ECHO "$(b[-4]):$(b[-3]):" $(message) ;
 }
+
+
 rule fail ( message * )
 {
     fail-count = [ CALC $(fail-count) + 1 ] ;
     message "error:" [FAILED] $(message) ;
 }
+
+
 rule pass ( message * )
 {
     pass-count = [ CALC $(pass-count) + 1 ] ;
@@ -23,6 +28,8 @@
         message "info:" [PASSED] $(message) ;
     }
 }
+
+
 rule assert ( expected * : test ? : obtained * )
 {
     test ?= "(==)" ;
@@ -41,8 +48,10 @@
     }
 }
 
+
 include action_status.jam ;
 include actions_quietly.jam ;
+include builtin_normalize_path.jam ;
 include builtin_shell.jam ;
 include builtin_w32_getregnames.jam ;
 include option_d2.jam ;


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk