# (C) Copyright David Abrahams 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 sequence ; import set ; import regex ; import feature ; import numbers ; # Transform property-set by applying f to each component property. local rule apply-to-property-set ( f property-set ) { local properties = [ feature.split $(property-set) ] ; return [ string.join [ $(f) $(properties) ] : / ] ; } # expand the given build request by combining all property-sets which don't # specify conflicting non-free features. rule expand ( property-sets * : feature-space ? ) { feature-space ?= feature ; # First make all features and subfeatures explicit local expanded-property-sets = [ sequence.transform apply-to-property-set $(feature-space).expand-subfeatures : $(property-sets) ] ; # Now combine all of the expanded property-sets local product = [ x-product $(expanded-property-sets) : $(feature-space) ] ; return [ sequence.transform apply-to-property-set $(feature-space).expand-composites : $(product) ] ; } local rule x-product-aux ( property-sets + : feature-space ) { local result ; local p = [ feature.split $(property-sets[1]) ] ; local f = [ set.difference $(p:G) : [ $(feature-space).free-features ] ] ; local seen ; # No conflict with things used at a higher level? if ! [ set.intersection $(f) : $(x-product-used) ] { local x-product-seen ; { # don't mix in any conflicting features local x-product-used = $(x-product-used) $(f) ; if $(property-sets[2]) { local rest = [ x-product-aux $(property-sets[2-]) : $(feature-space) ] ; result = $(property-sets[1])/$(rest) ; } result ?= $(property-sets[1]) ; } # If we didn't encounter a conflicting feature lower down, # don't recurse again. if ! [ set.intersection $(f) : $(x-product-seen) ] { property-sets = ; } seen = $(x-product-seen) ; } if $(property-sets[2]) { result += [ x-product-aux $(property-sets[2-]) : $(feature-space) ] ; } # Note that we've seen these features so that higher levels will # recurse again without them set. x-product-seen += $(f) $(seen) ; return $(result) ; } local rule x-product ( property-sets * : feature-space ) { local x-product-seen x-product-used ; return [ x-product-aux $(property-sets) : $(feature-space) ] ; } local rule __test__ ( ) { import assert ; import errors : try catch ; import class ; local test-space = [ class.new feature-space ] ; module $(test-space) { import build-request ; feature toolset : gcc msvc : implicit ; subfeature toolset gcc : version : 2.95.2 2.95.3 2.95.4 3.0 3.0.1 3.0.2 ; feature variant : debug release : implicit composite ; feature inlining : on off ; feature "include" : : free ; feature stdlib : native stlport : implicit ; assert.result gcc/3.0.1/stlport/debug msvc/stlport/debug msvc/debug : build-request.expand gcc-3.0.1/stlport msvc/stlport msvc debug : $(test-space) ; assert.result gcc/3.0.1/stlport/debug msvc/debug debug/msvc/stlport : build-request.expand gcc-3.0.1/stlport msvc debug msvc/stlport : $(test-space) ; assert.result gcc/3.0.1/stlport/debug/off gcc/3.0.1/stlport/release/off : build-request.expand gcc-3.0.1/stlport debug release off : $(test-space) ; assert.result a/b/c/gcc/3.0.1/stlport/debug/x/y/z a/b/c/msvc/stlport/debug/x/y/z a/b/c/msvc/debug/x/y/z : build-request.expand a/b/c gcc-3.0.1/stlport msvc/stlport msvc debug x/y/z : $(test-space) ; } }