2
0
mirror of https://github.com/boostorg/build.git synced 2026-02-16 13:22:11 +00:00
Files
build/new/property.jam
Vladimir Prus bceebcf3a1 Bugfix in 'property.refine'.
[SVN r14338]
2002-07-08 09:34:01 +00:00

253 lines
6.8 KiB
Plaintext

# Copyright (C) Vladimir Prus 2002. Permission to copy, use, modify, sell and
# distribute this software is granted provided this copyright notice appears in
# all copies. This software is provided "as is" without express or implied
# warranty, and with no claim as to its suitability for any purpose.
import feature ;
import utility : ungrist ;
import sequence : unique ;
import errors : error ;
# Refines 'properties' by overriding any elements for which a different
# value is specified in 'requirements'. If the resulting property set
# will be link-incompatible with 'properties', it is an error.
# On success, returns properties. On error, returns a list which first
# element is "@error" and the other elements compose the explanation
# string.
rule refine ( properties * : requirements * : feature-space ? )
{
feature-space ?= feature ;
local result ;
local error ;
# All the elements of requirements should be present in the result
# Record them so that we can handle 'properties'.
for local r in $(requirements)
{
# Note: cannot use local here, so take an ugly name
__require__$(r:G) = $(r:G=) ;
}
for local p in $(properties)
{
# No processing for free properties
if free in [ $(feature-space).attributes $(p:G) ]
{
result += $(p) ;
}
else
{
local required-value = $(__require__$(p:G)) ;
if $(required-value)
{
local value = $(p:G=) ;
if $(value) != $(required-value)
{
if link-incompatible in [ $(feature-space).attributes $(p:G) ]
{
error = @error link-incompatible properties $(p) and
$(p:G)$(required-value) ;
# Cannot break, so just iterate again
}
else
{
result += $(p:G)$(required-value) ;
}
}
else
{
result += $(p) ;
}
}
else
{
result += $(p) ;
}
}
}
# Unset our ugly map.
for local r in $(requirements)
{
__require__$(r:G) = ;
}
if $(error)
{
return $(error) ;
}
else
{
return [ unique $(result) $(requirements) ] ;
}
}
# Helper for as-path, below. Orders properties with the implicit ones
# first, and within the two sections in alphabetical order of feature
# name.
local rule path-order ( feature-space x y )
{
if $(y:G) && ! $(x:G)
{
return true ;
}
else if $(x:G) && ! $(y:G)
{
return ;
}
else
{
if ! $(x:G)
{
x = [ $(feature-space).expand-subfeatures $(x) ] ;
y = [ $(feature-space).expand-subfeatures $(y) ] ;
}
if $(x[0]) < $(y[0])
{
return true ;
}
}
}
# Returns a path which represents the given expanded property set.
rule as-path ( properties * : feature-space ? )
{
feature-space ?= feature ;
# trim redundancy
properties = [ $(feature-space).minimize $(properties) ] ;
# sort according to path-order
properties = [ sequence.insertion-sort $(properties) : path-order $(feature-space) ] ;
local components ;
for local p in $(properties)
{
if $(p:G)
{
local f = [ ungrist $(p:G) ] ;
components += $(f)-$(p:G=) ;
}
else
{
components += $(p) ;
}
}
return $(components:J=/) ;
}
# Exit with error if property is not valid.
rule validate ( property : feature-space ? )
{
feature-space ?= feature ;
local msg ;
if $(property:G)
{
local feature = [ ungrist $(property:G) ] ; # Ungrist for better error messages
local value = $(property:G=) ;
if ! [ $(feature-space).valid $(feature) ]
{
msg = "unknown feature '$(feature)'" ;
}
else if $(value) && ! $(value) in [ $(feature-space).values $(feature) ]
&& ! free in [ $(feature-space).attributes $(feature) ]
{
msg = "value '"$(value:J=" ")"' is not valid for feature'"$(feature)' ;
}
else if ! $(value)
{
msg = "No value specified for feature '$(feature)'" ;
}
}
else
{
if ! [ $(feature-space).is-implicit-value $(property) ]
{
msg = '$(property:J=" ")' "is not a value of implicit feature" ;
}
}
if $(msg)
{
error "Invalid property "'$(property:J=" ")'": "$(msg:J=" "). ;
}
}
local rule __test__ ( )
{
import class : new ;
import errors : try catch ;
local test-space = [ new feature-space ] ;
module $(test-space)
{
import assert ;
feature toolset : gcc : implicit ;
feature define : : free ;
feature runtime-link : dynamic static : symmetric link-incompatible ;
feature optimization : on off ;
feature variant : debug release : implicit composite ;
feature rtti : on off : link-incompatible ;
compose <variant>debug : <define>_DEBUG <optimization>off ;
compose <variant>release : <define>NDEBUG <optimization>on ;
}
assert.result <toolset>gcc <rtti>off <define>FOO
: refine <toolset>gcc <rtti>off
: <define>FOO
: $(test-space)
;
assert.result <toolset>gcc <optimization>on
: refine <toolset>gcc <optimization>off
: <optimization>on
: $(test-space)
;
assert.result <toolset>gcc <rtti>off
: refine <toolset>gcc : <rtti>off : $(test-space)
;
assert.result debug
: as-path <optimization>off <variant>debug
: $(test-space)
;
assert.result gcc/debug/rtti-off
: as-path <toolset>gcc <optimization>off <rtti>off <variant>debug
: $(test-space)
;
r = [ refine <toolset>gcc <rtti>off
: <rtti>on
: $(test-space) ] ;
assert.equal $(r[1]) : "@error" ;
try ;
validate <feature>value : $(test-space) ;
catch "Invalid property '<feature>value': unknown feature 'feature'." ;
try ;
validate <rtti>default : $(test-space) ;
catch "Invalid property '<rtti>default': value 'default' is not valid for feature'rtti'." ;
validate <define>WHATEVER : $(test-space) ;
try ;
validate <rtti> : $(test-space) ;
catch "Invalid property '<rtti>': No value specified for feature 'rtti'." ;
try ;
validate value : $(test-space) ;
catch "Invalid property 'value': 'value' is not a value of implicit feature." ;
}