📄 property.jam
字号:
# Copyright 2001, 2002, 2003 Dave Abrahams# Copyright 2006 Rene Rivera# Copyright 2002, 2003, 2004, 2005, 2006 Vladimir Prus# Distributed under the Boost Software License, Version 1.0.# (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)import errors ;import feature ;import indirect ;import path ;import regex ;import string ;import sequence ;import set ;import utility ;# Refines 'properties' by overriding any non-free and non-conditional properties# for which a different value is specified in 'requirements'. Returns the# resulting list of properties.#rule refine ( properties * : requirements * ){ local result ; local error ; # All the 'requirements' elements should be present in the result. Record # them so that we can handle 'properties'. for local r in $(requirements) { # Do not consider conditional requirements. if ! [ MATCH (:) : $(r:G=) ] { # Note: cannot use a local variable here, so use an ugly name. __require__$(r:G) = $(r:G=) ; } } for local p in $(properties) { if [ MATCH (:) : $(p:G=) ] { # Do not modify conditional properties. result += $(p) ; } else if free in [ feature.attributes $(p:G) ] { # Do not modify free properties. result += $(p) ; } else { local required-value = $(__require__$(p:G)) ; if $(required-value) { if $(p:G=) != $(required-value) { 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 [ sequence.unique $(result) $(requirements) ] ; }}# Removes all conditional properties whose conditions are not met. For those# with met conditions, removes the condition. Properties in conditions are# looked up in 'context'.#rule evaluate-conditionals-in-context ( properties * : context * ){ local base ; local conditionals ; for local p in $(properties) { if [ MATCH (:<) : $(p) ] { conditionals += $(p) ; } else { base += $(p) ; } } local result = $(base) ; for local p in $(conditionals) { # Separate condition and property. local s = [ MATCH (.*):(<.*) : $(p) ] ; # Split condition into individual properties. local c = [ regex.split $(s[1]) "," ] ; # Evaluate condition. if $(c) in $(context) { result += $(s[2]) ; } } return $(result) ;}rule expand-subfeatures-in-conditions ( properties * ){ local result ; for local p in $(properties) { local s = [ MATCH (.*):(<.*) : $(p) ] ; if ! $(s) { result += $(p) ; } else { local condition = $(s[1]) ; local value = $(s[2]) ; # Condition might include several elements. condition = [ regex.split $(condition) "," ] ; local e ; for local c in $(condition) { # It is common for a condition to include a toolset or # subfeatures that have not been defined. In that case we want # the condition to simply 'never be satisfied' and validation # would only produce a spurious error so we prevent it by # passing 'true' as the second parameter. e += [ feature.expand-subfeatures $(c) : true ] ; } if $(e) = $(condition) { # (todo) # This is just an optimization and possibly a premature one at # that. # (todo) (12.07.2008.) (Jurko) result += $(p) ; } else { result += $(e:J=,):$(value) ; } } } return $(result) ;}# 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 ( x y ){ if $(y:G) && ! $(x:G) { return true ; } else if $(x:G) && ! $(y:G) { return ; } else { if ! $(x:G) { x = [ feature.expand-subfeatures $(x) ] ; y = [ feature.expand-subfeatures $(y) ] ; } if $(x[1]) < $(y[1]) { return true ; } }}local rule abbreviate-dashed ( string ){ local r ; for local part in [ regex.split $(string) - ] { r += [ string.abbreviate $(part) ] ; } return $(r:J=-) ;}local rule identity ( string ){ return $(string) ;}if --abbreviate-paths in [ modules.peek : ARGV ]{ .abbrev = abbreviate-dashed ;}else{ .abbrev = identity ;}# Returns a path representing the given expanded property set.#rule as-path ( properties * ){ local entry = .result.$(properties:J=-) ; if ! $($(entry)) { # Trim redundancy. properties = [ feature.minimize $(properties) ] ; # Sort according to path-order. properties = [ sequence.insertion-sort $(properties) : path-order ] ; local components ; for local p in $(properties) { if $(p:G) { local f = [ utility.ungrist $(p:G) ] ; p = $(f)-$(p:G=) ; } components += [ $(.abbrev) $(p) ] ; } $(entry) = $(components:J=/) ; } return $($(entry)) ;}# Exit with error if property is not valid.#local rule validate1 ( property ){ local msg ; if $(property:G) { local feature = $(property:G) ; local value = $(property:G=) ; if ! [ feature.valid $(feature) ] { # Ungrist for better error messages. feature = [ utility.ungrist $(property:G) ] ; msg = "unknown feature '$(feature)'" ; } else if $(value) && ! free in [ feature.attributes $(feature) ] { feature.validate-value-string $(feature) $(value) ; } else if ! ( $(value) || ( optional in [ feature.attributes $(feature) ] ) ) { # Ungrist for better error messages. feature = [ utility.ungrist $(property:G) ] ; msg = "No value specified for feature '$(feature)'" ; } } else { local feature = [ feature.implied-feature $(property) ] ; feature.validate-value-string $(feature) $(property) ; } if $(msg) { errors.error "Invalid property "'$(property:J=" ")'": "$(msg:J=" "). ; }}rule validate ( properties * ){ for local p in $(properties) { validate1 $(p) ; }}rule validate-property-sets ( property-sets * ){ for local s in $(property-sets) { validate [ feature.split $(s) ] ; }}# Expands any implicit property values in the given property 'specification' so# they explicitly state their feature.#rule make ( specification * ){ local result ; for local e in $(specification) { if $(e:G) { result += $(e) ; } else if [ feature.is-implicit-value $(e) ] { local feature = [ feature.implied-feature $(e) ] ; result += $(feature)$(e) ; } else { errors.error "'$(e)' is not a valid property specification" ; } } return $(result) ;}# Returns a property set containing all the elements in 'properties' that do not# have their attributes listed in 'attributes'.#rule remove ( attributes + : properties * ){ local result ; for local e in $(properties) { if ! [ set.intersection $(attributes) : [ feature.attributes $(e:G) ] ] { result += $(e) ; } } return $(result) ;}# Returns a property set containing all the elements in 'properties' that have# their attributes listed in 'attributes'.#rule take ( attributes + : properties * ){ local result ; for local e in $(properties) { if [ set.intersection $(attributes) : [ feature.attributes $(e:G) ] ] { result += $(e) ; } } return $(result) ;}# Selects properties corresponding to any of the given features.#rule select ( features * : properties * )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -