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

📄 modifiers.jam

📁 C++的一个好库。。。现在很流行
💻 JAM
字号:
# (C) Copyright Rene Rivera, 2003.
#
# See accompanying license for terms and conditions of use.
#

# Modifiers are generalized generators that mutate targets in specific ways.
# This structure allows for grouping a variety of functionality in an
# orthogonal way to the functionality in toolsets, and without specifying
# more target variations. In turn the modifiers can be used as building
# blocks to implement simple requests, like the <version> feature.

import modules ;
import feature ;
import errors ;
import type ;
import "class" : new ;
import generators : generator ;
import property ;
import virtual-target ;
import numbers ;
import sequence ;
import symlink ;
import property-set ;

# Base generator for creating targets that are modifications of existing
# targets.
#
rule modifier (
    id
    composing ?
    : source-types *
    : target-types-and-names +   
    : requirements *
    )
{
    generator.__init__ $(id) $(composing) : $(source-types) : $(target-types-and-names) : $(requirements) ;
    
    self.targets-in-progress = ;
    
    # Wraps the generation of the target to call before and after rules to
    # affect the real target.
    #
    rule run ( project name ? : property-set : sources + :  multiple ? )
    {
        local result ;
        local current-target = $(project)^$(name) ;
        if ! $(current-target) in $(self.targets-in-progress)
        {
            # Before modifications...
            local project_ = [ modify-project-before
                $(project) $(name) : $(property-set) : $(sources) : $(multiple) ] ;
            local name_ = [ modify-name-before
                $(project) $(name) : $(property-set) : $(sources) : $(multiple) ] ;
            local property-set_ = [ modify-properties-before
                $(project) $(name) : $(property-set) : $(sources) : $(multiple) ] ;
            local sources_ = [ modify-sources-before
                $(project) $(name) : $(property-set) : $(sources) : $(multiple) ] ;
            local multiple_ = [ modify-multiple-before
                $(project) $(name) : $(property-set) : $(sources) : $(multiple) ] ;
            project = $(project_) ;
            name = $(name_) ;
            property-set = $(property-set_) ;
            sources = $(sources_) ;
            multiple = $(multiple_) ;
            
            # Generate the real target...
            local target-type-p = [ property.select <main-target-type> : [ $(property-set).raw ] ] ;
            self.targets-in-progress += $(current-target) ;
            result =
                [ generators.construct $(project) $(name) : $(target-type-p:G=) $(multiple) :
                    $(property-set) : $(sources) ] ;
            self.targets-in-progress = $(self.targets-in-progress[1--2]) ;
            
            # After modifications...
            result = [ modify-target-after $(result) :
                $(project) $(name) : $(property-set) : $(sources) : $(multiple) ] ;
        }
        return $(result) ;
    }
    
    rule modify-project-before ( project name ? : property-set : sources + :  multiple ? )
    {
        return $(project) ;
    }
    
    rule modify-name-before ( project name ? : property-set : sources + :  multiple ? )
    {
        return $(name) ;
    }
    
    rule modify-properties-before ( project name ? : property-set : sources + :  multiple ? )
    {
        return $(property-set) ;
    }
    
    rule modify-sources-before ( project name ? : property-set : sources + :  multiple ? )
    {
        return $(sources) ;
    }
    
    rule modify-multiple-before ( project name ? : property-set : sources + :  multiple ? )
    {
        return $(multiple) ;
    }
    
    rule modify-target-after ( target : project name ? : property-set : sources + :  multiple ? )
    {
        return $(target) ;
    }
    
    # Utility, clones a file-target with optional changes to the name, type, and project
    # of the target.
    # NOTE: This functionality should be moved, and generalized, to virtual-targets.
    #
    rule clone-file-target ( target : new-name ? : new-type ? : new-project ? )
    {
        # Need a MUTCH better way to clone a target...
        new-name ?= [ $(target).name ] ;
        new-type ?= [ $(target).type ] ;
        new-project ?= [ $(target).project ] ;
        local result = [ new file-target $(new-name) : $(new-type) : $(new-project) ] ;
        
        if [ $(target).dependencies ] { $(result).depends [ $(target).dependencies ] ; }
        $(result).root [ $(target).root ] ;
        $(result).set-usage-requirements [ $(target).usage-requirements ] ;
        
        local action = [ $(target).action ] ;
        local action-class = [ modules.peek $(action) : __class__ ] ;
        
        local ps = [ $(action).properties ] ;
        local cloned-action = [ new $(action-class) $(result) : 
          [ $(action).sources ] : [ $(action).action-name ] : $(ps) ] ;
        $(result).action $(cloned-action) ;
        
        return $(result) ;
    }
}
class modifier : generator ;

# A modifier that changes the name of a target, after it's generated, given
# a regular expression to slpit the name, and a set of token to insert
# between the split tokens of the name. This also exposes the target for other
# uses with a symlink to the original name (optionally).
#
rule name-modifier ( )
{
    # Apply ourselves to EXE targets, for now.
    modifier.__init__ name.modifier : : EXE LIB : <name-modify>yes ;
    
    # Modifies the name, by cloning the target with the new name.
    #
    rule modify-target-after ( target : project name ? : property-set : sources + :  multiple ? )
    {
        local result = $(target) ;
        
        local name-mod-p = [ property.select <name-modifier> : [ $(property-set).raw ] ] ;
        if $(name-mod-p)
        {
            local new-name = [ modify-name [ $(target).name ] : $(name-mod-p:G=) ] ;
            if $(new-name) != [ $(target).name ]
            {
                result = [ clone-file-target $(target) : $(new-name) ] ;
            }
            local expose-original-as-symlink = [ MATCH "<symlink>(.*)" : $(name-mod-p) ] ;
            if $(expose-original-as-symlink)
            {
                local symlink-t = [ new symlink-targets $(project) : $(name) : [ $(result).name ] ] ;
                result = [ $(symlink-t).construct $(result)
                    : [ property-set.create [ $(property-set).raw ] <symlink-location>build-relative ] ] ;
            }
        }
        
        return $(result) ;
    }
    
    # Do the transformation of the name.
    #
    rule modify-name ( name : modifier-spec + )
    {
        local match = [ MATCH "<match>(.*)" : $(modifier-spec) ] ;
        local name-parts = [ MATCH $(match) : $(name) ] ;
        local insertions = [ sequence.insertion-sort [ MATCH "(<[0123456789]+>.*)" : $(modifier-spec) ] ] ;
        local new-name-parts ;
        local insert-position = 1 ;
        while $(insertions)
        {
            local insertion = [ MATCH "<$(insert-position)>(.*)" : $(insertions[1]) ] ;
            if $(insertion)
            {
                new-name-parts += $(insertion) ;
                insertions = $(insertions[2-]) ;
            }
            new-name-parts += $(name-parts[1]) ;
            name-parts = $(name-parts[2-]) ;
            insert-position = [ numbers.increment $(insert-position) ] ;
        }
        new-name-parts += $(name-parts) ;
        return [ sequence.join $(new-name-parts) ] ;
    }
    
    rule optional-properties ( )
    {
        return <name-modify>yes ;
    }
}
class name-modifier : modifier ;
feature.feature name-modifier : : free ;
feature.feature name-modify : no yes : incidental optional ;
generators.register [ new name-modifier ] ;

# Translates <version> property to a set of modification properties
# that are applied by the name-modifier, and symlink-modifier.
#
rule version-to-modifier ( property : properties * )
{
    return
        <name-modify>yes
            <name-modifier><match>"^([^.]*)(.*)" <name-modifier><2>.$(property:G=)
            <name-modifier><symlink>yes
        ;
}
feature.action <version> : version-to-modifier ;

⌨️ 快捷键说明

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