| |
| |
| |
| |
| |
|
|
| |
|
|
| import errors ; |
| import feature ; |
| import generators ; |
| import numbers ; |
| import path ; |
| import property ; |
| import regex ; |
| import sequence ; |
| import set ; |
| import property-set ; |
|
|
|
|
| .flag-no = 1 ; |
|
|
| .ignore-requirements = ; |
|
|
| |
| |
| if --ignore-toolset-requirements in [ modules.peek : ARGV ] |
| { |
| .ignore-requirements = 1 ; |
| } |
|
|
|
|
| |
| |
| |
| rule using ( toolset-module : * ) |
| { |
| import $(toolset-module) ; |
| $(toolset-module).init $(2) : $(3) : $(4) : $(5) : $(6) : $(7) : $(8) : $(9) ; |
| } |
|
|
|
|
| |
| |
| |
| local rule normalize-condition ( property-sets * ) |
| { |
| local result ; |
| for local p in $(property-sets) |
| { |
| local split = [ feature.split $(p) ] ; |
| local expanded = [ feature.expand-subfeatures [ feature.split $(p) ] ] ; |
| result += $(expanded:J=/) ; |
| } |
| return $(result) ; |
| } |
|
|
|
|
| |
| |
| |
| |
| |
| rule push-checking-for-flags-module ( v ) |
| { |
| .flags-module-checking = $(v) $(.flags-module-checking) ; |
| } |
|
|
| rule pop-checking-for-flags-module ( ) |
| { |
| .flags-module-checking = $(.flags-module-checking[2-]) ; |
| } |
|
|
|
|
| |
| |
| |
| rule flags ( |
| rule-or-module |
| |
| |
| |
| |
| |
| |
| |
|
|
| variable-name |
| condition * : |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
| values * : |
| |
| unchecked ? |
| |
| : hack-hack ? |
| |
| |
| |
| ) |
| { |
| local caller = [ CALLER_MODULE ] ; |
| if ! [ MATCH ".*([.]).*" : $(rule-or-module) ] |
| && [ MATCH "(Jamfile<.*)" : $(caller) ] |
| { |
| |
| |
| |
| |
| |
| rule-or-module = $(caller).$(rule-or-module) ; |
| } |
| else |
| { |
| local module_ = [ MATCH "([^.]*).*" : $(rule-or-module) ] ; |
| if $(unchecked) != unchecked |
| && $(.flags-module-checking[1]) != unchecked |
| && $(module_) != $(caller) |
| { |
| errors.error "Module $(caller) attempted to set flags for module $(module_)" ; |
| } |
| } |
|
|
| if $(condition) && ! $(condition:G=) && ! $(hack-hack) |
| { |
| |
| |
| |
| |
| |
| values = $(condition) ; |
| condition = ; |
| } |
|
|
| if $(condition) |
| { |
| property.validate-property-sets $(condition) ; |
| condition = [ normalize-condition $(condition) ] ; |
| } |
|
|
| add-flag $(rule-or-module) : $(variable-name) : $(condition) : $(values) ; |
| } |
|
|
|
|
| |
| |
| local rule add-flag ( rule-or-module : variable-name : condition * : values * ) |
| { |
| .$(rule-or-module).flags += $(.flag-no) ; |
|
|
| |
| local module_ = [ MATCH "([^.]*).*" : $(rule-or-module) ] ; |
| .module-flags.$(module_) += $(.flag-no) ; |
| |
| .rule-or-module.$(.flag-no) = $(rule-or-module) ; |
|
|
| .$(rule-or-module).variable.$(.flag-no) += $(variable-name) ; |
| .$(rule-or-module).values.$(.flag-no) += $(values) ; |
| .$(rule-or-module).condition.$(.flag-no) += $(condition) ; |
|
|
| .flag-no = [ numbers.increment $(.flag-no) ] ; |
| } |
|
|
|
|
| |
| |
| |
| rule find-property-subset ( property-sets * : properties * ) |
| { |
| |
| local prop-keys = $(properties:G) ; |
|
|
| local result ; |
| for local s in $(property-sets) |
| { |
| if ! $(result) |
| { |
| |
| |
|
|
| local set = [ feature.split $(s) ] ; |
|
|
| |
| |
| |
| local default-props ; |
| for local i in $(set) |
| { |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| if ! ( $(i:G=) || ( $(i:G) in $(prop-keys) ) ) |
| { |
| default-props += $(i) ; |
| } |
| } |
|
|
| if $(set) in $(properties) $(default-props) |
| { |
| result = $(s) ; |
| } |
| } |
| } |
| return $(result) ; |
| } |
|
|
|
|
| |
| |
| |
| rule handle-flag-value ( value * : properties * ) |
| { |
| local result ; |
| if $(value:G) |
| { |
| local matches = [ property.select $(value) : $(properties) ] ; |
| for local p in $(matches) |
| { |
| local att = [ feature.attributes $(p:G) ] ; |
| if dependency in $(att) |
| { |
| |
| |
| result += [ $(p:G=).actualize ] ; |
| } |
| else if path in $(att) || free in $(att) |
| { |
| local values ; |
| |
| |
| |
| |
| if ! [ MATCH (&&) : $(p:G=) ] |
| { |
| values = $(p:G=) ; |
| } |
| else |
| { |
| values = [ regex.split $(p:G=) "&&" ] ; |
| } |
| if path in $(att) |
| { |
| result += [ sequence.transform path.native : $(values) ] ; |
| } |
| else |
| { |
| result += $(values) ; |
| } |
| } |
| else |
| { |
| result += $(p:G=) ; |
| } |
| } |
| } |
| else |
| { |
| result += $(value) ; |
| } |
| return $(result) ; |
| } |
|
|
|
|
| |
| |
| |
| |
| rule set-target-variables-aux ( rule-or-module : property-set ) |
| { |
| local result ; |
| properties = [ $(property-set).raw ] ; |
| for local f in $(.$(rule-or-module).flags) |
| { |
| local variable = $(.$(rule-or-module).variable.$(f)) ; |
| local condition = $(.$(rule-or-module).condition.$(f)) ; |
| local values = $(.$(rule-or-module).values.$(f)) ; |
|
|
| if ! $(condition) || |
| [ find-property-subset $(condition) : $(properties) ] |
| { |
| local processed ; |
| for local v in $(values) |
| { |
| |
| processed += [ handle-flag-value $(v) : $(properties) ] ; |
| } |
| for local r in $(processed) |
| { |
| result += $(variable) $(r) ; |
| } |
| } |
| } |
|
|
| |
| local next = [ MATCH ^(.+)\\.([^\\.])* : $(rule-or-module) ] ; |
| if $(next) |
| { |
| result += [ set-target-variables-aux $(next[1]) : $(property-set) ] ; |
| } |
| return $(result) ; |
| } |
|
|
| rule relevant-features ( rule-or-module ) |
| { |
| local result ; |
| if ! $(.relevant-features.$(rule-or-module)) |
| { |
| for local f in $(.$(rule-or-module).flags) |
| { |
| local condition = $(.$(rule-or-module).condition.$(f)) ; |
| local values = $(.$(rule-or-module).values.$(f)) ; |
|
|
| for local c in $(condition) |
| { |
| for local p in [ feature.split $(c) ] |
| { |
| if $(p:G) |
| { |
| result += $(p:G) ; |
| } |
| else |
| { |
| local temp = [ feature.expand-subfeatures $(p) ] ; |
| result += $(temp:G) ; |
| } |
| } |
| } |
|
|
| for local v in $(values) |
| { |
| if $(v:G) |
| { |
| result += $(v:G) ; |
| } |
| } |
| } |
|
|
| |
| local next = [ MATCH ^(.+)\\.([^\\.])* : $(rule-or-module) ] ; |
| if $(next) |
| { |
| result += [ relevant-features $(next[1]) ] ; |
| } |
| result = [ sequence.unique $(result) ] ; |
| if $(result[1]) = "" |
| { |
| result = $(result) ; |
| } |
| .relevant-features.$(rule-or-module) = $(result) ; |
| return $(result) ; |
| } |
| else |
| { |
| return $(.relevant-features.$(rule-or-module)) ; |
| } |
| } |
|
|
| rule filter-property-set ( rule-or-module : property-set ) |
| { |
| if ! $(.filtered.property-set.$(rule-or-module).$(property-set)) |
| { |
| local relevant = [ relevant-features $(rule-or-module) ] ; |
| local result ; |
| for local p in [ $(property-set).raw ] |
| { |
| if $(p:G) in $(relevant) |
| { |
| result += $(p) ; |
| } |
| } |
| .filtered.property-set.$(rule-or-module).$(property-set) = [ property-set.create $(result) ] ; |
| } |
| return $(.filtered.property-set.$(rule-or-module).$(property-set)) ; |
| } |
|
|
| rule set-target-variables ( rule-or-module targets + : property-set ) |
| { |
| property-set = [ filter-property-set $(rule-or-module) : $(property-set) ] ; |
| local key = $(rule-or-module).$(property-set) ; |
| local settings = $(.stv.$(key)) ; |
| if ! $(settings) |
| { |
| settings = [ set-target-variables-aux $(rule-or-module) : |
| $(property-set) ] ; |
|
|
| if ! $(settings) |
| { |
| settings = none ; |
| } |
| .stv.$(key) = $(settings) ; |
| } |
|
|
| if $(settings) != none |
| { |
| local var-name = ; |
| for local name-or-value in $(settings) |
| { |
| if $(var-name) |
| { |
| $(var-name) on $(targets) += $(name-or-value) ; |
| var-name = ; |
| } |
| else |
| { |
| var-name = $(name-or-value) ; |
| } |
| } |
| } |
| } |
|
|
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| rule inherit ( toolset : base ) |
| { |
| import $(base) ; |
| inherit-generators $(toolset) : $(base) ; |
| inherit-flags $(toolset) : $(base) ; |
| inherit-rules $(toolset) : $(base) ; |
| } |
|
|
|
|
| rule inherit-generators ( toolset properties * : base : generators-to-ignore * ) |
| { |
| properties ?= <toolset>$(toolset) ; |
| local base-generators = [ generators.generators-for-toolset $(base) ] ; |
| for local g in $(base-generators) |
| { |
| local id = [ $(g).id ] ; |
|
|
| if ! $(id) in $(generators-to-ignore) |
| { |
| |
| |
| |
| |
| |
| |
| local base = $(id) ; |
| local suffix = "" ; |
| while $(base:S) |
| { |
| suffix = $(base:S)$(suffix) ; |
| base = $(base:B) ; |
| } |
| local new-id = $(toolset)$(suffix) ; |
|
|
| generators.register [ $(g).clone $(new-id) : $(properties) ] ; |
| } |
| } |
| } |
|
|
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| rule inherit-flags ( toolset : base : prohibited-properties * : prohibited-vars * ) |
| { |
| for local f in $(.module-flags.$(base)) |
| { |
| local rule-or-module = $(.rule-or-module.$(f)) ; |
| if ( [ set.difference |
| $(.$(rule-or-module).condition.$(f)) : |
| $(prohibited-properties) ] |
| || ! $(.$(rule-or-module).condition.$(f)) |
| ) && ( ! $(.$(rule-or-module).variable.$(f)) in $(prohibited-vars) ) |
| { |
| local rule_ = [ MATCH "[^.]*\.(.*)" : $(rule-or-module) ] ; |
| local new-rule-or-module ; |
| if $(rule_) |
| { |
| new-rule-or-module = $(toolset).$(rule_) ; |
| } |
| else |
| { |
| new-rule-or-module = $(toolset) ; |
| } |
|
|
| add-flag |
| $(new-rule-or-module) |
| : $(.$(rule-or-module).variable.$(f)) |
| : $(.$(rule-or-module).condition.$(f)) |
| : $(.$(rule-or-module).values.$(f)) ; |
| } |
| } |
| } |
|
|
|
|
| rule inherit-rules ( toolset : base : localize ? ) |
| { |
| |
| local base-generators = [ generators.generators-for-toolset $(base) ] ; |
| local rules ; |
| for local g in $(base-generators) |
| { |
| rules += [ MATCH "[^.]*\.(.*)" : [ $(g).rule-name ] ] ; |
| } |
| rules = [ sequence.unique $(rules) ] ; |
| IMPORT $(base) : $(rules) : $(toolset) : $(rules) : $(localize) ; |
| IMPORT $(toolset) : $(rules) : : $(toolset).$(rules) ; |
| } |
|
|
|
|
| |
| |
| |
| rule requirements ( ) |
| { |
| return $(.requirements) ; |
| } |
|
|
|
|
| |
| |
| |
| |
| |
| rule add-requirements ( requirements * ) |
| { |
| if ! $(.ignore-requirements) |
| { |
| .requirements += $(requirements) ; |
| } |
| } |
|
|
|
|
| rule __test__ ( ) |
| { |
| import assert ; |
| local p = <b>0 <c>1 <d>2 <e>3 <f>4 ; |
| assert.result <c>1/<d>2/<e>3 : find-property-subset <c>1/<d>2/<e>3 <a>0/<b>0/<c>1 <d>2/<e>5 <a>9 : $(p) ; |
| assert.result : find-property-subset <a>0/<b>0/<c>9/<d>9/<e>5 <a>9 : $(p) ; |
|
|
| local p-set = <a>/<b> <a>0/<b> <a>/<b>1 <a>0/<b>1 ; |
| assert.result <a>/<b> : find-property-subset $(p-set) : ; |
| assert.result <a>0/<b> : find-property-subset $(p-set) : <a>0 <c>2 ; |
| assert.result <a>/<b>1 : find-property-subset $(p-set) : <b>1 <c>2 ; |
| assert.result <a>0/<b>1 : find-property-subset $(p-set) : <a>0 <b>1 ; |
| } |
|
|