| 145 | static struct ps_map all_property_sets; |
| 146 | |
| 147 | LIST * property_set_create( FRAME * frame, int flags ) |
| 148 | { |
| 149 | LIST * properties = lol_get( frame->args, 0 ); |
| 150 | LIST * sorted = list_sort( properties ); |
| 151 | LIST * unique = list_unique( sorted ); |
| 152 | struct ps_map_entry * pos = ps_map_insert( &all_property_sets, unique ); |
| 153 | list_free( sorted ); |
| 154 | if ( pos->value ) |
| 155 | { |
| 156 | list_free( unique ); |
| 157 | return list_new( object_copy( pos->value ) ); |
| 158 | } |
| 159 | else |
| 160 | { |
| 161 | OBJECT * rulename = object_new( "new" ); |
| 162 | OBJECT * varname = object_new( "self.raw" ); |
| 163 | LIST * val = call_rule( rulename, frame, |
| 164 | list_new( object_new( "property-set" ) ), 0 ); |
| 165 | LISTITER iter, end; |
| 166 | object_free( rulename ); |
| 167 | pos->value = list_front( val ); |
| 168 | var_set( bindmodule( pos->value ), varname, unique, VAR_SET ); |
| 169 | object_free( varname ); |
| 170 | |
| 171 | for ( iter = list_begin( unique ), end = list_end( unique ); iter != end; ++iter ) |
| 172 | { |
| 173 | const char * str = object_str( list_item( iter ) ); |
| 174 | if ( str[ 0 ] != '<' || ! strchr( str, '>' ) ) |
| 175 | { |
| 176 | string message[ 1 ]; |
| 177 | string_new( message ); |
| 178 | string_append( message, "Invalid property: '" ); |
| 179 | string_append( message, str ); |
| 180 | string_append( message, "'" ); |
| 181 | rulename = object_new( "errors.error" ); |
| 182 | call_rule( rulename, frame, |
| 183 | list_new( object_new( message->value ) ), 0 ); |
| 184 | /* unreachable */ |
| 185 | string_free( message ); |
| 186 | object_free( rulename ); |
| 187 | } |
| 188 | } |
| 189 | |
| 190 | return val; |
| 191 | } |
| 192 | } |
| 193 | |
| 194 | /* binary search for the property value */ |
| 195 | LIST * property_set_get( FRAME * frame, int flags ) |
nothing calls this directly
no test coverage detected