⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 feature.jam

📁 C++的一个好库。。。现在很流行
💻 JAM
📖 第 1 页 / 共 3 页
字号:
        # eliminate features in implicit properties.
        if implicit in [ attributes $(f) ]
        {
            p = $(v) ;
        }

        # locate all subproperties of $(x[1]) in the property set
        local subproperties = [ select-subproperties $(fullp) : $(x) ] ;
        if $(subproperties)
        {
            # reconstitute the joined property name
            local sorted = [ sequence.insertion-sort $(subproperties) ] ;
            result += $(p)-$(sorted:G="":J=-) ;

            x = [ set.difference $(x[2-]) : $(subproperties) ] ;
        }
        else
        {
            # eliminate properties whose value is equal to feature's
            # default and which are not symmetric and which do not
            # contradict values implied by composite properties.
            
            # since all component properties of composites in the set
            # have been eliminated, any remaining property whose
            # feature is the same as a component of a composite in the
            # set must have a non-redundant value.
            if $(fullp) != [ defaults $(f) ]
              || symmetric in [ attributes $(f) ]
                || $(fullp:G) in $(components:G)
            {
                result += $(p) ;
            }

            x = $(x[2-]) ;
        }
    }
    return $(result) ;
}

# Combine all subproperties into their parent properties
#
# Requires: for every subproperty, there is a parent property.  All
# features are explicitly expressed.
#
# This rule probably shouldn't be needed, but
# build-request.expand-no-defaults is being abused for unintended
# purposes and it needs help
rule compress-subproperties ( properties * )
{
    local all-subs matched-subs result ;
    
    for local p in $(properties)
    {
        if ! $(p:G)
        {
            assert.nonempty-variable p:G ; # expecting fully-gristed properties
        }
        
        
        if ! subfeature in $($(p:G).attributes)
        {
            local subs = [ 
              sequence.insertion-sort
                [ sequence.filter is-subproperty-of $(p) : $(properties) ]
            ] ;
            
            matched-subs += $(subs) ;

            local subvalues = -$(subs:G=:J=-) ;
            subvalues ?= "" ;
            result += $(p)$(subvalues) ;
        }
        else
        {
            all-subs += $(p) ;
        }
    }
    assert.result true : set.equal $(all-subs) : $(matched-subs) ;
    return $(result) ;
}
  
# given an ungristed string, finds the longest prefix which is a
# top-level feature name followed by a dash, and return a pair
# consisting of the parts before and after that dash.  More
# interesting than a simple split because feature names can contain
# dashes.
local rule split-top-feature ( feature-plus )
{
    local e = [ regex.split $(feature-plus) - ] ;
    local f = $(e[1]) ;
    
    local v ;
    while $(e)
    {
        if <$(f)> in $(.all-top-features)
        {
            v = $(f) $(e[2-]:J=-) ;
        }
        e = $(e[2-]) ;
        f = $(f)-$(e[1]) ;
    }
    return $(v) ;
}
  
# Given a set of properties, add default values for features not
# represented in the set. 
# Note: if there's there's ordinary feature F1 and composite feature
# F2, which includes some value for F1, and both feature have default values,
# then the default value of F1 will be added, not the value in F2. This might
# not be right idea: consider
#
#   feature variant : debug ... ;
#        <variant>debug : .... <runtime-debugging>on
#   feature <runtime-debugging> : off on ;
#   
#   Here, when adding default for an empty property set, we'll get
#
#     <variant>debug <runtime_debugging>off
#  
#   and that's kind of strange.
rule add-defaults ( properties * )
{
    for local v in $(properties:G=)
    {
        if $(v) in $(properties)
        {
            error add-defaults requires explicitly specified features,
                but \"$(v)\" appears to be the value of an un-expanded implicit feature ;
        }
    }
    # We don't add default for elements with ":" inside. This catches:
    # 1. Conditional properties --- we don't want <variant>debug:<define>DEBUG
    #    to be takes as specified value for <variant>
    # 2. Free properties with ":" in values. We don't care, since free properties
    #    don't have defaults.
    local xproperties = [ MATCH "^([^:]+)$" : $(properties) ] ;
    local missing-top = [ set.difference $(.all-top-features) : $(xproperties:G) ] ;
    local more =  [ defaults $(missing-top) ] ;
    properties += $(more) ;
    xproperties += $(more) ;
    
    # Add defaults for subfeatures of features which are present
    for local p in $(xproperties)
    {
        local s = $($(p:G).subfeatures) ;
        local f = [ utility.ungrist $(p:G) ] ;
        local missing-subs = [ set.difference <$(f)-$(s)> : $(properties:G) ] ;
        properties += [ defaults [ select-subfeatures $(p) : $(missing-subs) ] ] ;
    }
    
    return $(properties)  ;
}

# Given a property-set of the form
#       v1/v2/...vN-1/<fN>vN/<fN+1>vN+1/...<fM>vM
#
# Returns
#       v1 v2 ... vN-1 <fN>vN <fN+1>vN+1 ... <fM>vM
#
# Note that vN...vM may contain slashes. This is resilient to the
# substitution of backslashes for slashes, since Jam, unbidden,
# sometimes swaps slash direction on NT.
rule split ( property-set )
{
    local pieces = [ regex.split $(property-set) [\\/] ] ;
    local result ;

    for local x in $(pieces)
    {
        if ( ! $(x:G) ) && $(result[-1]:G)
        {
            result = $(result[1--2]) $(result[-1])/$(x) ;
        }
        else
        {
            result += $(x) ;
        }
    }

    return $(result) ;
}

# tests of module feature
local rule __test__ ( )
{
    # use a fresh copy of the feature module
    prepare-test feature-test-temp ;

    # These are local rules and so must be explicitly reimported into
    # the testing module
    import feature : extend-feature validate-feature select-subfeatures ; 
    
    import errors : try catch ;
    import assert ;

    feature toolset : gcc : implicit ;
    feature define : : free ;
    feature runtime-link : dynamic static : symmetric ;
    feature optimization : on off ;
    feature variant : debug release : implicit composite symmetric ;
    feature stdlib : native stlport ;
    feature magic : : free ;

    compose <variant>debug : <define>_DEBUG <optimization>off ;
    compose <variant>release : <define>NDEBUG <optimization>on ;

    extend-feature toolset : msvc metrowerks ;
    subfeature toolset gcc : version : 2.95.2 2.95.3 2.95.4
      3.0 3.0.1 3.0.2 ;
    
    subfeature toolset gcc : platform : linux cygwin : optional ;
    
    assert.result <toolset-gcc:version>
      : select-subfeatures <toolset>gcc
         : <toolset-gcc:version>
           <toolset-msvc:version>
           <toolset-version>
           <stdlib>
      ;
           
    subfeature stdlib : version : 3 4 : optional ;

    assert.result <stdlib-version>
      : select-subfeatures <stdlib>native
         : <toolset-gcc:version>
           <toolset-msvc:version>
           <toolset-version>
           <stdlib-version>
      ;
           
    assert.result <toolset>gcc <toolset-gcc:version>3.0.1
      : expand-subfeatures <toolset>gcc-3.0.1 ;
    
    assert.result <toolset>gcc <toolset-gcc:version>3.0.1 <toolset-gcc:platform>linux
      : expand-subfeatures <toolset>gcc-3.0.1-linux ;

    
    assert.result <toolset>gcc <toolset-gcc:version>3.0.1
      : expand <toolset>gcc <toolset-gcc:version>3.0.1  ;
      
    assert.result <define>foo=x-y
      : expand-subfeatures <define>foo=x-y ;

    assert.result <toolset>gcc <toolset-gcc:version>3.0.1
      : expand-subfeatures gcc-3.0.1 ;
    
    assert.result a c e
      : get-values <x> : <x>a <y>b <x>c <y>d <x>e ;

    assert.result <toolset>gcc <toolset-gcc:version>3.0.1
      <variant>debug <define>_DEBUG <optimization>on
      : expand gcc-3.0.1 debug <optimization>on
      ;
    
    assert.result <variant>debug <define>_DEBUG <optimization>on
      : expand debug <optimization>on
      ;

    assert.result <optimization>on <variant>debug <define>_DEBUG 
      : expand <optimization>on debug 
      ;

    assert.result <runtime-link>dynamic <optimization>on
      : defaults <runtime-link> <define> <optimization>
      ;
    
    feature dummy : dummy1 dummy2 ;
    subfeature dummy : subdummy : x y z : optional ;

    feature fu : fu1 fu2 : optional ;
    subfeature fu : subfu : x y z : optional ;
    subfeature fu : subfu2 : q r s ;
    
    assert.result <runtime-link>static <define>foobar <optimization>on <toolset>gcc:<define>FOO
      <toolset>gcc <variant>debug <stdlib>native <dummy>dummy1 <toolset-gcc:version>2.95.2

      : add-defaults <runtime-link>static <define>foobar
        <optimization>on <toolset>gcc:<define>FOO 
      ;
    
    assert.result <runtime-link>static <define>foobar <optimization>on <toolset>gcc:<define>FOO
      <fu>fu1 <toolset>gcc <variant>debug <stdlib>native <dummy>dummy1 <fu-subfu2>q      
      <toolset-gcc:version>2.95.2
      
      : add-defaults <runtime-link>static <define>foobar
        <optimization>on <toolset>gcc:<define>FOO <fu>fu1
      ;
    
    set-default <runtime-link> : static ;
    assert.result <runtime-link>static 
      : defaults <runtime-link>
      ;
      
    assert.result gcc-3.0.1 debug <optimization>on
      : minimize [ expand gcc-3.0.1 debug <optimization>on <stdlib>native ]
      ;

    assert.result gcc-3.0.1 debug <runtime-link>dynamic
      : minimize [ expand gcc-3.0.1 debug <optimization>off <runtime-link>dynamic ]
      ;

    assert.result gcc-3.0.1 debug
      : minimize [ expand gcc-3.0.1 debug <optimization>off ]
      ;

    assert.result debug <optimization>on
      : minimize [ expand debug <optimization>on ]
      ;

    assert.result gcc-3.0
      : minimize <toolset>gcc <toolset-gcc:version>3.0 
      ;

    assert.result gcc-3.0
      : minimize <toolset-gcc:version>3.0 <toolset>gcc
      ;

    assert.result <x>y/z <a>b/c <d>e/f
      : split <x>y/z/<a>b/c/<d>e/f
      ;

    assert.result <x>y/z <a>b/c <d>e/f
      : split <x>y\\z\\<a>b\\c\\<d>e\\f
      ;

    assert.result a b c <d>e/f/g <h>i/j/k
      : split a/b/c/<d>e/f/g/<h>i/j/k
      ;

    assert.result a b c <d>e/f/g <h>i/j/k
      : split a\\b\\c\\<d>e\\f\\g\\<h>i\\j\\k
      ;

    # test error checking

    try ;
    {
        expand release <optimization>off <optimization>on ;
    }
    catch explicitly-specified values of non-free feature <optimization> conflict ;

    try ;
    {
        validate-feature <foobar> ;
    }
    catch unknown feature ;

    validate-value-string <toolset> gcc ;
    validate-value-string <toolset> gcc-3.0.1 ;

    try ;
    {
        validate-value-string <toolset> digital_mars ;
    }
    catch \"digital_mars\" is not a known value of <toolset> ;

    try ;
    {
        feature foobar : : baz ;
    }
    catch unknown attributes: baz ;

    feature feature1 ;
    try ;
    {
        feature feature1 ;
    }
    catch feature already defined: ;

    try ;
    {
        feature feature2 : : free implicit ;
    }
    catch free features cannot also be implicit ;

    try ;
    {
        feature feature3 : : free propagated ;
    }
    catch free features cannot be propagated ;

    try ;
    {
        implied-feature lackluster ;
    }
    catch \"lackluster\" is not a value of an implicit feature ;

    try ;
    {
        implied-subfeature <toolset> 3.0.1 ;
    }
    catch \"3.0.1\" is not a known subfeature value of
      <toolset> ;

    try ;
    {
        implied-subfeature <toolset> not-a-version : gcc ;
    }
    catch \"not-a-version\" is not a known subfeature value of
      <toolset>gcc ;

    # leave a clean copy of the features module behind
    finish-test feature-test-temp ;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -