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; }
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; } }