📄 feature.jam
字号:
$(feature).values += $(values) ;}# Checks that value-string is a valid value-string for the given feature.#rule validate-value-string ( feature value-string ){ if ! ( free in $($(feature).attributes) || ( $(value-string) in $(feature).values ) ) { local values = $(value-string) ; if $($(feature).subfeatures) { values = [ regex.split $(value-string) - ] ; } if ! ( $(values[1]) in $($(feature).values) ) && # An empty value is allowed for optional features. ( $(values[1]) || ! ( optional in $($(feature).attributes) ) ) { errors.error \"$(values[1])\" is not a known value of feature $(feature) : legal values: \"$($(feature).values)\" ; } for local v in $(values[2-]) { # This will validate any subfeature values in value-string. implied-subfeature $(feature) $(v) : $(values[1]) ; } }}# A helper that computes:# * name(s) of module-local variable(s) used to record the correspondence# 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 # feature for which the subfeature values are valid. : subfeature # Subfeature name. : subvalues * # Subfeature values.){ feature = [ grist $(feature) ] ; validate-feature $(feature) ; if $(value-string) { validate-value-string $(feature) $(value-string) ; } local subfeature-name = [ get-subfeature-name $(subfeature) $(value-string) ] ; return $(subfeature-name) $(feature)$(value-string:E="")<>$(subvalues).subfeature ;}# Extends the given subfeature with the subvalues. If the optional value-string# is provided, the subvalues are only valid for the given value of the feature.# Thus, you could say that <target-platform>mingw is specific to# <toolset>gcc-2.95.2 as follows:## extend-subfeature toolset gcc-2.95.2 : target-platform : mingw ;#rule extend-subfeature ( feature # The feature whose subfeature is being extended. value-string ? # If supplied, specifies a specific value of the main # feature for which the new subfeature values are valid. : subfeature # Subfeature name. : subvalues * # Additional subfeature values.){ local subfeature-vars = [ subvalue-var $(feature) $(value-string) : $(subfeature) : $(subvalues) ] ; local f = [ utility.ungrist [ grist $(feature) ] ] ; extend $(f)-$(subfeature-vars[1]) : $(subvalues) ; # Provide a way to get from the given feature or property and subfeature # value to the subfeature name. $(subfeature-vars[2-]) = $(subfeature-vars[1]) ;}# 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) : $(subfeature) : $(subvalue) ] ; if $($(subfeature-vars[2])) = $(subfeature-vars[1]) { return true ; }}# Can be called three ways:## 1. extend feature : values *# 2. extend <feature> subfeature : values *# 3. extend <feature>value-string subfeature : values *## * Form 1 adds the given values to the given feature.# * Forms 2 and 3 add subfeature values to the given feature.# * Form 3 adds the subfeature values as specific to the given property# value-string.#rule extend ( feature-or-property subfeature ? : values * ){ local feature ; # If a property was specified this is its feature. local value-string ; # E.g., the gcc-2.95-2 part of <toolset>gcc-2.95.2. # If a property was specified. if $(feature-or-property:G) && $(feature-or-property:G=) { # Extract the feature and value-string, if any. feature = $(feature-or-property:G) ; value-string = $(feature-or-property:G=) ; } else { feature = [ grist $(feature-or-property) ] ; } # Dispatch to the appropriate handler. if $(subfeature) { extend-subfeature $(feature) $(value-string) : $(subfeature) : $(values) ; } else { # If no subfeature was specified, we do not expect to see a # value-string. if $(value-string) { errors.error can only specify a property as the first argument when extending a subfeature : usage: : " extend" feature ":" values... : " | extend" <feature>value-string subfeature ":" values... ; } extend-feature $(feature) : $(values) ; }}local rule get-subfeature-name ( subfeature value-string ? ){ local prefix = $(value-string): ; return $(prefix:E="")$(subfeature) ;}# Declares a subfeature.#rule subfeature ( feature # Root feature that is not a subfeature. value-string ? # A value-string specifying which feature or subfeature # values this subfeature is specific to, if any. : subfeature # The name of the subfeature being declared. : subvalues * # The allowed values of this subfeature. : attributes * # The attributes of the subfeature.){ feature = [ grist $(feature) ] ; validate-feature $(feature) ; # Add grist to the subfeature name if a value-string was supplied. local subfeature-name = [ get-subfeature-name $(subfeature) $(value-string) ] ; if $(subfeature-name) in $($(feature).subfeatures) { errors.error \"$(subfeature)\" already declared as a subfeature of \"$(feature)\" "specific to "$(value-string) ; } $(feature).subfeatures += $(subfeature-name) ; # First declare the subfeature as a feature in its own right. local f = [ utility.ungrist $(feature) ] ; feature $(f)-$(subfeature-name) : $(subvalues) : $(attributes) subfeature ; # Now make sure the subfeature values are known. extend-subfeature $(feature) $(value-string) : $(subfeature) : $(subvalues) ;}# Set components of the given composite property.#rule compose ( composite-property : component-properties * ){ local feature = $(composite-property:G) ; if ! ( composite in [ attributes $(feature) ] ) { errors.error "$(feature)" is not a composite feature ; } $(composite-property).components ?= ; if $($(composite-property).components) { errors.error components of "$(composite-property)" already set: $($(composite-property).components) ; } if $(composite-property) in $(component-properties) { errors.error composite property "$(composite-property)" cannot have itself as a component ; } $(composite-property).components = $(component-properties) ;}local rule expand-composite ( property ){ return $(property) [ sequence.transform expand-composite : $($(property).components) ] ;}# Return all values of the given feature specified by the given property set.#rule get-values ( feature : properties * ){ local result ; feature = $(:E=:G=$(feature)) ; # Add <> if necessary. for local p in $(properties) { if $(p:G) = $(feature) { # Use MATCH instead of :G= to get the value, in order to preserve # the value intact instead of having bjam treat it as a decomposable # path. result += [ MATCH ">(.*)" : $(p) ] ; } } return $(result) ;}rule free-features ( ){ return $(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) ; local result ; # Now expand composite features. for local p in $(properties) { local expanded = [ expand-composite $(p) ] ; for local x in $(expanded) { if ! $(x) in $(result) { local f = $(x:G) ; if $(f) in $(free.features) { result += $(x) ; } else if ! $(x) in $(properties) # x is the result of expansion { if ! $(f) in $(explicit-features) # not explicitly-specified { if $(f) in $(result:G) { errors.error expansions of composite features result in conflicting values for $(f) : values: [ get-values $(f) : $(result) ] $(x:G=) : one contributing composite property was $(p) ; } else { result += $(x) ; } } } else if $(f) in $(result:G) { errors.error explicitly-specified values of non-free feature $(f) conflict : "existing values:" [ get-values $(f) : $(properties) ] : "value from expanding " $(p) ":" $(x:G=) ; } else { result += $(x) ; } } } } return $(result) ;}# 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) { local specific-subfeature = [ MATCH <(.*):(.*)> : $(f) ] ; if $(specific-subfeature) { # The feature has the form <topfeature-topvalue:subfeature>, e.g. # <toolset-msvc:version>. local feature-value = [ split-top-feature $(specific-subfeature[1]) ] ; if <$(feature-value[1])>$(feature-value[2]) = $(parent-property) { return true ; } } else { # The feature has the form <topfeature-subfeature>, e.g. # <toolset-version> local top-sub = [ split-top-feature [ utility.ungrist $(f) ] ] ; if $(top-sub[2]) && <$(top-sub[1])> = $(parent-property:G) { return true ; } } }}# As for is-subfeature-of but for subproperties.#local rule is-subproperty-of ( parent-property p ){ return [ is-subfeature-of $(parent-property) $(p:G) ] ;}# 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) ] ;}# As for select-subfeatures but for subproperties.#local rule select-subproperties ( parent-property : properties * ){ return [ sequence.filter is-subproperty-of $(parent-property) : $(properties) ] ;}# Given a property set which may consist of composite and implicit properties# and combined subfeature values, returns an expanded, normalized property set# with all implicit features expressed explicitly, all subfeature values# individually expressed, and all components of composite properties expanded.# Non-free features directly expressed in the input properties cause any values# 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) ] ; return [ expand-composites $(expanded) ] ;}# 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)) { return true ; }}# 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 ; local x2 ; for local p in $(properties) { if subfeature in $($(p:G).attributes) { x2 += $(p) ; } else { x1 += $(p) ; } } return $(x1) $(x2) ;}# Given an expanded property set, eliminate all redundancy: properties that are# elements of other (composite) properties in the set will be eliminated.# Non-symmetric properties equal to default values will be eliminated unless# 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 * ){
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -