2
0
mirror of https://github.com/boostorg/build.git synced 2026-02-13 00:12:11 +00:00

Minor stylistic Boost Build script changes.

[SVN r46254]
This commit is contained in:
Jurko Gospodnetić
2008-06-08 19:41:56 +00:00
parent a4aa88a4f3
commit 39e67e8f0d
12 changed files with 439 additions and 260 deletions

View File

@@ -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:
#
# <toolset>gcc <toolset-version>2.95.2 <toolset-os>linux <toolset-cpu>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 )
# <variant>debug <runtime_debugging>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.

View File

@@ -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 * )

View File

@@ -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)

View File

@@ -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 : <threading>single <toolset>foo:<threading>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
#
# <threading>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 '<indirect-conditional>' feature. It's used as a loop
# each occurence of '<indirect-conditional>' 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
# <indirect-conditional> properties, and that rules referred by
# <indirect-conditional> properties can't add new <indirect-conditional>
# It is assumed that ordinary conditional requirements can not add
# <indirect-conditional> properties, and that rules referred to by
# <indirect-conditional> properties can not add new <indirect-conditional>
# properties. So the list of indirect conditionals does not change.
local indirect = [ $(requirements).get <conditional> ] ;
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 <foo>bar, which is composite and expands to <foo2>bar2, but
# default value of <foo2> is not bar2, in which case it's not clear what to
# we have added <foo>bar, which is composite and expands to <foo2>bar2, but
# default value of <foo2> 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 <build> ] != 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 <source> ] ;
@@ -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 <build> ] = no
{
ECHO [ targets.indent ]
"Skipping build of: " [ full-name ] " <build>no in common properties" ;
ECHO [ targets.indent ] "Skipping build of: " [ full-name ]
" <build>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 <build>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 <build>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 <build>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 <build>no to properties to
# cause any parent target to fail to build. Except that it
# - does not work now, since we check for <build>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 <build>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
# <pch-header> and <pch-file> features.
#
# That feature specifies which pch file to use, and should apply only to

View File

@@ -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 ;

4
src/kernel/errors.jam Executable file → Normal file
View File

@@ -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) ;

View File

@@ -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 * : * )
{

View File

@@ -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=<location>) ] ;
}
@@ -76,7 +75,7 @@ class install-target-class : basic-target
ps-raw = [ $(ps).raw ] ;
# Unless <hardcode-dll-paths>true is in properties, which can happen
# only if the user has explicitly requested it, nuke all.
# only if the user has explicitly requested it, nuke all
# <dll-path> properties
if [ $(property-set).get <hardcode-dll-paths> ] != true
{
@@ -158,7 +157,7 @@ class install-target-class : basic-target
{
if $(ename)
{
errors.error "In 'install': <name> property specified with target that requires relinking" ;
errors.error "In 'install': <name> 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 <install-type> ] ;
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 * )
{

View File

@@ -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 ;
}

View File

@@ -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 ;

5
src/util/indirect.jam Executable file → Normal file
View File

@@ -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)

View File

@@ -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" ;