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:
@@ -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.
|
||||
|
||||
@@ -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 * )
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
4
src/kernel/errors.jam
Executable file → Normal 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) ;
|
||||
|
||||
@@ -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 * : * )
|
||||
{
|
||||
|
||||
@@ -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 * )
|
||||
{
|
||||
|
||||
@@ -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 ;
|
||||
}
|
||||
|
||||
@@ -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
5
src/util/indirect.jam
Executable file → Normal 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)
|
||||
|
||||
@@ -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" ;
|
||||
|
||||
Reference in New Issue
Block a user