|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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 ; |
|
} |
|
|