From 39e67e8f0dca70a0e4fbdf48ad31d02b35f72eca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jurko=20Gospodneti=C4=87?= Date: Sun, 8 Jun 2008 19:41:56 +0000 Subject: [PATCH] Minor stylistic Boost Build script changes. [SVN r46254] --- src/build/feature.jam | 45 +++++- src/build/project.jam | 80 ++++++---- src/build/property-set.jam | 42 ++++-- src/build/targets.jam | 112 +++++++------- src/kernel/class.jam | 72 ++++----- src/kernel/errors.jam | 4 +- src/kernel/modules.jam | 4 +- src/tools/stage.jam | 9 +- src/util/assert.jam | 289 +++++++++++++++++++++++++------------ src/util/container.jam | 13 +- src/util/indirect.jam | 5 + src/util/path.jam | 24 +-- 12 files changed, 439 insertions(+), 260 deletions(-) mode change 100755 => 100644 src/kernel/errors.jam mode change 100755 => 100644 src/util/indirect.jam diff --git a/src/build/feature.jam b/src/build/feature.jam index 4b980ab21..b56f58d78 100644 --- a/src/build/feature.jam +++ b/src/build/feature.jam @@ -42,6 +42,7 @@ setup ; # Prepare a fresh space to test in by moving all global variable settings into # the given temporary module and erasing them here. +# rule prepare-test ( temp-module ) { DELETE_MODULE $(temp-module) ; @@ -61,6 +62,7 @@ rule prepare-test ( temp-module ) # Clear out all global variables and recover all variables from the given # temporary module. +# rule finish-test ( temp-module ) { # Clear globals. @@ -80,8 +82,9 @@ rule finish-test ( temp-module ) } -# Transform features by bracketing any elements which aren't already bracketed +# Transform features by bracketing any elements which are not already bracketed # by "<>". +# local rule grist ( features * ) { local empty = "" ; @@ -90,6 +93,7 @@ local rule grist ( features * ) # Declare a new feature with the given name, values, and attributes. +# rule feature ( name # Feature name. : values * # Allowable values - may be extended later using feature.extend. @@ -118,15 +122,15 @@ rule feature ( { error = free features cannot be propagated ; } - else + else { local m = [ MATCH (.*=.*) : $(values) ] ; if $(m[1]) { error = "feature value may not contain '='" ; - } + } } - + if $(error) { errors.error $(error) @@ -153,6 +157,7 @@ rule feature ( # Sets the default value of the given feature, overriding any previous default. +# rule set-default ( feature : value ) { local f = [ grist $(feature) ] ; @@ -166,6 +171,7 @@ rule set-default ( feature : value ) # Returns the default property values for the given features. +# rule defaults ( features * ) { local result ; @@ -186,6 +192,7 @@ rule defaults ( features * ) # Returns true iff all 'names' elements are valid features. +# rule valid ( names + ) { if $(names) in $(.all-features) @@ -196,6 +203,7 @@ rule valid ( names + ) # Returns the attibutes of the given feature. +# rule attributes ( feature ) { return $($(:E=:G=$(feature)).attributes) ; @@ -203,6 +211,7 @@ rule attributes ( feature ) # Returns the values of the given feature. +# rule values ( feature ) { return $($(:E=:G=$(feature)).values) ; @@ -210,6 +219,7 @@ rule values ( feature ) # Returns true iff 'value-string' is a value-string of an implicit feature. +# rule is-implicit-value ( value-string ) { local v = [ regex.split $(value-string) - ] ; @@ -238,6 +248,7 @@ rule is-implicit-value ( value-string ) # Returns the implicit feature associated with the given implicit value. +# rule implied-feature ( implicit-value ) { local components = [ regex.split $(implicit-value) "-" ] ; @@ -267,6 +278,7 @@ local rule find-implied-subfeature ( feature subvalue : value-string ? ) # Given a feature and a value of one of its subfeatures, find the name of the # subfeature. If value-string is supplied, looks for implied subfeatures that # are specific to that value of feature +# rule implied-subfeature ( feature # The main feature name. subvalue # The value of one of its subfeatures. @@ -286,6 +298,7 @@ rule implied-subfeature ( # Generate an error if the feature is unknown. +# local rule validate-feature ( feature ) { if ! $(feature) in $(.all-features) @@ -305,6 +318,7 @@ local rule validate-feature ( feature ) # return: # # gcc 2.95.2 linux x86 +# local rule expand-subfeatures-aux ( feature ? # Feature name or empty if value corresponds to an # implicit property. @@ -399,6 +413,7 @@ rule expand-subfeatures ( # Helper for extend, below. Handles the feature case. +# local rule extend-feature ( feature : values * ) { feature = [ grist $(feature) ] ; @@ -427,6 +442,7 @@ local rule extend-feature ( feature : values * ) # Checks that value-string is a valid value-string for the given feature. +# rule validate-value-string ( feature value-string ) { if ! ( @@ -464,6 +480,7 @@ rule validate-value-string ( feature value-string ) # between subvalue(s) and a subfeature # * value of that variable when such a subfeature/subvalue has been defined and # returns a list consisting of the latter followed by the former. +# local rule subvalue-var ( feature # Main feature name. value-string ? # If supplied, specifies a specific value of the main @@ -518,6 +535,7 @@ rule extend-subfeature ( # Returns true iff the subvalues are valid for the feature. When the optional # value-string is provided, returns true iff the subvalues are valid for the # given value of the feature. +# rule is-subvalue ( feature : value-string ? : subfeature : subvalue ) { local subfeature-vars = [ subvalue-var $(feature) $(value-string) @@ -591,6 +609,7 @@ local rule get-subfeature-name ( subfeature value-string ? ) # Declares a subfeature. +# rule subfeature ( feature # Root feature that is not a subfeature. value-string ? # A value-string specifying which feature or subfeature @@ -623,6 +642,7 @@ rule subfeature ( # Set components of the given composite property. +# rule compose ( composite-property : component-properties * ) { local feature = $(composite-property:G) ; @@ -654,6 +674,7 @@ local rule expand-composite ( property ) # Return all values of the given feature specified by the given property set. +# rule get-values ( feature : properties * ) { local result ; @@ -681,6 +702,7 @@ rule free-features ( ) # Expand all composite properties in the set so that all components are # explicitly expressed. +# rule expand-composites ( properties * ) { local explicit-features = $(properties:G) ; @@ -739,6 +761,7 @@ rule expand-composites ( properties * ) # Return true iff f is an ordinary subfeature of the parent-property's feature, # or if f is a subfeature of the parent-property's feature specific to the # parent-property's value. +# local rule is-subfeature-of ( parent-property f ) { if subfeature in $($(f).attributes) @@ -769,6 +792,7 @@ local rule is-subfeature-of ( parent-property f ) # As for is-subfeature-of but for subproperties. +# local rule is-subproperty-of ( parent-property p ) { return [ is-subfeature-of $(parent-property) $(p:G) ] ; @@ -778,6 +802,7 @@ local rule is-subproperty-of ( parent-property p ) # Given a property, return the subset of features consisting of all ordinary # subfeatures of the property's feature, and all specific subfeatures of the # property's feature which are conditional on the property's value. +# local rule select-subfeatures ( parent-property : features * ) { return [ sequence.filter is-subfeature-of $(parent-property) : $(features) ] ; @@ -785,6 +810,7 @@ local rule select-subfeatures ( parent-property : features * ) # As for select-subfeatures but for subproperties. +# local rule select-subproperties ( parent-property : properties * ) { return [ sequence.filter is-subproperty-of $(parent-property) : $(properties) ] ; @@ -799,6 +825,7 @@ local rule select-subproperties ( parent-property : properties * ) # of those features due to composite feature expansion to be dropped. If two # values of a given non-free feature are directly expressed in the input, an # error is issued. +# rule expand ( properties * ) { local expanded = [ expand-subfeatures $(properties) ] ; @@ -808,6 +835,7 @@ rule expand ( properties * ) # Helper rule for minimize. Returns true iff property's feature is present in # the contents of the variable named by feature-set-var. +# local rule in-features ( feature-set-var property ) { if $(property:G) in $($(feature-set-var)) @@ -819,6 +847,7 @@ local rule in-features ( feature-set-var property ) # Helper rule for minimize. Returns the list with the same properties, but with # all subfeatures moved to the end of the list. +# local rule move-subfeatures-to-the-end ( properties * ) { local x1 ; @@ -844,6 +873,7 @@ local rule move-subfeatures-to-the-end ( properties * ) # they override a value from some composite property. Implicit properties will # be expressed without feature grist, and sub-property values will be expressed # as elements joined to the corresponding main property. +# rule minimize ( properties * ) { # Precondition checking @@ -913,8 +943,9 @@ rule minimize ( properties * ) # Requires: for every subproperty, there is a parent property. All features are # explicitly expressed. # -# This rule probably shouldn't be needed, but build-request.expand-no-defaults +# This rule probably should not be needed, but build-request.expand-no-defaults # is being abused for unintended purposes and it needs help. +# rule compress-subproperties ( properties * ) { local all-subs ; @@ -954,6 +985,7 @@ rule compress-subproperties ( properties * ) # feature name followed by a dash, and return a pair consisting of the parts # before and after that dash. More interesting than a simple split because # feature names may contain dashes. +# local rule split-top-feature ( feature-plus ) { local e = [ regex.split $(feature-plus) - ] ; @@ -989,6 +1021,7 @@ local rule split-top-feature ( feature-plus ) # debug off # # and that's kind of strange. +# rule add-defaults ( properties * ) { for local v in $(properties:G=) @@ -1033,6 +1066,7 @@ rule add-defaults ( properties * ) # Note that vN...vM may contain slashes. This needs to be resilient to the # substitution of backslashes for slashes, since Jam, unbidden, sometimes swaps # slash direction on NT. +# rule split ( property-set ) { local pieces = [ regex.split $(property-set) [\\/] ] ; @@ -1055,6 +1089,7 @@ rule split ( property-set ) # Tests of module feature. +# local rule __test__ ( ) { # Use a fresh copy of the feature module. diff --git a/src/build/project.jam b/src/build/project.jam index c5a59e42c..b25e9b9b0 100644 --- a/src/build/project.jam +++ b/src/build/project.jam @@ -4,36 +4,35 @@ # 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) -# Implements project representation and loading. Each project is represented -# by: -# - a module where all the Jamfile content live. -# - an instance of 'project-attributes' class. -# (given a module name, can be obtained using the 'attributes' rule) -# - an instance of 'project-target' class (from targets.jam) -# (given a module name, can be obtained using the 'target' rule) +# Implements project representation and loading. Each project is represented by: +# - a module where all the Jamfile content live. +# - an instance of 'project-attributes' class. +# (given a module name, can be obtained using the 'attributes' rule) +# - an instance of 'project-target' class (from targets.jam) +# (given a module name, can be obtained using the 'target' rule) # -# Typically, projects are created as result of loading a Jamfile, which is done -# by rules 'load' and 'initialize', below. First, module for Jamfile is loaded -# and new project-attributes instance is created. Some rules necessary for -# project are added to the module (see 'project-rules' module) at the bottom of -# this file. Default project attributes are set (inheriting attributes of -# parent project, if it exists). After that the Jamfile is read. It can declare -# its own attributes using the 'project' rule which will be combined with any -# alread set attributes. +# Typically, projects are created as result of loading a Jamfile, which is done +# by rules 'load' and 'initialize', below. First, module for Jamfile is loaded +# and new project-attributes instance is created. Some rules necessary for +# project are added to the module (see 'project-rules' module) at the bottom of +# this file. Default project attributes are set (inheriting attributes of parent +# project, if it exists). After that the Jamfile is read. It can declare its own +# attributes using the 'project' rule which will be combined with any already +# set attributes. # -# The 'project' rule can also declare a project id which will be associated -# with the project module. +# The 'project' rule can also declare a project id which will be associated with +# the project module. # -# There can also be 'standalone' projects. They are created by calling -# 'initialize' on an arbitrary module and not specifying their location. After -# the call, the module can call the 'project' rule, declare main targets and -# behave as a regular project except that, since it's not associated with any -# location, it should not declare targets that are not prebuilt. +# There can also be 'standalone' projects. They are created by calling +# 'initialize' on an arbitrary module and not specifying their location. After +# the call, the module can call the 'project' rule, declare main targets and +# behave as a regular project except that, since it is not associated with any +# location, it should not declare targets that are not prebuilt. # -# The list of all loaded Jamfile is stored in the .project-locations variable. -# It's possible to obtain a module name for a location using the 'module-name' -# rule. Standalone projects are not recorded and can only be referenced using -# their project id. +# The list of all loaded Jamfile is stored in the .project-locations variable. +# It is possible to obtain a module name for a location using the 'module-name' +# rule. Standalone projects are not recorded and can only be referenced using +# their project id. import "class" : new ; import errors ; @@ -94,13 +93,14 @@ rule load-used-projects ( module-name ) # Note the use of character groups, as opposed to listing 'Jamroot' and -# 'jamroot'. With the latter, we'd get duplicate matches on Windows and would -# have to eliminate duplicates. +# 'jamroot'. With the latter, we would get duplicate matches on Windows and +# would have to eliminate duplicates. JAMROOT ?= [ modules.peek : JAMROOT ] ; JAMROOT ?= project-root.jam [Jj]amroot [Jj]amroot.jam ; # Loads parent of Jamfile at 'location'. Issues an error if nothing is found. +# rule load-parent ( location ) { local found = [ path.glob-in-parents $(location) : @@ -120,6 +120,7 @@ rule load-parent ( location ) # Makes the specified 'module' act as if it were a regularly loaded Jamfile at # 'location'. Reports an error if a Jamfile has already been loaded for that # location. +# rule act-as-jamfile ( module : location ) { if [ module-name $(location) ] in $(.jamfile-modules) @@ -139,6 +140,7 @@ rule act-as-jamfile ( module : location ) # Returns the project module corresponding to the given project-id or plain # directory name. Returns nothing if such a project can not be found. +# rule find ( name : current-location ) { local project-module ; @@ -489,6 +491,7 @@ rule initialize ( # Make 'project-module' inherit attributes of project root and parent module. +# rule inherit-attributes ( project-module : parent-module ) { local attributes = $($(project-module).attributes) ; @@ -528,6 +531,7 @@ rule inherit-attributes ( project-module : parent-module ) # Associate the given id with the given project module. +# rule register-id ( id : module ) { $(id).jamfile-module = $(module) ; @@ -538,6 +542,7 @@ rule register-id ( id : module ) # # The standard attributes are "id", "location", "project-root", "parent" # "requirements", "default-build", "source-location" and "projects-to-build". +# class project-attributes { import property ; @@ -556,6 +561,7 @@ class project-attributes # Set the named attribute from the specification given by the user. The # value actually set may be different. + # rule set ( attribute : specification * : exact ? # Sets value from 'specification' without any processing. ) @@ -640,12 +646,14 @@ class project-attributes } # Returns the value of the given attribute. + # rule get ( attribute ) { return $(self.$(attribute)) ; } # Prints the project attributes. + # rule print ( ) { local id = $(self.id) ; id ?= (none) ; @@ -664,6 +672,7 @@ class project-attributes # Returns the project which is currently being loaded. +# rule current ( ) { return $(.current-project) ; @@ -672,6 +681,7 @@ rule current ( ) # Temporarily changes the current project to 'project'. Should be followed by # 'pop-current'. +# rule push-current ( project ) { .saved-current-project += $(.current-project) ; @@ -687,6 +697,7 @@ rule pop-current ( ) # Returns the project-attribute instance for the specified Jamfile module. +# rule attributes ( project ) { return $($(project).attributes) ; @@ -694,6 +705,7 @@ rule attributes ( project ) # Returns the value of the specified attribute in the specified Jamfile module. +# rule attribute ( project attribute ) { return [ $($(project).attributes).get $(attribute) ] ; @@ -701,6 +713,7 @@ rule attribute ( project attribute ) # Returns the project target corresponding to the 'project-module'. +# rule target ( project-module ) { if ! $(.target.$(project-module)) @@ -714,6 +727,7 @@ rule target ( project-module ) # Use/load a project. +# rule use ( id : location ) { local saved-project = $(.current-project) ; @@ -810,6 +824,7 @@ rule glob-internal ( project : wildcards + : excludes * : rule-name ) # This module defines rules common to all projects. +# module project-rules { rule using ( toolset-module : * ) @@ -926,8 +941,8 @@ module project-rules # child Jamfile. # rule constant ( - name # Variable name of the constant. - : value + # Value of the constant. + name # Variable name of the constant. + : value + # Value of the constant. ) { import project ; @@ -938,6 +953,7 @@ module project-rules # Declare and set a project global constant, whose value is a path. The path # is adjusted to be relative to the invocation directory. The given value # path is taken to be either absolute, or relative to this project root. + # rule path-constant ( name # Variable name of the constant. : value + # Value of the constant. @@ -979,8 +995,8 @@ module project-rules rule glob ( wildcards + : excludes * ) { import project ; - return [ project.glob-internal [ project.current ] - : $(wildcards) : $(excludes) : glob ] ; + return [ project.glob-internal [ project.current ] : $(wildcards) : + $(excludes) : glob ] ; } rule glob-tree ( wildcards + : excludes * ) diff --git a/src/build/property-set.jam b/src/build/property-set.jam index 2ab25a3dd..b3217f0da 100644 --- a/src/build/property-set.jam +++ b/src/build/property-set.jam @@ -9,22 +9,23 @@ import property ; import sequence ; import set ; + # Class for storing a set of properties. -# - there's 1<->1 correspondence between identity and value. No two instances of -# the class are equal. To maintain this property, the 'property-set.create' -# rule should be used to create new instances. Instances are immutable. # -# - each property is classified with regard to it's effect on build results. -# Incidental properties have no effect on build results, from Boost.Build's -# point of view. Others are either free, or non-free, which we call 'base'. -# Each property belongs to exactly one of those categories and it's possible -# to get list of properties in each category. +# There is 1<->1 correspondence between identity and value. No two instances +# of the class are equal. To maintain this property, the 'property-set.create' +# rule should be used to create new instances. Instances are immutable. # -# In addition, it's possible to get a list of properties with a specific -# attribute. +# Each property is classified with regard to its effect on build results. +# Incidental properties have no effect on build results, from Boost.Build's +# point of view. Others are either free, or non-free and we refer to non-free +# ones as 'base'. Each property belongs to exactly one of those categories. # -# - several operations, like and refine and as-path are provided. They all use -# caching whenever possible. +# It is possible to get a list of properties belonging to each category as +# well as a list of properties with a specific attribute. +# +# Several operations, like and refine and as-path are provided. They all use +# caching whenever possible. # class property-set { @@ -92,6 +93,7 @@ class property-set } # Returns Jam list of stored properties. + # rule raw ( ) { return $(self.raw) ; @@ -103,18 +105,21 @@ class property-set } # Returns properties that are neither incidental nor free. + # rule base ( ) { return $(self.base) ; } - # Returns free properties which are not dependency properties. + # Returns free properties which are not incidental. + # rule free ( ) { return $(self.free) ; } # Returns dependency properties. + # rule dependency ( ) { return $(self.dependency) ; @@ -136,6 +141,7 @@ class property-set } # Returns incidental properties. + # rule incidental ( ) { return $(self.incidental) ; @@ -239,6 +245,7 @@ class property-set # Returns a list of # - the computed path # - if the path is relative to the build directory, a value of 'true'. + # rule target-path ( ) { if ! $(self.target-path) @@ -318,6 +325,7 @@ class property-set } # Returns all values of 'feature'. + # rule get ( feature ) { if ! $(self.map-built) @@ -338,6 +346,7 @@ class property-set # Creates a new 'property-set' instance for the given raw properties or returns # an already existing ones. +# rule create ( raw-properties * ) { raw-properties = [ sequence.unique @@ -356,6 +365,7 @@ NATIVE_RULE property-set : create ; # Creates a new 'property-set' instance after checking that all properties are # valid and converting incidental properties into gristed form. +# rule create-with-validation ( raw-properties * ) { property.validate $(raw-properties) ; @@ -365,6 +375,7 @@ rule create-with-validation ( raw-properties * ) # Creates a property-set from the input given by the user, in the context of # 'jamfile-module' at 'location'. +# rule create-from-user-input ( raw-properties * : jamfile-module location ) { local specification = [ property.translate-paths $(raw-properties) @@ -386,8 +397,8 @@ rule create-from-user-input ( raw-properties * : jamfile-module location ) # bound. # - location -- path to which path features are relative. # -rule refine-from-user-input ( parent-requirements : specification * - : project-module : location ) +rule refine-from-user-input ( parent-requirements : specification * : + project-module : location ) { if ! $(specification) { @@ -434,6 +445,7 @@ rule refine-from-user-input ( parent-requirements : specification * # Returns a property-set with an empty set of properties. +# rule empty ( ) { if ! $(.empty) diff --git a/src/build/targets.jam b/src/build/targets.jam index 989af45cf..0737552cf 100644 --- a/src/build/targets.jam +++ b/src/build/targets.jam @@ -507,7 +507,7 @@ class project-target : abstract-target # Import rules from parent. local this-module = [ project-module ] ; local parent-module = [ $(parent).project-module ] ; - # Don't import rules coming from 'project-rules' as they must be + # Do not import rules coming from 'project-rules' as they must be # imported localized. local user-rules = [ set.difference [ RULENAMES $(parent-module) ] : @@ -832,7 +832,7 @@ class file-reference : abstract-target # rule resolve-reference ( target-reference : project ) { - # Separate target name from properties override + # Separate target name from properties override. local split = [ MATCH "^([^<]*)(/(<.*))?$" : $(target-reference) ] ; local id = $(split[1]) ; local sproperties = ; @@ -842,7 +842,7 @@ rule resolve-reference ( target-reference : project ) sproperties = [ feature.expand-composites $(sproperties) ] ; } - # Find the target + # Find the target. local target = [ $(project).find $(id) ] ; return $(target) [ property-set.create $(sproperties) ] ; @@ -880,16 +880,23 @@ rule generate-from-reference ( # Given a build request and requirements, return properties common to dependency -# build request and target build properties. +# build request and target requirements. +# +# TODO: Document exactly what 'common properties' are, whether they should +# include default property values, whether they should contain any conditional +# properties or should those be already processed, etc. See whether there are +# any differences between use cases with empty and non-empty build-request as +# well as with requirements containing and those not containing any non-free +# features. # rule common-properties ( build-request requirements ) { # For optimization, we add free requirements directly, without using a - # complex algorithm. This gives the complex algorithm better chance of + # complex algorithm. This gives the complex algorithm a better chance of # caching results. local free = [ $(requirements).free ] ; - local non-free = [ property-set.create - [ $(requirements).base ] [ $(requirements).incidental ] ] ; + local non-free = [ property-set.create [ $(requirements).base ] + [ $(requirements).incidental ] ] ; local key = .rp.$(build-request)-$(non-free) ; if ! $($(key)) @@ -900,7 +907,7 @@ rule common-properties ( build-request requirements ) } -# Given 'context' -- a set of already present properties, and 'requirements', +# Given a 'context' -- a set of already present properties, and 'requirements', # decide which extra properties should be applied to 'context'. For conditional # requirements, this means evaluating condition. For indirect conditional # requirements, this means calling a rule. Ordinary requirements are always @@ -915,13 +922,13 @@ rule common-properties ( build-request requirements ) # rule evaluate-requirements ( requirements : context : what ) { - # Apply non-conditional requirements. It's possible that further conditional - # requirement change a value set by non-conditional requirements. For - # example: + # Apply non-conditional requirements. It is possible that further + # conditional requirement change a value set by non-conditional + # requirements. For example: # # exe a : a.cpp : single foo:multi ; # - # I'm not sure if this should be an error, or not, especially given that + # I am not sure if this should be an error, or not, especially given that # # single # @@ -932,15 +939,15 @@ rule evaluate-requirements ( requirements : context : what ) local raw = [ $(context).raw ] ; raw = [ property.refine $(raw) : $(unconditional) ] ; - # We've collected properties that surely must be present in common + # We have collected properties that surely must be present in common # properties. We now try to figure out what other properties should be added # in order to satisfy rules (4)-(6) from the docs. local conditionals = [ $(requirements).conditional ] ; # The 'count' variable has one element for each conditional feature and for - # each occurence of '' feature. It's used as a loop + # each occurence of '' feature. It is used as a loop # counter: for each iteration of the loop before we remove one element and - # the property set should stabilize before we're done. It's assumed that + # the property set should stabilize before we are done. It is assumed that # #conditionals iterations should be enough for properties to propagate # along conditions in any direction. local count = $(conditionals) @@ -951,9 +958,9 @@ rule evaluate-requirements ( requirements : context : what ) local current = $(raw) ; - # It's assumed that ordinary conditional requirements can't add - # properties, and that rules referred by - # properties can't add new + # It is assumed that ordinary conditional requirements can not add + # properties, and that rules referred to by + # properties can not add new # properties. So the list of indirect conditionals does not change. local indirect = [ $(requirements).get ] ; indirect = [ MATCH @(.*) : $(indirect) ] ; @@ -979,9 +986,9 @@ rule evaluate-requirements ( requirements : context : what ) } else { - # Oops, results of evaluation of conditionals has changed. Also - # 'current' contains leftover from previous evaluation. Recompute - # 'current' using initial properties and conditional requirements. + # Oops, conditional evaluation results have changed. Also 'current' + # contains leftovers from a previous evaluation. Recompute 'current' + # using initial properties and conditional requirements. added-requirements = $(e) ; current = [ property.refine $(raw) : [ feature.expand $(e) ] ] ; } @@ -989,7 +996,7 @@ rule evaluate-requirements ( requirements : context : what ) } if ! $(ok) { - errors.error "Can't evaluate conditional properties " $(conditionals) ; + errors.error "Can not evaluate conditional properties " $(conditionals) ; } if $(what) = added @@ -1011,18 +1018,18 @@ rule common-properties2 ( build-request requirements ) { # This guarantees that default properties are present in the result, unless # they are overriden by some requirement. FIXME: There is possibility that - # we've added bar, which is composite and expands to bar2, but - # default value of is not bar2, in which case it's not clear what to + # we have added bar, which is composite and expands to bar2, but + # default value of is not bar2, in which case it is not clear what to # do. # build-request = [ $(build-request).add-defaults ] ; # Features added by 'add-default' can be composite and expand to features # without default values -- so they are not added yet. It could be clearer/ - # /faster to expand only newly added properties but that's not critical. + # /faster to expand only newly added properties but that is not critical. build-request = [ $(build-request).expand ] ; - return [ evaluate-requirements $(requirements) - : $(build-request) : refined ] ; + return [ evaluate-requirements $(requirements) : $(build-request) : + refined ] ; } @@ -1177,7 +1184,7 @@ class basic-target : abstract-target if ! $(self.generated.$(property-set)) { - # Apply free features form the command line. If user said + # Apply free features from the command line. If user said # define=FOO # he most likely wants this define to be set for all compiles. property-set = [ $(property-set).refine @@ -1188,7 +1195,7 @@ class basic-target : abstract-target if [ modules.peek : .debug-building ] { ECHO ; - ECHO [ targets.indent ] "Common properties:" [ $(rproperties).raw ] ; + ECHO [ targets.indent ] "Common properties: " [ $(rproperties).raw ] ; } if $(rproperties[1]) != "@error" && [ $(rproperties).get ] != no @@ -1206,8 +1213,8 @@ class basic-target : abstract-target if [ modules.peek : .debug-building ] { ECHO ; - ECHO [ targets.indent ] - "Usage requirements for $(self.name) are " $(usage-requirements) ; + ECHO [ targets.indent ] "Usage requirements for" + $(self.name)": " $(usage-requirements) ; } rproperties = [ property-set.create $(properties) @@ -1216,8 +1223,8 @@ class basic-target : abstract-target if [ modules.peek : .debug-building ] { - ECHO [ targets.indent ] - "Build properties: " [ $(rproperties).raw ] ; + ECHO [ targets.indent ] "Build properties: " + [ $(rproperties).raw ] ; } local extra = [ $(rproperties).get ] ; @@ -1245,9 +1252,8 @@ class basic-target : abstract-target $(s).set-usage-requirements $(ur) ; if [ modules.peek : .debug-building ] { - ECHO [ targets.indent ] - "Usage requirements from $(self.name) are" - [ $(ur).raw ] ; + ECHO [ targets.indent ] "Usage requirements from" + $(self.name)": " [ $(ur).raw ] ; } self.generated.$(property-set) = $(ur) $(result) ; @@ -1262,27 +1268,28 @@ class basic-target : abstract-target } else if [ $(rproperties).get ] = no { - ECHO [ targets.indent ] - "Skipping build of: " [ full-name ] " no in common properties" ; + ECHO [ targets.indent ] "Skipping build of: " [ full-name ] + " no in common properties" ; } else { - ECHO [ targets.indent ] "Skipping build of: " [ full-name ] " unknown reason" ; + ECHO [ targets.indent ] "Skipping build of: " [ full-name ] + " unknown reason" ; } - # We are here either because there's been an error computing - # properties, or there's no in properties. In the latter - # case we don't want any diagnostic. In the former case, we need - # diagnostics. FIXME - - # If this target fails to build, add no to properties - # to cause any parent target to fail to build. Except that it + # We are here either because there has been an error computing + # properties or there is no in properties. In the latter + # case we do not want any diagnostic. In the former case, we + # need diagnostics. FIXME + + # If this target fails to build, add no to properties to + # cause any parent target to fail to build. Except that it # - does not work now, since we check for no only in # common properties, but not in properties that came from # dependencies - # - it's not clear if that's a good idea anyway. The alias - # target, for example, should not fail to build if a dependency - # fails. + # - it is not clear if that is a good idea anyway. The alias + # target, for example, should not fail to build if a + # dependency fails. self.generated.$(property-set) = [ property-set.create no ] ; } } @@ -1293,7 +1300,10 @@ class basic-target : abstract-target ECHO [ targets.indent ] "Already built" ; local ur = $(self.generated.$(property-set)) ; ur = $(ur[0]) ; - ECHO [ targets.indent ] " Usage requirements " [ $(ur).raw ] ; + targets.increase-indent ; + ECHO [ targets.indent ] "Usage requirements from" + $(self.name)": " [ $(ur).raw ] ; + targets.decrease-indent ; } } @@ -1319,7 +1329,7 @@ class basic-target : abstract-target local result = [ property-set.create [ $(xusage-requirements).non-dependency ] $(extra) ] ; - # Propagate usage requirements we've got from sources, except for the + # Propagate usage requirements we got from sources, except for the # and features. # # That feature specifies which pch file to use, and should apply only to diff --git a/src/kernel/class.jam b/src/kernel/class.jam index 3746d7891..18e83bac8 100644 --- a/src/kernel/class.jam +++ b/src/kernel/class.jam @@ -62,13 +62,8 @@ # base-name.method-name. By convention, attribute names are prefixed with # "self.". -import numbers ; -import errors : * ; -import set ; import modules ; -import assert ; - -classes = ; +import numbers ; rule xinit ( instance : class ) @@ -89,10 +84,10 @@ rule new ( class args * : * ) xinit $(id) : $(class) ; INSTANCE $(id) : class@$(class) ; - IMPORT_MODULE $(id) : ; + IMPORT_MODULE $(id) ; $(id).__init__ $(args) : $(2) : $(3) : $(4) : $(5) : $(6) : $(7) : $(8) : $(9) ; - # bump the next unique object name + # Bump the next unique object name. .next-instance = [ numbers.increment $(.next-instance) ] ; # Return the name of the new instance. @@ -102,11 +97,6 @@ rule new ( class args * : * ) rule bases ( class ) { - #if ! ( $(class) in $(classes) ) - #{ - # error class $(class) not defined ; - #} - module class@$(class) { return $(__bases__) ; @@ -116,15 +106,9 @@ rule bases ( class ) rule is-derived ( class : bases + ) { - #local all = $(class) $(bases) ; - #if ! ( $(all) in $(classes) ) - #{ - # error class(es) [ set.difference $(class) $(bases) : $(classes) ] not defined ; - #} - local stack = $(class) ; local visited found ; - while ( ! $(found) ) && $(stack) + while ! $(found) && $(stack) { local top = $(stack[1]) ; stack = $(stack[2-]) ; @@ -154,9 +138,9 @@ rule is-instance ( value ) # Check if the given value is of the given type. # rule is-a ( - instance # The value to check. - : type # The type to test for. - ) + instance # The value to check. + : type # The type to test for. +) { if [ is-instance $(instance) ] { @@ -177,18 +161,18 @@ local rule typecheck ( x ) local rule __test__ ( ) { - import "class" : * ; import assert ; - import errors : * ; + import "class" : new ; # This will be the construction function for a class called 'myclass'. + # class myclass { - import assert : nonempty-variable ; + import assert ; rule __init__ ( x_ * : y_ * ) { - # set some instance variables + # Set some instance variables. x = $(x_) ; y = $(y_) ; foo += 10 ; @@ -265,7 +249,8 @@ local rule __test__ ( ) z = $(z_) ; } - # override g + # Override g. + # rule g ( args * ) { return derived1.g ; @@ -282,16 +267,19 @@ local rule __test__ ( ) } # Check that 'assert.equal' visible in base class is visible here. + # rule invariant2 ( ) { assert.equal 2 : 2 ; } - # Check that 'nonempty-variable' visible in base class is visible here. + # Check that 'assert.variable-not-empty' visible in base class is + # visible here. + # rule invariant3 ( ) { local v = 10 ; - nonempty-variable v ; + assert.nonempty-variable v ; } } # class derived1 : myclass ; @@ -303,17 +291,19 @@ local rule __test__ ( ) myclass.__init__ 1 : 2 ; } - # override g + # Override g. + # rule g ( args * ) { return derived2.g ; } - rule get-x ( ) - { - # Test the ability to call base class functions with qualification. - return [ myclass.get-x ] ; - } + # Test the ability to call base class functions with qualification. + # + rule get-x ( ) + { + return [ myclass.get-x ] ; + } } # class derived2 : myclass ; @@ -339,9 +329,9 @@ local rule __test__ ( ) expect_derived2 $(e) ; # Argument checking is set up to call exit(1) directly on failure, and we - # can't hijack that with try, so we'd better not do this test by default. - # We could fix this by having errors look up and invoke the EXIT rule - # instead; EXIT can be hijacked (;-) + # can not hijack that with try, so we should better not do this test by + # default. We could fix this by having errors look up and invoke the EXIT + # rule instead; EXIT can be hijacked (;-) if --fail-typecheck in [ modules.peek : ARGV ] { try ; @@ -349,8 +339,8 @@ local rule __test__ ( ) expect_derived2 $(a) ; } catch - "Expected an instance of derived2 but got" instead - ; + "Expected an instance of derived2 but got" instead + ; } #try ; diff --git a/src/kernel/errors.jam b/src/kernel/errors.jam old mode 100755 new mode 100644 index 7fae6385b..676d9a02f --- a/src/kernel/errors.jam +++ b/src/kernel/errors.jam @@ -102,7 +102,7 @@ rule catch ( messages * : * ) .last-error-$(.args) = ; error-skip-frames 3 expected \"$(v)\" in argument $(n) of error - : got \"$(joined)\" instead ; + : got \"$(joined)\" instead ; } } } @@ -164,6 +164,7 @@ rule error ( messages * : * ) # Same as 'error', but the generated backtrace will include only user files. +# rule user-error ( messages * : * ) { .user-modules-only = 1 ; @@ -172,6 +173,7 @@ rule user-error ( messages * : * ) # Print a warning message with a stack backtrace and exit. +# rule warning { backtrace 2 warning: $(1) : $(2) : $(3) : $(4) : $(5) : $(6) : $(7) : $(8) : $(9) ; diff --git a/src/kernel/modules.jam b/src/kernel/modules.jam index 4e7833111..8e55db4b7 100644 --- a/src/kernel/modules.jam +++ b/src/kernel/modules.jam @@ -94,7 +94,7 @@ rule peek ( module-name ? : variables + ) # Call the given rule locally in the given module. Use this for rules accepting # rule names as arguments, so that the passed rule may be invoked in the context # of the rule's caller (for example, if the rule accesses module globals or is a -# local rule). Note that rules called this way may accept at most 8 parmeters. +# local rule). Note that rules called this way may accept at most 8 parameters. # rule call-in ( module-name ? : rule-name args * : * ) { @@ -108,7 +108,7 @@ rule call-in ( module-name ? : rule-name args * : * ) # Given a possibly qualified rule name and arguments, remove any initial module # qualification from the rule and invoke it in that module. If there is no # module qualification, the rule is invoked in the global module. Note that -# rules called this way may accept at most 8 parmeters. +# rules called this way may accept at most 8 parameters. # rule call-locally ( qualified-rule-name args * : * ) { diff --git a/src/tools/stage.jam b/src/tools/stage.jam index 5814c4641..bdc42eabf 100644 --- a/src/tools/stage.jam +++ b/src/tools/stage.jam @@ -56,7 +56,6 @@ class install-target-class : basic-target if ! $(loc) { loc = [ path.root $(self.name) [ $(self.project).get location ] ] ; - property-set = [ $(property-set).add-raw $(loc:G=) ] ; } @@ -76,7 +75,7 @@ class install-target-class : basic-target ps-raw = [ $(ps).raw ] ; # Unless true is in properties, which can happen - # only if the user has explicitly requested it, nuke all. + # only if the user has explicitly requested it, nuke all # properties if [ $(property-set).get ] != true { @@ -158,7 +157,7 @@ class install-target-class : basic-target { if $(ename) { - errors.error "In 'install': property specified with target that requires relinking" ; + errors.error "In 'install': property specified with target that requires relinking." ; } else { @@ -200,7 +199,7 @@ class install-target-class : basic-target source-targets = [ collect-targets $(source-targets) ] ; } - # Filter the target types, if needed + # Filter the target types, if needed. local included-types = [ $(property-set).get ] ; for local r in $(source-targets) { @@ -234,7 +233,7 @@ class install-target-class : basic-target return $(result) ; } - # CONSIDER: figure out why we can't use virtual-target.traverse here. + # CONSIDER: figure out why we can not use virtual-target.traverse here. # rule collect-targets ( targets * ) { diff --git a/src/util/assert.jam b/src/util/assert.jam index 293ccbd5c..0d2546089 100644 --- a/src/util/assert.jam +++ b/src/util/assert.jam @@ -1,48 +1,37 @@ -# Copyright 2001, 2002, 2003 Dave Abrahams -# Copyright 2006 Rene Rivera -# Copyright 2002, 2003 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) +# Copyright 2001, 2002, 2003 Dave Abrahams +# Copyright 2006 Rene Rivera +# Copyright 2002, 2003 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) -import errors : error-skip-frames lol->list ; +import errors ; import modules ; -# Assert the equality of A and B. +################################################################################ # -rule equal ( a * : b * ) +# Private implementation details. +# +################################################################################ + +# Rule added as a replacement for the regular Jam = operator but which does not +# ignore trailing empty string elements. +# +local rule exact-equal-test ( lhs * : rhs * ) { - if $(a) != $(b) + local lhs_extended = $(lhs) xxx ; + local rhs_extended = $(rhs) xxx ; + if $(lhs_extended) = $(rhs_extended) { - error-skip-frames 3 assertion failure: \"$(a)\" "!=" \"$(b)\" ; + return true ; } } -# Assert that EXPECTED is the result of calling RULE-NAME with the given -# arguments. +# Two lists are considered set-equal if they contain the same elements, ignoring +# duplicates and ordering. # -rule result ( expected * : rule-name args * : * ) -{ - local result ; - module [ CALLER_MODULE ] - { - modules.poke assert : result - : [ $(2) : $(3) : $(4) : $(5) : $(6) : $(7) : $(8) : $(9) ] ; - } - - if $(result) != $(expected) - { - error-skip-frames 3 assertion failure: "[" $(rule-name) - [ lol->list $(args) : $(3) : $(4) : $(5) : $(6) : $(7) : $(8) : $(9) ] - "]" - : expected: \"$(expected)\" - : got: \"$(result)\" ; - } -} - - -rule .set.equal ( set1 * : set2 * ) +local rule set-equal-test ( set1 * : set2 * ) { if ( $(set1) in $(set2) ) && ( $(set2) in $(set1) ) { @@ -51,61 +40,20 @@ rule .set.equal ( set1 * : set2 * ) } -# Assert that EXPECTED is equal to the result of calling RULE-NAME with the -# given arguments. +################################################################################ # -rule result-equal ( expected * : rule-name args * : * ) -{ - local result ; - module [ CALLER_MODULE ] - { - modules.poke assert : result - : [ $(2) : $(3) : $(4) : $(5) : $(6) : $(7) : $(8) : $(9) ] ; - } - - if ! [ .set.equal $(result) : $(expected) ] - { - error-skip-frames 3 assertion failure: "[" $(rule-name) - [ lol->list $(args) : $(3) : $(4) : $(5) : $(6) : $(7) : $(8) : $(9) ] - "]" - : expected: \"$(expected)\" - : got: \"$(result)\" ; - } -} - - -# Assert that the given variable is nonempty. +# Public interface. # -rule nonempty-variable ( name ) -{ - local value = [ modules.peek [ CALLER_MODULE ] : $(name) ] ; +################################################################################ - if ! $(value)-is-nonempty - { - error-skip-frames 3 assertion failure: expecting non-empty variable $(variable) ; - } -} - - -# Assert that the result of calling RULE-NAME on the given arguments has a true -# logical value (is neither an empty list nor all empty strings). +# Assert the equality of A and B, ignoring trailing empty string elements. # -rule true ( rule-name args * : * ) +rule equal ( a * : b * ) { - local result ; - module [ CALLER_MODULE ] + if $(a) != $(b) { - modules.poke assert : result - : [ $(1) : $(2) : $(3) : $(4) - : $(5) : $(6) : $(7) : $(8) : $(9) ] ; - } - - if ! $(result) - { - error-skip-frames 3 assertion failure: expecting true result from - "[" $(rule-name) - [ lol->list $(args) : $(2) : $(3) : $(4) : $(5) : $(6) : $(7) : $(8) : $(9) ] - "]" ; + errors.error-skip-frames 3 assertion failure: \"$(a)\" "==" \"$(b)\" + (ignoring trailing empty strings) ; } } @@ -124,33 +72,190 @@ rule false ( rule-name args * : * ) if $(result) { - error-skip-frames 3 assertion failure: expecting false result from - "[" $(rule-name) [ lol->list $(args) : $(2) : $(3) : $(4) : $(5) : - $(6) : $(7) : $(8) : $(9) ] "]" : got [ lol->list $(result) ] - instead ; + errors.error-skip-frames 3 assertion failure: Expected false result from + "[" $(rule-name) [ errors.lol->list $(args) : $(2) : $(3) : $(4) : + $(5) : $(6) : $(7) : $(8) : $(9) ] "]" : Got: "[" \"$(result)\" "]" ; } } -# Assert that 'element' is present in 'list'. +# Assert that ELEMENT is present in LIST. # rule "in" ( element : list * ) { if ! $(element) in $(list) { - error-skip-frames 3 assertion failure: expecting $(element) in - "[" $(list) "]" ; + errors.error-skip-frames 3 assertion failure: Expected \"$(element)\" in + "[" \"$(list)\" "]" ; } } -# Assert that 'element' is not present in 'list'. +# Assert the inequality of A and B, ignoring trailing empty string elements. +# +rule not-equal ( a * : b * ) +{ + if $(a) = $(b) + { + errors.error-skip-frames 3 assertion failure: \"$(a)\" "!=" \"$(b)\" + (ignoring trailing empty strings) ; + } +} + + +# Assert that ELEMENT is not present in LIST. # rule not-in ( element : list * ) { if $(element) in $(list) { - error-skip-frames 3 assertion failure: did not expect $(element) in - "[" $(list) "]" ; + errors.error-skip-frames 3 assertion failure: Did not expect + \"$(element)\" in "[" \"$(list)\" "]" ; } } + + +# Assert the inequality of A and B as sets. +# +rule not-set-equal ( a * : b * ) +{ + if [ set-equal-test $(a) : $(b) ] + { + errors.error-skip-frames 3 assertion failure: Expected "[" \"$(a)\" "]" + and "[" \"$(b)\" "]" to not be equal as sets ; + } +} + + +# Assert that A and B are not exactly equal, not ignoring trailing empty string +# elements. +# +rule not-exact-equal ( a * : b * ) +{ + if [ exact-equal-test $(a) : $(b) ] + { + errors.error-skip-frames 3 assertion failure: \"$(a)\" "!=" \"$(b)\" ; + } +} + + +# Assert that EXPECTED is the result of calling RULE-NAME with the given +# arguments. +# +rule result ( expected * : rule-name args * : * ) +{ + local result ; + module [ CALLER_MODULE ] + { + modules.poke assert : result : [ $(2) : $(3) : $(4) : $(5) : $(6) : $(7) + : $(8) : $(9) ] ; + } + + if $(result) != $(expected) + { + errors.error-skip-frames 3 assertion failure: "[" $(rule-name) [ + errors.lol->list $(args) : $(3) : $(4) : $(5) : $(6) : $(7) : $(8) : + $(9) ] "]" : Expected: "[" \"$(expected)\" "]" : Got: "[" + \"$(result)\" "]" ; + } +} + + +# Assert that EXPECTED is set-equal (i.e. duplicates and ordering are ignored) +# to the result of calling RULE-NAME with the given arguments. Note that rules +# called this way may accept at most 8 parameters. +# +rule result-equal ( expected * : rule-name args * : * ) +{ + local result ; + module [ CALLER_MODULE ] + { + modules.poke assert : result : [ $(2) : $(3) : $(4) : $(5) : $(6) : $(7) + : $(8) : $(9) ] ; + } + + if ! [ set-equal-test $(result) : $(expected) ] + { + errors.error-skip-frames 3 assertion failure: "[" $(rule-name) [ + errors.lol->list $(args) : $(3) : $(4) : $(5) : $(6) : $(7) : $(8) : + $(9) ] "]" : Expected: "[" \"$(expected)\" "]" : Got: "[" + \"$(result)\" "]" ; + } +} + + +# Assert the equality of A and B as sets. +# +rule set-equal ( a * : b * ) +{ + if ! [ set-equal-test $(a) : $(b) ] + { + errors.error-skip-frames 3 assertion failure: Expected "[" \"$(a)\" "]" + and "[" \"$(b)\" "]" to be equal as sets ; + } +} + + +# Assert that the result of calling RULE-NAME on the given arguments has a true +# logical value (is neither an empty list nor all empty strings). +# +rule true ( rule-name args * : * ) +{ + local result ; + module [ CALLER_MODULE ] + { + modules.poke assert : result : [ $(1) : $(2) : $(3) : $(4) : $(5) : $(6) + : $(7) : $(8) : $(9) ] ; + } + + if ! $(result) + { + errors.error-skip-frames 3 assertion failure: Expected true result from + "[" $(rule-name) [ errors.lol->list $(args) : $(2) : $(3) : $(4) : + $(5) : $(6) : $(7) : $(8) : $(9) ] "]" ; + } +} + + +# Assert the exact equality of A and B, not ignoring trailing empty string +# elements. +# +rule exact-equal ( a * : b * ) +{ + if ! [ exact-equal-test $(a) : $(b) ] + { + errors.error-skip-frames 3 assertion failure: \"$(a)\" "==" \"$(b)\" ; + } +} + + +# Assert that the given variable is not an empty list. +# +rule nonempty-variable ( name ) +{ + local value = [ modules.peek [ CALLER_MODULE ] : $(name) ] ; + if ! $(value)-is-not-empty + { + errors.error-skip-frames 3 assertion failure: Expected variable + \"$(name)\" not to be an empty list ; + } +} + + +rule __test__ ( ) +{ + # ------------------------- + # assert.set-equal() tests. + # ------------------------- + + set-equal : ; + not-set-equal "" "" : ; + set-equal "" "" : "" ; + set-equal "" "" : "" "" ; + set-equal a b c : a b c ; + set-equal a b c : b c a ; + set-equal a b c a : a b c ; + set-equal a b c : a b c a ; + not-set-equal a b c : a b c d ; + not-set-equal a b c d : a b c ; +} diff --git a/src/util/container.jam b/src/util/container.jam index a37a50c0d..33a45cf99 100644 --- a/src/util/container.jam +++ b/src/util/container.jam @@ -151,7 +151,7 @@ class vector : node { local left = $(self.value[1-$(index)]) ; local right = $(self.value[$(index)-]) ; - if $(right)-is-defined + if $(right)-is-not-empty { left = $(left[1--2]) ; } @@ -192,7 +192,7 @@ class vector : node # rule empty ( ) { - if ! $(self.value)-is-defined + if ! $(self.value)-is-not-empty { return true ; } @@ -248,6 +248,7 @@ local rule __test__ ( ) import "class" : new ; local v1 = [ new vector ] ; + assert.true $(v1).equal $(v1) ; assert.true $(v1).empty ; assert.result 0 : $(v1).size ; assert.result "[" "]" : $(v1).str ; @@ -313,9 +314,13 @@ local rule __test__ ( ) assert.result 111 222 333 444 xxx : $(v7).get ; local v8 = [ new vector "" "" "" ] ; - assert.true $(v7).equal $(v7) ; - assert.result 3 : $(v8).size ; + assert.true $(v8).equal $(v8) ; assert.false $(v8).empty ; + assert.result 3 : $(v8).size ; + assert.result "" : $(v8).at 1 ; + assert.result "" : $(v8).at 2 ; + assert.result "" : $(v8).at 3 ; + assert.result : $(v8).at 4 ; $(v8).insert 2 : 222 ; assert.result 4 : $(v8).size ; assert.result "" 222 "" "" : $(v8).get ; diff --git a/src/util/indirect.jam b/src/util/indirect.jam old mode 100755 new mode 100644 index 749b9479e..c116506fd --- a/src/util/indirect.jam +++ b/src/util/indirect.jam @@ -27,6 +27,7 @@ local rule indirect-rule ( x ) # expected to be the module in which to invoke the rule by the 'call' rule # below. Otherwise, the rule will be invoked in the module of this rule's # caller. +# rule make ( rulename bound-args * : context ? ) { context ?= [ CALLER_MODULE ] ; @@ -40,6 +41,7 @@ rule make ( rulename bound-args * : context ? ) # supplied, the result will be invoked (by 'call', below) in the module of the # caller. Otherwise, frames > 1 specifies additional call frames to back up in # order to find the module context. +# rule make-qualified ( rulename bound-args * : frames ? ) { if [ MATCH $(.pattern) : $(rulename) ] @@ -59,6 +61,7 @@ rule make-qualified ( rulename bound-args * : frames ? ) # Returns the module name in which the given indirect rule will be invoked. +# rule get-module ( [indirect-rule] x ) { local m = [ MATCH $(.pattern) : $(x) ] ; @@ -71,6 +74,7 @@ rule get-module ( [indirect-rule] x ) # Returns the rulename that will be called when x is invoked. +# rule get-rule ( [indirect-rule] x ) { local m = [ MATCH $(.pattern) : $(x) ] ; @@ -79,6 +83,7 @@ rule get-rule ( [indirect-rule] x ) # Invoke the given indirect-rule. +# rule call ( [indirect-rule] r args * : * ) { return [ modules.call-in [ get-module $(r) ] : [ get-rule $(r) ] $(args) diff --git a/src/util/path.jam b/src/util/path.jam index 1fafda787..31e907378 100644 --- a/src/util/path.jam +++ b/src/util/path.jam @@ -510,7 +510,7 @@ rule native-NT ( path ) rule make-UNIX ( native ) { # VP: I have no idea now 'native' can be empty here! But it can! - if $(native) = "" + if ! $(native) { errors.error "Empty path passed to 'make-UNIX'" ; } @@ -815,17 +815,17 @@ rule __test__ ( ) # Test processing 'invalid' rooted paths with too many '..' path elements # that would place them before the root. - assert.result "" : make "/.." ; - assert.result "" : make "/../" ; - assert.result "" : make "/../." ; - assert.result "" : make "/.././" ; - assert.result "" : make "/foo/../bar/giz/.././././../../." ; - assert.result "" : make "/foo/../bar/giz/.././././../.././" ; - assert.result "" : make "//foo/../bar/giz/.././././../../." ; - assert.result "" : make "//foo/../bar/giz/.././././../.././" ; - assert.result "" : make "\\\\foo/../bar/giz/.././././../../." ; - assert.result "" : make "\\\\foo/../bar/giz/.././././../.././" ; - assert.result "" : make "/..///.//..///.//..////foo///" ; + assert.result : make "/.." ; + assert.result : make "/../" ; + assert.result : make "/../." ; + assert.result : make "/.././" ; + assert.result : make "/foo/../bar/giz/.././././../../." ; + assert.result : make "/foo/../bar/giz/.././././../.././" ; + assert.result : make "//foo/../bar/giz/.././././../../." ; + assert.result : make "//foo/../bar/giz/.././././../.././" ; + assert.result : make "\\\\foo/../bar/giz/.././././../../." ; + assert.result : make "\\\\foo/../bar/giz/.././././../.././" ; + assert.result : make "/..///.//..///.//..////foo///" ; assert.result "foo\\bar\\giz" : native "foo/bar/giz" ; assert.result "foo" : native "foo" ;