2 * Copyright 2001-2004 David Abrahams.
3 * Distributed under the Boost Software License, Version 1.0.
4 * (See accompanying file LICENSE_1_0.txt or copy at
5 * http://www.boost.org/LICENSE_1_0.txt)
23 static struct hash
* module_hash
= 0;
27 module_t
* bindmodule( OBJECT
* name
)
33 PROFILE_ENTER( BINDMODULE
);
39 module_hash
= hashinit( sizeof( module_t
), "modules" );
41 m
= (module_t
*)hash_insert( module_hash
, name
, &found
);
44 m
->name
= object_copy( name
);
46 m
->variable_indices
= 0;
47 m
->num_fixed_variables
= 0;
48 m
->fixed_variables
= 0;
50 m
->imported_modules
= 0;
56 PROFILE_EXIT( BINDMODULE
);
64 * demand_rules() - Get the module's "rules" hash on demand.
66 struct hash
* demand_rules( module_t
* m
)
69 m
->rules
= hashinit( sizeof( RULE
), "rules" );
75 * delete_module() - wipe out the module's rules and variables.
78 static void delete_rule_( void * xrule
, void * data
)
80 rule_free( (RULE
*)xrule
);
84 static void delete_native_rule( void * xrule
, void * data
)
86 native_rule_t
* rule
= (native_rule_t
*)xrule
;
87 object_free( rule
->name
);
88 if ( rule
->procedure
)
89 function_free( rule
->procedure
);
93 static void delete_imported_modules( void * xmodule_name
, void * data
)
95 object_free( *(OBJECT
* *)xmodule_name
);
99 static void free_fixed_variable( void * xvar
, void * data
);
101 void delete_module( module_t
* m
)
103 /* Clear out all the rules. */
106 hashenumerate( m
->rules
, delete_rule_
, (void *)0 );
107 hash_free( m
->rules
);
111 if ( m
->native_rules
)
113 hashenumerate( m
->native_rules
, delete_native_rule
, (void *)0 );
114 hash_free( m
->native_rules
);
124 if ( m
->fixed_variables
)
127 for ( i
= 0; i
< m
->num_fixed_variables
; ++i
)
129 list_free( m
->fixed_variables
[ i
] );
131 BJAM_FREE( m
->fixed_variables
);
132 m
->fixed_variables
= 0;
135 if ( m
->variable_indices
)
137 hashenumerate( m
->variable_indices
, &free_fixed_variable
, (void *)0 );
138 hash_free( m
->variable_indices
);
139 m
->variable_indices
= 0;
142 if ( m
->imported_modules
)
144 hashenumerate( m
->imported_modules
, delete_imported_modules
, (void *)0 );
145 hash_free( m
->imported_modules
);
146 m
->imported_modules
= 0;
153 OBJECT
* module_name
;
154 struct hashstats rules_stats
[ 1 ];
155 struct hashstats variables_stats
[ 1 ];
156 struct hashstats variable_indices_stats
[ 1 ];
157 struct hashstats imported_modules_stats
[ 1 ];
161 static void module_stat( struct hash
* hp
, OBJECT
* module
, const char * name
)
165 struct hashstats stats
[ 1 ];
167 hashstats_init( stats
);
169 string_append( id
, object_str( module
) );
170 string_push_back( id
, ' ' );
171 string_append( id
, name
);
173 hashstats_add( stats
, hp
);
174 hashstats_print( stats
, id
->value
);
181 static void class_module_stat( struct hashstats
* stats
, OBJECT
* module
, const char * name
)
183 if ( stats
->item_size
)
187 string_append( id
, object_str( module
) );
188 string_append( id
, " object " );
189 string_append( id
, name
);
191 hashstats_print( stats
, id
->value
);
198 static void stat_module( void * xmodule
, void * data
)
200 module_t
*m
= (module_t
*)xmodule
;
202 if ( DEBUG_MEM
|| DEBUG_PROFILE
)
204 struct hash
* class_info
= (struct hash
*)data
;
205 if ( m
->class_module
)
208 struct module_stats
* ms
= (struct module_stats
*)hash_insert( class_info
, m
->class_module
->name
, &found
);
211 ms
->module_name
= m
->class_module
->name
;
212 hashstats_init( ms
->rules_stats
);
213 hashstats_init( ms
->variables_stats
);
214 hashstats_init( ms
->variable_indices_stats
);
215 hashstats_init( ms
->imported_modules_stats
);
218 hashstats_add( ms
->rules_stats
, m
->rules
);
219 hashstats_add( ms
->variables_stats
, m
->variables
);
220 hashstats_add( ms
->variable_indices_stats
, m
->variable_indices
);
221 hashstats_add( ms
->imported_modules_stats
, m
->imported_modules
);
225 module_stat( m
->rules
, m
->name
, "rules" );
226 module_stat( m
->variables
, m
->name
, "variables" );
227 module_stat( m
->variable_indices
, m
->name
, "fixed variables" );
228 module_stat( m
->imported_modules
, m
->name
, "imported modules" );
233 object_free( m
->name
);
236 static void print_class_stats( void * xstats
, void * data
)
238 struct module_stats
* stats
= (struct module_stats
*)xstats
;
239 class_module_stat( stats
->rules_stats
, stats
->module_name
, "rules" );
240 class_module_stat( stats
->variables_stats
, stats
->module_name
, "variables" );
241 class_module_stat( stats
->variable_indices_stats
, stats
->module_name
, "fixed variables" );
242 class_module_stat( stats
->imported_modules_stats
, stats
->module_name
, "imported modules" );
246 static void delete_module_( void * xmodule
, void * data
)
248 module_t
*m
= (module_t
*)xmodule
;
251 object_free( m
->name
);
257 if ( DEBUG_MEM
|| DEBUG_PROFILE
)
259 struct hash
* class_hash
= hashinit( sizeof( struct module_stats
), "object info" );
260 hashenumerate( module_hash
, stat_module
, (void *)class_hash
);
261 hashenumerate( class_hash
, print_class_stats
, (void *)0 );
262 hash_free( class_hash
);
264 hashenumerate( module_hash
, delete_module_
, (void *)0 );
265 hashdone( module_hash
);
267 delete_module( &root
);
270 module_t
* root_module()
276 void import_module( LIST
* module_names
, module_t
* target_module
)
278 PROFILE_ENTER( IMPORT_MODULE
);
284 if ( !target_module
->imported_modules
)
285 target_module
->imported_modules
= hashinit( sizeof( char * ), "imported"
287 h
= target_module
->imported_modules
;
289 iter
= list_begin( module_names
);
290 end
= list_end( module_names
);
291 for ( ; iter
!= end
; iter
= list_next( iter
) )
294 OBJECT
* const s
= list_item( iter
);
295 OBJECT
* * const ss
= (OBJECT
* *)hash_insert( h
, s
, &found
);
297 *ss
= object_copy( s
);
300 PROFILE_EXIT( IMPORT_MODULE
);
304 static void add_module_name( void * r_
, void * result_
)
306 OBJECT
* * const r
= (OBJECT
* *)r_
;
307 LIST
* * const result
= (LIST
* *)result_
;
308 *result
= list_push_back( *result
, object_copy( *r
) );
312 LIST
* imported_modules( module_t
* module
)
315 if ( module
->imported_modules
)
316 hashenumerate( module
->imported_modules
, add_module_name
, &result
);
321 FUNCTION
* function_bind_variables( FUNCTION
*, module_t
*, int * counter
);
322 FUNCTION
* function_unbind_variables( FUNCTION
* );
324 struct fixed_variable
337 static void free_fixed_variable( void * xvar
, void * data
)
339 object_free( ( (struct fixed_variable
*)xvar
)->key
);
343 static void bind_variables_for_rule( void * xrule
, void * xdata
)
345 RULE
* rule
= (RULE
*)xrule
;
346 struct bind_vars_t
* data
= (struct bind_vars_t
*)xdata
;
347 if ( rule
->procedure
&& rule
->module
== data
->module
)
348 rule
->procedure
= function_bind_variables( rule
->procedure
,
349 data
->module
, &data
->counter
);
353 void module_bind_variables( struct module_t
* m
)
355 if ( m
!= root_module() && m
->rules
)
357 struct bind_vars_t data
;
359 data
.counter
= m
->num_fixed_variables
;
360 hashenumerate( m
->rules
, &bind_variables_for_rule
, &data
);
361 module_set_fixed_variables( m
, data
.counter
);
366 int module_add_fixed_var( struct module_t
* m
, OBJECT
* name
, int * counter
)
368 struct fixed_variable
* v
;
371 assert( !m
->class_module
);
373 if ( !m
->variable_indices
)
374 m
->variable_indices
= hashinit( sizeof( struct fixed_variable
), "variable index table" );
376 v
= (struct fixed_variable
*)hash_insert( m
->variable_indices
, name
, &found
);
379 v
->key
= object_copy( name
);
387 LIST
* var_get_and_clear_raw( module_t
* m
, OBJECT
* name
);
389 static void load_fixed_variable( void * xvar
, void * data
)
391 struct fixed_variable
* var
= (struct fixed_variable
*)xvar
;
392 struct module_t
* m
= (struct module_t
*)data
;
393 if ( var
->n
>= m
->num_fixed_variables
)
394 m
->fixed_variables
[ var
->n
] = var_get_and_clear_raw( m
, var
->key
);
398 void module_set_fixed_variables( struct module_t
* m
, int n_variables
)
401 struct hash
* variable_indices
;
402 LIST
* * fixed_variables
= (LIST
* *)BJAM_MALLOC( n_variables
* sizeof( LIST
* ) );
403 if ( m
->fixed_variables
)
405 memcpy( fixed_variables
, m
->fixed_variables
, m
->num_fixed_variables
* sizeof( LIST
* ) );
406 BJAM_FREE( m
->fixed_variables
);
408 m
->fixed_variables
= fixed_variables
;
409 variable_indices
= m
->class_module
410 ? m
->class_module
->variable_indices
411 : m
->variable_indices
;
412 if ( variable_indices
)
413 hashenumerate( variable_indices
, &load_fixed_variable
, m
);
414 m
->num_fixed_variables
= n_variables
;
418 int module_get_fixed_var( struct module_t
* m_
, OBJECT
* name
)
420 struct fixed_variable
* v
;
421 struct module_t
* m
= m_
;
423 if ( m
->class_module
)
426 if ( !m
->variable_indices
)
429 v
= (struct fixed_variable
*)hash_find( m
->variable_indices
, name
);
430 return v
&& v
->n
< m_
->num_fixed_variables
? v
->n
: -1;