示例#1
0
def libraries_to_install(existing_libraries):
    # Decides which libraries are to be installed by looking at --with-<library>
    # --without-<library> arguments. Returns the list of directories under "libs"
    # which must be built and installed.

    with_parameter = regex.transform(sys.argv, "--with-(.*)")
    without_parameter = regex.transform(sys.argv, "--without-(.*)")

    if not with_parameter and not without_parameter:
        # Nothing is specified on command line. See if maybe
        # project-config.jam has some choices.
        project_config_libs = bjam.call("peek", "project-config", "libraries")
        with_parameter = regex.transform(project_config_libs, "--with-(.*)")
        without_parameter = regex.transform(project_config_libs, "--without-(.*)")

    # Do some checks.
    if with_parameter and without_parameter:
        get_manager().errors()("both --with-<library> and --without-<library> specified")

    wrong = set.difference(with_parameter, existing_libraries)
    if wrong:
        get_manager().errors()("wrong library name '" + wrong[0] + "' in the --with-<library> option.")

    wrong = set.difference(without_parameter, existing_libraries)
    if wrong:
        get_manager().errors()("wrong library name '" + wrong[0] + "' in the --without-<library> option.")

    if with_parameter:
        return set.intersection(existing_libraries, with_parameter)
    else:
        return set.difference(existing_libraries, without_parameter)
示例#2
0
def libraries_to_install(existing_libraries):
    # Decides which libraries are to be installed by looking at --with-<library>
    # --without-<library> arguments. Returns the list of directories under "libs"
    # which must be built and installed.

    with_parameter = regex.transform(sys.argv, "--with-(.*)")
    without_parameter = regex.transform(sys.argv, "--without-(.*)")

    if not with_parameter and not without_parameter:
        # Nothing is specified on command line. See if maybe
        # project-config.jam has some choices.
        project_config_libs = bjam.call("peek", "project-config", "libraries")
        with_parameter = regex.transform(project_config_libs, "--with-(.*)")
        without_parameter = regex.transform(project_config_libs,
                                            "--without-(.*)")

    # Do some checks.
    if with_parameter and without_parameter:
        get_manager().errors()(
            "both --with-<library> and --without-<library> specified")

    wrong = set.difference(with_parameter, existing_libraries)
    if wrong:
        get_manager().errors()("wrong library name '" + wrong[0] +
                               "' in the --with-<library> option.")

    wrong = set.difference(without_parameter, existing_libraries)
    if wrong:
        get_manager().errors()("wrong library name '" + wrong[0] +
                               "' in the --without-<library> option.")

    if with_parameter:
        return set.intersection(existing_libraries, with_parameter)
    else:
        return set.difference(existing_libraries, without_parameter)
示例#3
0
文件: feature.py 项目: malinost/boost
def add_defaults(properties):
    """ 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.        
    """
    result = [x for x in properties]

    for v in replace_grist(properties, ''):
        if v in properties:
            raise BaseException(
                "'add_defaults' requires explicitly specified features, but '%s' appears to be the value of an un-expanded implicit feature"
                % v)

    # 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.
    xproperties = [
        property for property in properties if __re_no_hyphen.match(property)
    ]
    missing_top = set.difference(__all_top_features, get_grist(xproperties))
    more = defaults(missing_top)
    result += more
    xproperties += more

    # Add defaults for subfeatures of features which are present
    for p in xproperties:
        gp = get_grist(p)
        s = []
        if __all_features.has_key(gp):
            s = __all_features[gp]['subfeatures']
        f = ungrist(gp)

        xbase = ['<%s-%s>' % (f, xs) for xs in s]

        missing_subs = set.difference(xbase, get_grist(result))
        result += defaults(__select_subfeatures(p, missing_subs))

    return result
示例#4
0
    def register_actual_name(self, actual_name, virtual_target):
        assert isinstance(actual_name, basestring)
        assert isinstance(virtual_target, VirtualTarget)
        if self.actual_.has_key(actual_name):
            cs1 = self.actual_[actual_name].creating_subvariant()
            cs2 = virtual_target.creating_subvariant()
            cmt1 = cs1.main_target()
            cmt2 = cs2.main_target()

            action1 = self.actual_[actual_name].action()
            action2 = virtual_target.action()

            properties_added = []
            properties_removed = []
            if action1 and action2:
                p1 = action1.properties()
                p1 = p1.raw()
                p2 = action2.properties()
                p2 = p2.raw()

                properties_removed = set.difference(p1, p2)
                if not properties_removed:
                    properties_removed = "none"

                properties_added = set.difference(p2, p1)
                if not properties_added:
                    properties_added = "none"

            # FIXME: Revive printing of real location.
            get_manager().errors()(
                "Duplicate name of actual target: '%s'\n"
                "previous virtual target '%s'\n"
                "created from '%s'\n"
                "another virtual target '%s'\n"
                "created from '%s'\n"
                "added properties: '%s'\n"
                "removed properties: '%s'\n"
                % (
                    actual_name,
                    self.actual_[actual_name],
                    "loc",  # cmt1.location (),
                    virtual_target,
                    "loc",  # cmt2.location (),
                    properties_added,
                    properties_removed,
                )
            )

        else:
            self.actual_[actual_name] = virtual_target
示例#5
0
def add_defaults (properties):
    """ 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.        
    """
    result = [ x for x in properties ]
    
    for v in replace_grist (properties, ''):
        if v in properties:
            raise BaseException ("'add_defaults' requires explicitly specified features, but '%s' appears to be the value of an un-expanded implicit feature" % v)

    # 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.
    xproperties = [ property for property in properties if __re_no_hyphen.match (property) ]
    missing_top = set.difference (__all_top_features, get_grist (xproperties))
    more =  defaults (missing_top)
    result += more
    xproperties += more
    
    # Add defaults for subfeatures of features which are present
    for p in xproperties:
        gp = get_grist (p)
        s = []
        if __all_features.has_key (gp):
            s = __all_features [gp]['subfeatures']
        f = ungrist (gp)
        
        xbase = ['<%s-%s>' % (f, xs) for xs in s]
            
        missing_subs = set.difference (xbase, get_grist (result))
        result += defaults (__select_subfeatures (p, missing_subs))
    
    return result
示例#6
0
def inherit_flags(toolset, base, prohibited_properties=[]):
    """Brings all flag definitions from the 'base' toolset into the 'toolset'
    toolset. Flag definitions whose conditions make use of properties in
    'prohibited-properties' are ignored. Don't confuse property and feature, for
    example <debug-symbols>on and <debug-symbols>off, so blocking one of them does
    not block the other one.
    
    The flag conditions are not altered at all, so if a condition includes a name,
    or version of a base toolset, it won't ever match the inheriting toolset. When
    such flag settings must be inherited, define a rule in base toolset module and
    call it as needed."""
    for f in __module_flags.get(base, []):

        if not f.condition or set.difference(f.condition,
                                             prohibited_properties):
            match = __re_first_group.match(f.rule)
            rule_ = None
            if match:
                rule_ = match.group(1)

            new_rule_or_module = ''

            if rule_:
                new_rule_or_module = toolset + '.' + rule_
            else:
                new_rule_or_module = toolset

            __add_flag(new_rule_or_module, f.variable_name, f.condition,
                       f.values)
示例#7
0
def inherit_flags(toolset, base, prohibited_properties = []):
    """Brings all flag definitions from the 'base' toolset into the 'toolset'
    toolset. Flag definitions whose conditions make use of properties in
    'prohibited-properties' are ignored. Don't confuse property and feature, for
    example <debug-symbols>on and <debug-symbols>off, so blocking one of them does
    not block the other one.
    
    The flag conditions are not altered at all, so if a condition includes a name,
    or version of a base toolset, it won't ever match the inheriting toolset. When
    such flag settings must be inherited, define a rule in base toolset module and
    call it as needed."""
    for f in __module_flags.get(base, []):
        
        if not f.condition or set.difference(f.condition, prohibited_properties):
            match = __re_first_group.match(f.rule)
            rule_ = None
            if match:
                rule_ = match.group(1)

            new_rule_or_module = ''

            if rule_:
                new_rule_or_module = toolset + '.' + rule_
            else:
                new_rule_or_module = toolset

            __add_flag (new_rule_or_module, f.variable_name, f.condition, f.values)
示例#8
0
def expand_subfeatures_in_conditions(properties):

    result = []
    for p in properties:

        s = __re_separate_condition_and_property.match(p)
        if not s:
            result.append(p)
        else:
            condition = s.group(1)
            # Condition might include several elements
            condition = condition.split(",")
            value = s.group(2)
            
            e = []
            for c in condition:
                # 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 prevent
                # validation by passing 'true' as second parameter.
                e.extend(feature.expand_subfeatures(c, dont_validate=True))

            if e == condition:
                result.append(p)
            else:
                individual_subfeatures = set.difference(e, condition)
                result.append(",".join(individual_subfeatures) + ":" + value)
                
    return result
    def register_actual_name(self, actual_name, virtual_target):
        assert isinstance(actual_name, basestring)
        assert isinstance(virtual_target, VirtualTarget)
        if actual_name in self.actual_:
            cs1 = self.actual_[actual_name].creating_subvariant()
            cs2 = virtual_target.creating_subvariant()
            cmt1 = cs1.main_target()
            cmt2 = cs2.main_target()

            action1 = self.actual_[actual_name].action()
            action2 = virtual_target.action()

            properties_added = []
            properties_removed = []
            if action1 and action2:
                p1 = action1.properties()
                p1 = p1.raw()
                p2 = action2.properties()
                p2 = p2.raw()

                properties_removed = set.difference(p1, p2)
                if not properties_removed:
                    properties_removed = ["none"]

                properties_added = set.difference(p2, p1)
                if not properties_added:
                    properties_added = ["none"]

            # FIXME: Revive printing of real location.
            get_manager().errors()("Duplicate name of actual target: '%s'\n"
                                   "previous virtual target '%s'\n"
                                   "created from '%s'\n"
                                   "another virtual target '%s'\n"
                                   "created from '%s'\n"
                                   "added properties:\n%s\n"
                                   "removed properties:\n%s\n" %
                                   (actual_name, self.actual_[actual_name],
                                    cmt1.project().location(), virtual_target,
                                    cmt2.project().location(), '\n'.join(
                                        '\t' + p
                                        for p in properties_added), '\n'.join(
                                            '\t' + p
                                            for p in properties_removed)))

        else:
            self.actual_[actual_name] = virtual_target
示例#10
0
    def register_actual_name(self, actual_name, virtual_target):
        if self.actual_.has_key(actual_name):
            cs1 = self.actual_[actual_name].creating_subvariant()
            cs2 = virtual_target.creating_subvariant()
            cmt1 = cs1.main_target()
            cmt2 = cs2.main_target()

            action1 = self.actual_[actual_name].action()
            action2 = virtual_target.action()

            properties_added = []
            properties_removed = []
            if action1 and action2:
                p1 = action1.properties()
                p1 = p1.raw()
                p2 = action2.properties()
                p2 = p2.raw()

                properties_removed = set.difference(p1, p2)
                if not properties_removed: properties_removed = "none"

                properties_added = set.difference(p2, p1)
                if not properties_added: properties_added = "none"

            # FIXME: Revive printing of real location.
            get_manager().errors()(
                "Duplicate name of actual target: '%s'\n"
                "previous virtual target '%s'\n"
                "created from '%s'\n"
                "another virtual target '%s'\n"
                "created from '%s'\n"
                "added properties: '%s'\n"
                "removed properties: '%s'\n" % (
                    actual_name,
                    self.actual_[actual_name],
                    "loc",  #cmt1.location (),
                    virtual_target,
                    "loc",  #cmt2.location (),
                    properties_added,
                    properties_removed))

        else:
            self.actual_[actual_name] = virtual_target
示例#11
0
文件: feature.py 项目: malinost/boost
def __validate_feature_attributes(name, attributes):
    for attribute in attributes:
        if not attribute in __all_attributes:
            raise InvalidAttribute(
                "unknown attributes: '%s' in feature declaration: '%s'" %
                (str(set.difference(attributes, __all_attributes)), name))

    if name in __all_features:
        raise AlreadyDefined("feature '%s' already defined" % name)
    elif 'implicit' in attributes and 'free' in attributes:
        raise InvalidAttribute(
            "free features cannot also be implicit (in declaration of feature '%s')"
            % name)
    elif 'free' in attributes and 'propagated' in attributes:
        raise InvalidAttribute(
            "free features cannot also be propagated (in declaration of feature '%s')"
            % name)
示例#12
0
def __x_product_aux(property_sets, x_product_seen, x_product_used,
                    feature_space):
    """ Implementation of __x_product.
    """
    result = []

    if property_sets:
        p = feature.split(property_sets[0])
    else:
        p = []

    f = set.difference(get_grist(p), feature.free_features())

    seen = []
    # No conflict with things used at a higher level?
    if not set.intersection(f, x_product_used):
        # don't mix in any conflicting features
        local_x_product_used = x_product_used + f
        local_x_product_seen = []

        if len(property_sets) > 1:
            rest = __x_product_aux(property_sets[1:], local_x_product_seen,
                                   local_x_product_used, feature_space)
            result = [property_sets[0] + '/' + x for x in rest]

        if not result and property_sets:
            result = [property_sets[0]]

        # If we didn't encounter a conflicting feature lower down,
        # don't recurse again.
        if not set.intersection(f, local_x_product_seen):
            property_sets = []

        seen = local_x_product_seen

    if len(property_sets) > 1:
        result.extend(
            __x_product_aux(property_sets[1:], x_product_seen, x_product_used,
                            feature_space))
    x_product_seen += f + seen

    # Note that we've seen these features so that higher levels will
    # recurse again without them set.

    return result
示例#13
0
def set_library_order(manager, sources, prop_set, result):
    used_libraries = []
    deps = prop_set.dependency()

    sources.extend(d.value() for d in deps)
    sources = sequence.unique(sources)

    for l in sources:
        if l.type() and type.is_derived(l.type(), 'LIB'):
            used_libraries.append(l)

    created_libraries = []
    for l in result:
        if l.type() and type.is_derived(l.type(), 'LIB'):
            created_libraries.append(l)

    created_libraries = set.difference(created_libraries, used_libraries)
    set_library_order_aux(created_libraries, used_libraries)
示例#14
0
文件: unix.py 项目: 4ukuta/core
def set_library_order (manager, sources, prop_set, result):
    used_libraries = []
    deps = prop_set.dependency ()

    sources.extend(d.value() for d in deps)
    sources = sequence.unique(sources)

    for l in sources:
        if l.type () and type.is_derived (l.type (), 'LIB'):
            used_libraries.append (l)

    created_libraries = []
    for l in result:
        if l.type () and type.is_derived (l.type (), 'LIB'):
            created_libraries.append (l)
    
    created_libraries = set.difference (created_libraries, used_libraries)
    set_library_order_aux (created_libraries, used_libraries)
示例#15
0
def refine_from_user_input(parent_requirements, specification, jamfile_module,
                           location):
    """Refines requirements with requirements provided by the user.
    Specially handles "-<property>value" syntax in specification
     to remove given requirements.
     - parent-requirements -- property-set object with requirements
       to refine
     - specification -- string list of requirements provided by the use
     - project-module -- the module to which context indirect features
       will be bound.
     - location -- the path to which path features are relative."""
    assert isinstance(parent_requirements, PropertySet)
    assert is_iterable_typed(specification, basestring)
    assert isinstance(jamfile_module, basestring)
    assert isinstance(location, basestring)

    if not specification:
        return parent_requirements


    add_requirements = []
    remove_requirements = []

    for r in specification:
        if r[0] == '-':
            remove_requirements.append(r[1:])
        else:
            add_requirements.append(r)

    if remove_requirements:
        # Need to create property set, so that path features
        # and indirect features are translated just like they
        # are in project requirements.
        ps = create_from_user_input(remove_requirements,
                                    jamfile_module, location)

        parent_requirements = create(difference(parent_requirements.all(),
                                                ps.all()))
        specification = add_requirements

    requirements = create_from_user_input(specification,
                                          jamfile_module, location)

    return parent_requirements.refine(requirements)
示例#16
0
def __x_product_aux (property_sets, x_product_seen, x_product_used, feature_space):
    """ Implementation of __x_product.
    """
    result = []
    
    if property_sets:
        p = feature.split (property_sets [0])
    else:
        p = []
        
    f = set.difference (get_grist (p), feature.free_features ())
    
    seen = []
    # No conflict with things used at a higher level?
    if not set.intersection (f, x_product_used):
        # don't mix in any conflicting features
        local_x_product_used = x_product_used + f
        local_x_product_seen = []
        
        if len (property_sets) > 1:
            rest = __x_product_aux (property_sets [1:], local_x_product_seen, local_x_product_used, feature_space)
            result = [ property_sets [0] + '/' + x for x in rest]
        
        if not result and property_sets:
            result = [property_sets [0]]
        
        # If we didn't encounter a conflicting feature lower down,
        # don't recurse again.
        if not set.intersection (f, local_x_product_seen):
            property_sets = []
        
        seen = local_x_product_seen
    
    if len (property_sets) > 1:
        result.extend (__x_product_aux (property_sets [1:], x_product_seen, x_product_used, feature_space))
    x_product_seen += f + seen
    
    # Note that we've seen these features so that higher levels will
    # recurse again without them set.

    return result
示例#17
0
def __validate_feature_attributes (name, attributes):
    for attribute in attributes:
        if not attribute in __all_attributes:
            raise InvalidAttribute ("unknown attributes: '%s' in feature declaration: '%s'" % (str (set.difference (attributes, __all_attributes)), name))
    
    if name in __all_features:
            raise AlreadyDefined ("feature '%s' already defined" % name)
    elif 'implicit' in attributes and 'free' in attributes:
        raise InvalidAttribute ("free features cannot also be implicit (in declaration of feature '%s')" % name)
    elif 'free' in attributes and 'propagated' in attributes:
        raise InvalidAttribute ("free features cannot also be propagated (in declaration of feature '%s')" % name)
示例#18
0
def minimize (properties):
    """ Given an expanded property set, eliminate all redundancy: properties
        which are elements of other (composite) properties in the set will
        be eliminated. Non-symmetric properties equal to default values will be
        eliminated, unless the override a value from some composite property.
        Implicit properties will be expressed without feature
        grist, and sub-property values will be expressed as elements joined
        to the corresponding main property.
    """    
# FXIME: the code below was in the original feature.jam file, however 'p' is not defined.
#       # Precondition checking
#       local implicits = [ set.intersection $(p:G=) : $(p:G) ] ;
#       if $(implicits)
#       {
#           error minimize requires an expanded property set, but \"$(implicits[1])\"
#             appears to be the value of an un-expanded implicit feature ;
#       }
           
    # remove properties implied by composite features
    components = []
    for property in properties:
        if __composite_properties.has_key (property):
            components.extend (__composite_properties [property]['components'])
    
    x = set.difference (properties, components)
    
    # handle subfeatures and implicit features
    x = __move_subfeatures_to_the_end (x)
    
    result = []
    while x:
        fullp = x [0]
        p = fullp
        f = get_grist (p)
        v = replace_grist (p, '')
        
        # eliminate features in implicit properties.
        if 'implicit' in __all_features [f]['attributes']:
            p = v

        # locate all subproperties of $(x[1]) in the property set
        subproperties = __select_subproperties (fullp, x)
        
        if subproperties:
            # reconstitute the joined property name
            subproperties.sort ()
            joined = p + '-' + '-'.join (replace_grist (subproperties, ''))
            result.append (joined)

            x = set.difference (x [1:], 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]) or 'symmetric' in attributes (f)\
                   or get_grist (fullp) in get_grist (components):
                result.append (p)

            x = x [1:]

    return result
示例#19
0
文件: feature.py 项目: malinost/boost
def minimize(properties):
    """ Given an expanded property set, eliminate all redundancy: properties
        which are elements of other (composite) properties in the set will
        be eliminated. Non-symmetric properties equal to default values will be
        eliminated, unless the override a value from some composite property.
        Implicit properties will be expressed without feature
        grist, and sub-property values will be expressed as elements joined
        to the corresponding main property.
    """
    # FXIME: the code below was in the original feature.jam file, however 'p' is not defined.
    #       # Precondition checking
    #       local implicits = [ set.intersection $(p:G=) : $(p:G) ] ;
    #       if $(implicits)
    #       {
    #           error minimize requires an expanded property set, but \"$(implicits[1])\"
    #             appears to be the value of an un-expanded implicit feature ;
    #       }

    # remove properties implied by composite features
    components = []
    for property in properties:
        if __composite_properties.has_key(property):
            components.extend(__composite_properties[property]['components'])

    x = set.difference(properties, components)

    # handle subfeatures and implicit features
    x = __move_subfeatures_to_the_end(x)

    result = []
    while x:
        fullp = x[0]
        p = fullp
        f = get_grist(p)
        v = replace_grist(p, '')

        # eliminate features in implicit properties.
        if 'implicit' in __all_features[f]['attributes']:
            p = v

        # locate all subproperties of $(x[1]) in the property set
        subproperties = __select_subproperties(fullp, x)

        if subproperties:
            # reconstitute the joined property name
            subproperties.sort()
            joined = p + '-' + '-'.join(replace_grist(subproperties, ''))
            result.append(joined)

            x = set.difference(x[1:], 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]) or 'symmetric' in attributes (f)\
                   or get_grist (fullp) in get_grist (components):
                result.append(p)

            x = x[1:]

    return result
示例#20
0
    def convert_to_consumable_types (self, project, name, prop_set, sources, only_one=False):
        """ Attempts to convert 'source' to the types that this generator can
            handle. The intention is to produce the set of targets can should be
            used when generator is run.
            only_one:   convert 'source' to only one of source types
                        if there's more that one possibility, report an
                        error.
                        
            Returns a pair:
                consumed: all targets that can be consumed. 
                bypassed: all targets that cannot be consumed.
        """
        consumed = []
        bypassed = []
        missing_types = [] 

        if len (sources) > 1:
            # Don't know how to handle several sources yet. Just try 
            # to pass the request to other generator
            missing_types = self.source_types_

        else:
            (c, m) = self.consume_directly (sources [0])
            consumed += c
            missing_types += m
        
        # No need to search for transformation if
        # some source type has consumed source and
        # no more source types are needed.
        if only_one and consumed:
            missing_types = []
            
        #TODO: we should check that only one source type
        #if create of 'only_one' is true.
        # TODO: consider if consuned/bypassed separation should
        # be done by 'construct_types'.
                    
        if missing_types:
            transformed = construct_types (project, name, missing_types, prop_set, sources)
                                
            # Add targets of right type to 'consumed'. Add others to
            # 'bypassed'. The 'generators.construct' rule has done
            # its best to convert everything to the required type.
            # There's no need to rerun it on targets of different types.
                
            # NOTE: ignoring usage requirements
            for t in transformed[1]:
                if t.type() in missing_types:
                    consumed.append(t)

                else:
                    bypassed.append(t)
        
        consumed = unique(consumed)
        bypassed = unique(bypassed)
        
        # remove elements of 'bypassed' that are in 'consumed'
        
        # Suppose the target type of current generator, X is produced from 
        # X_1 and X_2, which are produced from Y by one generator.
        # When creating X_1 from Y, X_2 will be added to 'bypassed'
        # Likewise, when creating X_2 from Y, X_1 will be added to 'bypassed'
        # But they are also in 'consumed'. We have to remove them from
        # bypassed, so that generators up the call stack don't try to convert
        # them. 

        # In this particular case, X_1 instance in 'consumed' and X_1 instance
        # in 'bypassed' will be the same: because they have the same source and
        # action name, and 'virtual-target.register' won't allow two different
        # instances. Therefore, it's OK to use 'set.difference'.
        
        bypassed = set.difference(bypassed, consumed)

        return (consumed, bypassed)
示例#21
0
    def convert_to_consumable_types(self,
                                    project,
                                    name,
                                    prop_set,
                                    sources,
                                    only_one=False):
        """ Attempts to convert 'source' to the types that this generator can
            handle. The intention is to produce the set of targets can should be
            used when generator is run.
            only_one:   convert 'source' to only one of source types
                        if there's more that one possibility, report an
                        error.
                        
            Returns a pair:
                consumed: all targets that can be consumed. 
                bypassed: all targets that cannot be consumed.
        """
        consumed = []
        bypassed = []
        missing_types = []

        if len(sources) > 1:
            # Don't know how to handle several sources yet. Just try
            # to pass the request to other generator
            missing_types = self.source_types_

        else:
            (c, m) = self.consume_directly(sources[0])
            consumed += c
            missing_types += m

        # No need to search for transformation if
        # some source type has consumed source and
        # no more source types are needed.
        if only_one and consumed:
            missing_types = []

        #TODO: we should check that only one source type
        #if create of 'only_one' is true.
        # TODO: consider if consuned/bypassed separation should
        # be done by 'construct_types'.

        if missing_types:
            transformed = construct_types(project, name, missing_types,
                                          prop_set, sources)

            # Add targets of right type to 'consumed'. Add others to
            # 'bypassed'. The 'generators.construct' rule has done
            # its best to convert everything to the required type.
            # There's no need to rerun it on targets of different types.

            # NOTE: ignoring usage requirements
            for t in transformed[1]:
                if t.type() in missing_types:
                    consumed.append(t)

                else:
                    bypassed.append(t)

        consumed = unique(consumed)
        bypassed = unique(bypassed)

        # remove elements of 'bypassed' that are in 'consumed'

        # Suppose the target type of current generator, X is produced from
        # X_1 and X_2, which are produced from Y by one generator.
        # When creating X_1 from Y, X_2 will be added to 'bypassed'
        # Likewise, when creating X_2 from Y, X_1 will be added to 'bypassed'
        # But they are also in 'consumed'. We have to remove them from
        # bypassed, so that generators up the call stack don't try to convert
        # them.

        # In this particular case, X_1 instance in 'consumed' and X_1 instance
        # in 'bypassed' will be the same: because they have the same source and
        # action name, and 'virtual-target.register' won't allow two different
        # instances. Therefore, it's OK to use 'set.difference'.

        bypassed = set.difference(bypassed, consumed)

        return (consumed, bypassed)