]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/tools/build/src/engine/modules.cpp
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / boost / tools / build / src / engine / modules.cpp
1 /*
2 * Copyright 2001-2004 David Abrahams.
3 * Distributed under the Boost Software License, Version 1.0.
4 * (See accompanying file LICENSE.txt or copy at
5 * https://www.bfgroup.xyz/b2/LICENSE.txt)
6 */
7
8 #include "jam.h"
9 #include "modules.h"
10
11 #include "hash.h"
12 #include "lists.h"
13 #include "native.h"
14 #include "object.h"
15 #include "parse.h"
16 #include "rules.h"
17 #include "jam_strings.h"
18 #include "variable.h"
19
20 #include <assert.h>
21 #include <string.h>
22
23 static struct hash * module_hash = 0;
24 static module_t root;
25
26
27 module_t * bindmodule( OBJECT * name )
28 {
29 if ( !name )
30 return &root;
31
32 {
33 PROFILE_ENTER( BINDMODULE );
34
35 module_t * m;
36 int found;
37
38 if ( !module_hash )
39 module_hash = hashinit( sizeof( module_t ), "modules" );
40
41 m = (module_t *)hash_insert( module_hash, name, &found );
42 if ( !found )
43 {
44 m->name = object_copy( name );
45 m->variables = 0;
46 m->variable_indices = 0;
47 m->num_fixed_variables = 0;
48 m->fixed_variables = 0;
49 m->rules = 0;
50 m->imported_modules = 0;
51 m->class_module = 0;
52 m->native_rules = 0;
53 m->user_module = 0;
54 }
55
56 PROFILE_EXIT( BINDMODULE );
57
58 return m;
59 }
60 }
61
62
63 /*
64 * demand_rules() - Get the module's "rules" hash on demand.
65 */
66 struct hash * demand_rules( module_t * m )
67 {
68 if ( !m->rules )
69 m->rules = hashinit( sizeof( RULE ), "rules" );
70 return m->rules;
71 }
72
73
74 /*
75 * delete_module() - wipe out the module's rules and variables.
76 */
77
78 static void delete_rule_( void * xrule, void * data )
79 {
80 rule_free( (RULE *)xrule );
81 }
82
83
84 static void delete_native_rule( void * xrule, void * data )
85 {
86 native_rule_t * rule = (native_rule_t *)xrule;
87 object_free( rule->name );
88 if ( rule->procedure )
89 function_free( rule->procedure );
90 }
91
92
93 static void delete_imported_modules( void * xmodule_name, void * data )
94 {
95 object_free( *(OBJECT * *)xmodule_name );
96 }
97
98
99 static void free_fixed_variable( void * xvar, void * data );
100
101 void delete_module( module_t * m )
102 {
103 /* Clear out all the rules. */
104 if ( m->rules )
105 {
106 hashenumerate( m->rules, delete_rule_, (void *)0 );
107 hash_free( m->rules );
108 m->rules = 0;
109 }
110
111 if ( m->native_rules )
112 {
113 hashenumerate( m->native_rules, delete_native_rule, (void *)0 );
114 hash_free( m->native_rules );
115 m->native_rules = 0;
116 }
117
118 if ( m->variables )
119 {
120 var_done( m );
121 m->variables = 0;
122 }
123
124 if ( m->fixed_variables )
125 {
126 int i;
127 for ( i = 0; i < m->num_fixed_variables; ++i )
128 {
129 list_free( m->fixed_variables[ i ] );
130 }
131 BJAM_FREE( m->fixed_variables );
132 m->fixed_variables = 0;
133 }
134
135 if ( m->variable_indices )
136 {
137 hashenumerate( m->variable_indices, &free_fixed_variable, (void *)0 );
138 hash_free( m->variable_indices );
139 m->variable_indices = 0;
140 }
141
142 if ( m->imported_modules )
143 {
144 hashenumerate( m->imported_modules, delete_imported_modules, (void *)0 );
145 hash_free( m->imported_modules );
146 m->imported_modules = 0;
147 }
148 }
149
150
151 struct module_stats
152 {
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 ];
158 };
159
160
161 static void module_stat( struct hash * hp, OBJECT * module, const char * name )
162 {
163 if ( hp )
164 {
165 struct hashstats stats[ 1 ];
166 string id[ 1 ];
167 hashstats_init( stats );
168 string_new( id );
169 string_append( id, object_str( module ) );
170 string_push_back( id, ' ' );
171 string_append( id, name );
172
173 hashstats_add( stats, hp );
174 hashstats_print( stats, id->value );
175
176 string_free( id );
177 }
178 }
179
180
181 static void class_module_stat( struct hashstats * stats, OBJECT * module, const char * name )
182 {
183 if ( stats->item_size )
184 {
185 string id[ 1 ];
186 string_new( id );
187 string_append( id, object_str( module ) );
188 string_append( id, " object " );
189 string_append( id, name );
190
191 hashstats_print( stats, id->value );
192
193 string_free( id );
194 }
195 }
196
197
198 static void stat_module( void * xmodule, void * data )
199 {
200 module_t *m = (module_t *)xmodule;
201
202 if ( DEBUG_MEM || DEBUG_PROFILE )
203 {
204 struct hash * class_info = (struct hash *)data;
205 if ( m->class_module )
206 {
207 int found;
208 struct module_stats * ms = (struct module_stats *)hash_insert( class_info, m->class_module->name, &found );
209 if ( !found )
210 {
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 );
216 }
217
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 );
222 }
223 else
224 {
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" );
229 }
230 }
231
232 delete_module( m );
233 object_free( m->name );
234 }
235
236 static void print_class_stats( void * xstats, void * data )
237 {
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" );
243 }
244
245
246 static void delete_module_( void * xmodule, void * data )
247 {
248 module_t *m = (module_t *)xmodule;
249
250 delete_module( m );
251 object_free( m->name );
252 }
253
254
255 void modules_done()
256 {
257 if ( module_hash )
258 {
259 if ( DEBUG_MEM || DEBUG_PROFILE )
260 {
261 struct hash * class_hash = hashinit( sizeof( struct module_stats ), "object info" );
262 hashenumerate( module_hash, stat_module, (void *)class_hash );
263 hashenumerate( class_hash, print_class_stats, (void *)0 );
264 hash_free( class_hash );
265 }
266 hashenumerate( module_hash, delete_module_, (void *)0 );
267 hashdone( module_hash );
268 }
269 module_hash = 0;
270 delete_module( &root );
271 }
272
273 module_t * root_module()
274 {
275 return &root;
276 }
277
278
279 void import_module( LIST * module_names, module_t * target_module )
280 {
281 PROFILE_ENTER( IMPORT_MODULE );
282
283 struct hash * h;
284 LISTITER iter;
285 LISTITER end;
286
287 if ( !target_module->imported_modules )
288 target_module->imported_modules = hashinit( sizeof( char * ), "imported"
289 );
290 h = target_module->imported_modules;
291
292 iter = list_begin( module_names );
293 end = list_end( module_names );
294 for ( ; iter != end; iter = list_next( iter ) )
295 {
296 int found;
297 OBJECT * const s = list_item( iter );
298 OBJECT * * const ss = (OBJECT * *)hash_insert( h, s, &found );
299 if ( !found )
300 *ss = object_copy( s );
301 }
302
303 PROFILE_EXIT( IMPORT_MODULE );
304 }
305
306
307 static void add_module_name( void * r_, void * result_ )
308 {
309 OBJECT * * const r = (OBJECT * *)r_;
310 LIST * * const result = (LIST * *)result_;
311 *result = list_push_back( *result, object_copy( *r ) );
312 }
313
314
315 LIST * imported_modules( module_t * module )
316 {
317 LIST * result = L0;
318 if ( module->imported_modules )
319 hashenumerate( module->imported_modules, add_module_name, &result );
320 return result;
321 }
322
323
324 FUNCTION * function_bind_variables( FUNCTION *, module_t *, int * counter );
325 FUNCTION * function_unbind_variables( FUNCTION * );
326
327 struct fixed_variable
328 {
329 OBJECT * key;
330 int n;
331 };
332
333 struct bind_vars_t
334 {
335 module_t * module;
336 int counter;
337 };
338
339
340 static void free_fixed_variable( void * xvar, void * data )
341 {
342 object_free( ( (struct fixed_variable *)xvar )->key );
343 }
344
345
346 static void bind_variables_for_rule( void * xrule, void * xdata )
347 {
348 RULE * rule = (RULE *)xrule;
349 struct bind_vars_t * data = (struct bind_vars_t *)xdata;
350 if ( rule->procedure && rule->module == data->module )
351 rule->procedure = function_bind_variables( rule->procedure,
352 data->module, &data->counter );
353 }
354
355
356 void module_bind_variables( struct module_t * m )
357 {
358 if ( m != root_module() && m->rules )
359 {
360 struct bind_vars_t data;
361 data.module = m;
362 data.counter = m->num_fixed_variables;
363 hashenumerate( m->rules, &bind_variables_for_rule, &data );
364 module_set_fixed_variables( m, data.counter );
365 }
366 }
367
368
369 int module_add_fixed_var( struct module_t * m, OBJECT * name, int * counter )
370 {
371 struct fixed_variable * v;
372 int found;
373
374 assert( !m->class_module );
375
376 if ( !m->variable_indices )
377 m->variable_indices = hashinit( sizeof( struct fixed_variable ), "variable index table" );
378
379 v = (struct fixed_variable *)hash_insert( m->variable_indices, name, &found );
380 if ( !found )
381 {
382 v->key = object_copy( name );
383 v->n = (*counter)++;
384 }
385
386 return v->n;
387 }
388
389
390 LIST * var_get_and_clear_raw( module_t * m, OBJECT * name );
391
392 static void load_fixed_variable( void * xvar, void * data )
393 {
394 struct fixed_variable * var = (struct fixed_variable *)xvar;
395 struct module_t * m = (struct module_t *)data;
396 if ( var->n >= m->num_fixed_variables )
397 m->fixed_variables[ var->n ] = var_get_and_clear_raw( m, var->key );
398 }
399
400
401 void module_set_fixed_variables( struct module_t * m, int n_variables )
402 {
403 /* Reallocate */
404 struct hash * variable_indices;
405 LIST * * fixed_variables = (LIST * *)BJAM_MALLOC( n_variables * sizeof( LIST * ) );
406 if ( m->fixed_variables )
407 {
408 memcpy( fixed_variables, m->fixed_variables, m->num_fixed_variables * sizeof( LIST * ) );
409 BJAM_FREE( m->fixed_variables );
410 }
411 m->fixed_variables = fixed_variables;
412 variable_indices = m->class_module
413 ? m->class_module->variable_indices
414 : m->variable_indices;
415 if ( variable_indices )
416 hashenumerate( variable_indices, &load_fixed_variable, m );
417 m->num_fixed_variables = n_variables;
418 }
419
420
421 int module_get_fixed_var( struct module_t * m_, OBJECT * name )
422 {
423 struct fixed_variable * v;
424 struct module_t * m = m_;
425
426 if ( m->class_module )
427 m = m->class_module;
428
429 if ( !m->variable_indices )
430 return -1;
431
432 v = (struct fixed_variable *)hash_find( m->variable_indices, name );
433 return v && v->n < m_->num_fixed_variables ? v->n : -1;
434 }