LIST *property_set_create( PARSE *parse, FRAME *frame )
{
    LIST* properties = lol_get( frame->args, 0 );    
    LIST* sorted = 0;
    LIST* order_sensitive = 0;
    LIST* unique;
    LIST* tmp;
    LIST* val;
    string var[1];

#if 0
    /* Sort all properties which are not order sensitive */
    for(tmp = properties; tmp; tmp = tmp->next) {
        LIST* g = get_grist(tmp->string);
        LIST* att = call_rule("feature.attributes", frame, g, 0);
        if (list_in(att, "order-sensitive")) {
            order_sensitive = list_new( order_sensitive, tmp->string);
        } else {
            sorted = list_new( sorted, tmp->string);
        }
        list_free(att);
    }
    
    sorted = list_sort(sorted);
    sorted = list_append(sorted, order_sensitive);
    unique = list_unique(sorted);
#endif
    sorted = list_sort(properties);
    unique = list_unique(sorted);

    string_new(var);
    string_append(var, ".ps.");
    
    for(tmp = unique; tmp; tmp = tmp->next) {
        string_append(var, tmp->string);
        string_push_back(var, '-');
    }
    val = var_get(var->value);
    if (val == 0) 
    {          
        val = call_rule("new", frame, 
                        list_append(list_new(0, "property-set"), unique), 0);                
        
        var_set(newstr(var->value), list_copy(0, val), VAR_SET);
    }
    else
    {
        val = list_copy(0, val);
    }
    
    string_free(var);
    /* The 'unique' variable is freed in 'call_rule'. */
    list_free(sorted);

    return val;

}
Пример #2
0
LIST * property_set_create( FRAME * frame, int flags )
{
    LIST * properties = lol_get( frame->args, 0 );
    LIST * sorted = list_sort( properties );
    LIST * unique = list_unique( sorted );
    struct ps_map_entry * pos = ps_map_insert( &all_property_sets, unique );
    list_free( sorted );
    if ( pos->value )
    {
        list_free( unique );
        return list_new( object_copy( pos->value ) );
    }
    else
    {
        OBJECT * rulename = object_new( "new" );
        OBJECT * varname = object_new( "self.raw" );
        LIST * val = call_rule( rulename, frame,
            list_new( object_new( "property-set" ) ), 0 );
        LISTITER iter, end;
        object_free( rulename );
        pos->value = list_front( val );
        var_set( bindmodule( pos->value ), varname, unique, VAR_SET );
        object_free( varname );

        for ( iter = list_begin( unique ), end = list_end( unique ); iter != end; ++iter )
        {
            const char * str = object_str( list_item( iter ) );
            if ( str[ 0 ] != '<' || ! strchr( str, '>' ) )
            {
                string message[ 1 ];
                string_new( message );
                string_append( message, "Invalid property: '" );
                string_append( message, str );
                string_append( message, "'" );
                rulename = object_new( "errors.error" );
                call_rule( rulename, frame,
                    list_new( object_new( message->value ) ), 0 );
                /* unreachable */
                string_free( message );
                object_free( rulename );
            }
        }

        return val;
    }
}