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

📄 property.jam

📁 C++的一个好库。。。现在很流行
💻 JAM
📖 第 1 页 / 共 2 页
字号:
#  Copyright (C) Vladimir Prus 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 utility : ungrist ;
import sequence : unique ;
import errors : error ;
import feature ;
import regex ;
import sequence ;
import set ;
import path ;
import assert ;
import indirect ;

# Refines 'properties' by overriding any non-free properties 
# for which a different value is specified in 'requirements'. 
# Conditional requirements are just added without modification.
# Returns the resulting list of properties.
rule refine ( properties * : requirements * )
{
    local result ;
    local error ;
    
    # All the elements of requirements should be present in the result
    # Record them so that we can handle 'properties'.
    for local r in $(requirements)
    {
        # Don't consider conditional requirements.
        if ! [ MATCH (:) : $(r:G=) ]
        {            
            # Note: cannot use local here, so take an ugly name
            __require__$(r:G) = $(r:G=) ;
        }        
    }

    for local p in $(properties)
    {       
        # No processing for free properties
        if [ MATCH (:) : $(p:G=) ]
        {
            # Skip conditional properties
            result += $(p) ;
        }        
        else if free in [ feature.attributes $(p:G) ]
        {
            result += $(p) ;
        }
        else
        {
            local required-value = $(__require__$(p:G)) ;
            if $(required-value)
            {
                local value = $(p:G=) ;
                if $(value) != $(required-value)
                {
                    result += $(p:G)$(required-value) ;
                }
                else
                {
                    result += $(p) ;
                }
            }
            else
            {
                result += $(p) ;
            }
        }
    }

    # Unset our ugly map.        
    for local r in $(requirements)
    {
         __require__$(r:G) = ;
    }
    
    if $(error)
    {
        return $(error) ;
    }
    else
    {
        return [ unique $(result) $(requirements) ] ;
    }
}

# Removes all conditional properties which conditions are not met
# For those with met conditions, removes the condition. Properies
# in conditions are looked up in 'context'
rule evaluate-conditionals-in-context ( properties * : context * )
{
    local base ;
    local conditionals ;
    for local p in $(properties)
    {
        if [ MATCH (:<) : $(p) ]
        {
            conditionals += $(p) ;
        }
        else
        {
            base += $(p) ;
        }        
    }

    local result = $(base) ;
    for local p in $(conditionals)
    {
        # Separate condition and property
        local s = [ MATCH (.*):(<.*) : $(p) ] ;
        # Split condition into individual properties
        local c = [ regex.split $(s[1]) "," ] ;
        # Evaluate condition
        if $(c) in $(context)
        {
            result += $(s[2]) ;
        }                
    }
    return $(result) ;    
}

rule expand-subfeatures-in-conditions ( properties * )
{
    local result ;
    for local p in $(properties)
    {
        local s = [ MATCH (.*):(<.*) : $(p) ] ;        
        if ! $(s)
        {
            result += $(p) ;
        }
        else
        {
            local condition = $(s[1]) ;
            # Condition might include several elements
            condition = [ regex.split $(condition) "," ] ;
            local value = $(s[2]) ;
            local e ;
            for local c in $(condition)
            {           
                if [ MATCH "^(<toolset>|<toolset->)" : $(c:G) ] ||
                   [ MATCH "^(<os>)" : $(c:G) ]
                {
                    # It common that condition includes a toolset which
                    # was never defined, or mentiones subfeatures which
                    # were never defined. In that case, validation will
                    # only produce an spirious error, so don't validate.
                    e += [ feature.expand-subfeatures $(c) : true ] ;
                }               
                else
                {
                    e += [ feature.expand-subfeatures $(c) ] ;
                }                
            }
            
            if $(e) = $(condition)
            {
                result += $(p) ;
            }
            else
            {
                local individual-subfeatures = [ set.difference $(e) : $(condition) ] ;
                result += $(individual-subfeatures:J=,):$(value) ;
            }            
        }        
    }    
    return $(result) ;
}



# Helper for as-path, below. Orders properties with the implicit ones
# first, and within the two sections in alphabetical order of feature
# name.
local rule path-order ( x y )
{
    if $(y:G) && ! $(x:G)
    {
        return true ;
    }
    else if $(x:G) && ! $(y:G)
    {
        return ;
    }
    else
    {
        if ! $(x:G)
        {
            x = [ feature.expand-subfeatures $(x) ] ;
            y = [ feature.expand-subfeatures $(y) ] ;
        }
        
        if $(x[1]) < $(y[1])
        {
            return true ;
        }
    }
}

# Returns a path which represents the given expanded property set.
rule as-path ( properties * )
{
    local entry = .result.$(properties:J=-) ;
    
    if ! $($(entry))
    {
        # trim redundancy
        properties = [ feature.minimize $(properties) ] ;
    
        # sort according to path-order
        properties = [ sequence.insertion-sort $(properties) : path-order ] ;
    
        local components ;
        for local p in $(properties)
        {
            if $(p:G)
            {
                local f = [ ungrist $(p:G) ] ;
                components += $(f)-$(p:G=) ;
            }
            else
            {
                components += $(p) ;
            }
        }
        
        $(entry) = $(components:J=/) ;
    }    
    
    return $($(entry)) ;
}

# Exit with error if property is not valid.
local rule validate1 ( property )
{
    local msg ;
    if $(property:G)
    {
        local feature = $(property:G) ;
        local value = $(property:G=) ;

        if ! [ feature.valid $(feature) ]
        {
            feature = [ ungrist $(property:G) ] ; # Ungrist for better error messages
            msg = "unknown feature '$(feature)'" ;
        }
        else if $(value) && ! free in [ feature.attributes $(feature) ] 
        {
            feature.validate-value-string $(feature) $(value) ;
        } 
        else if ! $(value)
        {
            feature = [ ungrist $(property:G) ] ; # Ungrist for better error messages
            msg = "No value specified for feature '$(feature)'" ; 
        }
    }
    else
    {
        local feature = [ feature.implied-feature $(property) ] ;
        feature.validate-value-string $(feature) $(property) ;
    }
    if $(msg) 
    {
        error "Invalid property "'$(property:J=" ")'": "$(msg:J=" "). ;
    }
}

rule validate ( properties * )
{
    for local p in $(properties)
    {
        validate1 $(p) ;
    }
}

rule validate-property-sets ( property-sets * )
{
    for local s in $(property-sets)
    {
        validate [ feature.split $(s) ] ;
    }
}

# Makes a property set from 'specification', converting implicit values into 
# full properties.
rule make ( specification * )
{
    local result ;
    for local e in $(specification) 
    {
        if $(e:G)
        {
            result += $(e) ;
        }
        else if [ feature.is-implicit-value $(e) ]
        {
            local feature = [ feature.implied-feature $(e) ] ;
            result += $(feature)$(e) ;      
        }
        else
        {
            error "'$(e)' is not a valid for property specification" ;
        }
    }
    return $(result) ;
}

# Returns a property sets which include all the elements in 'properties' that
# do not have attributes listed in 'attributes'. 
rule remove ( attributes + : properties * )
{
    local result ;
    for local e in $(properties)
    {
        if ! [ set.intersection $(attributes) : [ feature.attributes $(e:G) ] ]
        {
            result += $(e) ;
        }
    }
    return $(result) ;
}

# Returns a property set which include all properties in 'properties' that have
# any of 'attributes'.
rule take ( attributes + : properties * )
{
    local result ;
    for local e in $(properties)
    {
        if [ set.intersection $(attributes) : [ feature.attributes $(e:G) ] ]
        {

⌨️ 快捷键说明

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