Example #1
0
def feature (name, values, attributes = []):
    """ Declares a new feature with the given name, values, and attributes.
        name: the feature name
        values: a sequence of the allowable values - may be extended later with feature.extend
        attributes: a sequence of the feature's attributes (e.g. implicit, free, propagated, ...)
    """
    name = add_grist (name)

    __validate_feature_attributes (name, attributes)

    feature = { 
        'values': [],
        'attributes': attributes,
        'subfeatures': [],
        'default': None
        }
    __all_features [name] = feature
    
    feature ['attributes'] = attributes
    
    for attribute in attributes:
        __features_with_attributes [attribute].append (name)
        
    if 'subfeature' in attributes:
        __all_subfeatures.append(name)
    else:
        __all_top_features.append(name)

    extend (name, values)

    # FIXME: why his is needed.
    if 'free' in attributes:
        __free_features.append (name)
Example #2
0
def extend(name, values):
    """ Adds the given values to the given feature.
    """
    assert isinstance(name, basestring)
    assert is_iterable_typed(values, basestring)
    name = add_grist(name)
    __validate_feature(name)
    feature = __all_features[name]

    if feature.implicit:
        for v in values:
            if v in __implicit_features:
                raise BaseException(
                    "'%s' is already associated with the feature '%s'" %
                    (v, __implicit_features[v]))

            __implicit_features[v] = feature

    if values and not feature.values and not (feature.free
                                              or feature.optional):
        # This is the first value specified for this feature,
        # take it as default value
        feature.set_default(values[0])

    feature.add_values(values)
Example #3
0
def feature(name, values, attributes=[]):
    """ Declares a new feature with the given name, values, and attributes.
        name: the feature name
        values: a sequence of the allowable values - may be extended later with feature.extend
        attributes: a sequence of the feature's attributes (e.g. implicit, free, propagated, ...)
    """
    __validate_feature_attributes(name, attributes)

    feature = Feature(name, [], attributes)
    __all_features[name] = feature
    # Temporary measure while we have not fully moved from 'gristed strings'
    __all_features["<" + name + ">"] = feature

    for attribute in attributes:
        __features_with_attributes[attribute].append(name)

    name = add_grist(name)

    if 'subfeature' in attributes:
        __all_subfeatures.append(name)
    else:
        __all_top_features.append(feature)

    extend(name, values)

    # FIXME: why his is needed.
    if 'free' in attributes:
        __free_features.append(name)

    return feature
Example #4
0
def split_top_feature(feature_plus):
    """ 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.
    """
    e = feature_plus.split('-')
    f = e[0]

    v = None
    while e:
        if add_grist(f) in __all_top_features:
            if len(e) > 1:
                after = '-'.join(e[1:])
            else:
                after = ''

            v = (f, after)

        e = e[1:]
        f = f + '-'
        if len(e): f += e[0]

    return v
Example #5
0
def feature(name, values, attributes=[]):
    """ Declares a new feature with the given name, values, and attributes.
        name: the feature name
        values: a sequence of the allowable values - may be extended later with feature.extend
        attributes: a sequence of the feature's attributes (e.g. implicit, free, propagated, ...)
    """
    name = add_grist(name)

    __validate_feature_attributes(name, attributes)

    feature = {
        'values': [],
        'attributes': attributes,
        'subfeatures': [],
        'default': None
    }
    __all_features[name] = feature

    feature['attributes'] = attributes

    for attribute in attributes:
        __features_with_attributes[attribute].append(name)

    if 'subfeature' in attributes:
        __all_subfeatures.append(name)
    else:
        __all_top_features.append(name)

    extend(name, values)

    # FIXME: why his is needed.
    if 'free' in attributes:
        __free_features.append(name)
Example #6
0
def subfeature(feature_name,
               value_string,
               subfeature,
               subvalues,
               attributes=[]):
    """ Declares a subfeature.
        feature_name:   Root feature that is not a subfeature.
        value_string:   An optional value-string specifying which feature or
                        subfeature values this subfeature is specific to,
                        if any.                
        subfeature:     The name of the subfeature being declared.
        subvalues:      The allowed values of this subfeature.
        attributes:     The attributes of the subfeature.
    """
    feature_name = add_grist(feature_name)
    validate_feature(feature_name)

    # Add grist to the subfeature name if a value-string was supplied
    subfeature_name = __get_subfeature_name(subfeature, value_string)

    if subfeature_name in __all_features[feature_name]['subfeatures']:
        message = "'%s' already declared as a subfeature of '%s'" % (
            subfeature, feature_name)
        message += " specific to '%s'" % value_string
        raise BaseException(message)

    __all_features[feature_name]['subfeatures'].append(subfeature_name)

    # First declare the subfeature as a feature in its own right
    f = ungrist(feature_name)
    feature(f + '-' + subfeature_name, subvalues, attributes + ['subfeature'])

    # Now make sure the subfeature values are known.
    extend_subfeature(feature_name, value_string, subfeature, subvalues)
Example #7
0
def is_subfeature_of(parent_property, f):
    """ Return true iff f is an ordinary subfeature of the parent_property's
        feature, or if f is a subfeature of the parent_property's feature
        specific to the parent_property's value.
    """
    if not valid(f) or not 'subfeature' in __all_features[f]['attributes']:
        return False

    specific_subfeature = __re_split_subfeatures.match(f)

    if specific_subfeature:
        # The feature has the form
        # <topfeature-topvalue:subfeature>,
        # e.g. <toolset-msvc:version>
        feature_value = split_top_feature(specific_subfeature.group(1))
        if replace_grist(feature_value[1],
                         '<' + feature_value[0] + '>') == parent_property:
            return True
    else:
        # The feature has the form <topfeature-subfeature>,
        # e.g. <toolset-version>
        top_sub = split_top_feature(ungrist(f))

        if top_sub[1] and add_grist(top_sub[0]) == get_grist(parent_property):
            return True

    return False
Example #8
0
def set_default (feature, value):
    """ Sets the default value of the given feature, overriding any previous default.
        feature: the name of the feature
        value: the default value to assign
    """

    if isinstance(feature, list):
        feature = feature[0]

    feature = add_grist (feature)
    f = __all_features [feature]
    attributes = f['attributes']
    bad_attribute = None

    if "free" in attributes:
        bad_attribute = "free"
    elif "optional" in attributes:
        bad_attribute = "optional"
        
    if bad_attribute:
        raise InvalidValue ("%s property %s cannot have a default" % (bad_attribute, feature))
        
    if isinstance(value, list):
        value = value[0]

    values = f['values']
    if not value in values:
        raise InvalidValue ("The specified default value, '%s' is invalid.\n" % value + "allowed values are: %s" % values)

    f ['default'] = value
Example #9
0
def split_top_feature (feature_plus):
    """ 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.
    """
    e = feature_plus.split ('-')
    f = e [0]

    v = None
    while e:
        if add_grist (f) in __all_top_features:
            if len (e) > 1:
                after = '-'.join (e [1:])
            else:
                after = ''
                
            v = (f, after)

        e = e [1:]
        f = f + '-'
        if len (e): f += e [0]

    return v
Example #10
0
def subfeature (feature_name, value_string, subfeature, subvalues, attributes = []):
    """ Declares a subfeature.
        feature_name:   Root feature that is not a subfeature.
        value_string:   An optional value-string specifying which feature or
                        subfeature values this subfeature is specific to,
                        if any.                
        subfeature:     The name of the subfeature being declared.
        subvalues:      The allowed values of this subfeature.
        attributes:     The attributes of the subfeature.
    """
    feature_name = add_grist (feature_name)
    validate_feature (feature_name)
    
    # Add grist to the subfeature name if a value-string was supplied
    subfeature_name = __get_subfeature_name (subfeature, value_string)
    
    if subfeature_name in __all_features [feature_name]['subfeatures']:
        message = "'%s' already declared as a subfeature of '%s'" % (subfeature, feature_name)
        message += " specific to '%s'" % value_string
        raise BaseException (message)

    __all_features [feature_name]['subfeatures'].append (subfeature_name)

    # First declare the subfeature as a feature in its own right
    f = ungrist (feature_name)
    feature (f + '-' + subfeature_name, subvalues, attributes + ['subfeature'])
    
    # Now make sure the subfeature values are known.
    extend_subfeature (feature_name, value_string, subfeature, subvalues)
Example #11
0
def is_subfeature_of (parent_property, f):
    """ Return true iff f is an ordinary subfeature of the parent_property's
        feature, or if f is a subfeature of the parent_property's feature
        specific to the parent_property's value.
    """
    if not valid (f) or not 'subfeature' in __all_features [f]['attributes']:
        return False

    specific_subfeature = __re_split_subfeatures.match (f)

    if specific_subfeature:
        # The feature has the form
        # <topfeature-topvalue:subfeature>,
        # e.g. <toolset-msvc:version>
        feature_value = split_top_feature(specific_subfeature.group(1))
        if replace_grist (feature_value [1], '<' + feature_value [0] + '>') == parent_property:
            return True
    else:
        # The feature has the form <topfeature-subfeature>,
        # e.g. <toolset-version>
        top_sub = split_top_feature (ungrist (f))

        if top_sub [1] and add_grist (top_sub [0]) == get_grist (parent_property):
            return True

    return False
Example #12
0
def feature (name, values, attributes = []):
    """ Declares a new feature with the given name, values, and attributes.
        name: the feature name
        values: a sequence of the allowable values - may be extended later with feature.extend
        attributes: a sequence of the feature's attributes (e.g. implicit, free, propagated, ...)
    """
    __validate_feature_attributes (name, attributes)

    feature = Feature(name, [], attributes)
    __all_features[name] = feature
    # Temporary measure while we have not fully moved from 'gristed strings'
    __all_features["<" + name + ">"] = feature
        
    for attribute in attributes:
        __features_with_attributes [attribute].append (name)

    name = add_grist(name)
        
    if 'subfeature' in attributes:
        __all_subfeatures.append(name)
    else:
        __all_top_features.append(feature)

    extend (name, values)

    # FIXME: why his is needed.
    if 'free' in attributes:
        __free_features.append (name)

    return feature
Example #13
0
def set_default(feature, value):
    """ Sets the default value of the given feature, overriding any previous default.
        feature: the name of the feature
        value: the default value to assign
    """

    if isinstance(feature, list):
        feature = feature[0]

    feature = add_grist(feature)
    f = __all_features[feature]
    attributes = f['attributes']
    bad_attribute = None

    if "free" in attributes:
        bad_attribute = "free"
    elif "optional" in attributes:
        bad_attribute = "optional"

    if bad_attribute:
        raise InvalidValue("%s property %s cannot have a default" %
                           (bad_attribute, feature))

    if isinstance(value, list):
        value = value[0]

    values = f['values']
    if not value in values:
        raise InvalidValue("The specified default value, '%s' is invalid.\n" %
                           value + "allowed values are: %s" % values)

    f['default'] = value
Example #14
0
def __find_implied_subfeature(feature, subvalue, value_string):
    feature = add_grist(feature)
    if value_string == None: value_string = ''

    if not __subfeature_value_to_name.has_key (feature) \
        or not __subfeature_value_to_name [feature].has_key (value_string) \
        or not __subfeature_value_to_name [feature][value_string].has_key (subvalue):
        return None

    return __subfeature_value_to_name[feature][value_string][subvalue]
Example #15
0
def __find_implied_subfeature (feature, subvalue, value_string):
    feature = add_grist (feature)
    if value_string == None: value_string = ''

    if not __subfeature_value_to_name.has_key (feature) \
        or not __subfeature_value_to_name [feature].has_key (value_string) \
        or not __subfeature_value_to_name [feature][value_string].has_key (subvalue):
        return None
        
    return __subfeature_value_to_name[feature][value_string][subvalue]
Example #16
0
def extend_subfeature (feature, value_string, subfeature, subvalues):
    feature = add_grist (feature)
    validate_feature (feature)

    if value_string:
        validate_value_string (feature, value_string)

    subfeature_name = __get_subfeature_name (subfeature, value_string)
    
    f = ungrist (feature)
    extend (f + '-' + subfeature_name, subvalues) ;
    
    __add_to_subfeature_value_to_name_map (feature, value_string, subfeature_name, subvalues)
Example #17
0
def extend (name, values):
    """ Adds the given values to the given feature.
    """
    name = add_grist (name)
    __validate_feature (name)
    feature = __all_features [name]

    if feature.implicit():
        for v in values:
            if __implicit_features.has_key(v):
                raise BaseException ("'%s' is already associated with the feature '%s'" % (v, __implicit_features [v]))

            __implicit_features[v] = feature

    if len (feature.values()) == 0 and len (values) > 0:
        # This is the first value specified for this feature,
        # take it as default value
        feature.set_default(values[0])

    feature.add_values(values)
Example #18
0
def extend (name, values):
    """ Adds the given values to the given feature.
    """
    name = add_grist (name)
    __validate_feature (name)
    feature = __all_features [name]
    
    if 'implicit' in feature ['attributes']:
        for v in values:
            if __implicit_features.has_key (v):
                raise BaseException ("'%s' is already associated with the feature '%s'" % (v, __implicit_features [v]))

            __implicit_features[v] = name

    if len (feature ['values']) == 0 and len (values) > 0:
        # This is the first value specified for this feature,
        # take it as default value
        feature ['default'] = values[0]

    feature['values'].extend (values)
Example #19
0
def extend (name, values):
    """ Adds the given values to the given feature.
    """
    name = add_grist (name)
    __validate_feature (name)
    feature = __all_features [name]

    if feature.implicit():
        for v in values:
            if __implicit_features.has_key(v):
                raise BaseException ("'%s' is already associated with the feature '%s'" % (v, __implicit_features [v]))

            __implicit_features[v] = feature

    if len (feature.values()) == 0 and len (values) > 0:
        # This is the first value specified for this feature,
        # take it as default value
        feature.set_default(values[0])

    feature.add_values(values)
Example #20
0
def extend (name, values):
    """ Adds the given values to the given feature.
    """
    assert isinstance(name, basestring)
    assert is_iterable_typed(values, basestring)
    name = add_grist (name)
    __validate_feature (name)
    feature = __all_features [name]

    if feature.implicit():
        for v in values:
            if __implicit_features.has_key(v):
                raise BaseException ("'%s' is already associated with the feature '%s'" % (v, __implicit_features [v]))

            __implicit_features[v] = feature

    if values and not feature.values() and not(feature.free() or feature.optional()):
        # This is the first value specified for this feature,
        # take it as default value
        feature.set_default(values[0])

    feature.add_values(values)