2 * Copyright 1993, 1995 Christopher Seiwald.
4 * This file is part of Jam - see jam.c for Copyright information.
8 * Copyright 2001-2004 David Abrahams.
9 * Distributed under the Boost Software License, Version 1.0.
10 * (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
14 * rules.c - access to RULEs, TARGETs, and ACTIONs
17 * bindrule() - return pointer to RULE, creating it if necessary.
18 * bindtarget() - return pointer to TARGET, creating it if necessary.
19 * touch_target() - mark a target to simulate being new.
20 * targetlist() - turn list of target names into a TARGET chain.
21 * targetentry() - add a TARGET to a chain of TARGETS.
22 * actionlist() - append to an ACTION chain.
23 * addsettings() - add a deferred "set" command to a target.
24 * pushsettings() - set all target specific variables.
25 * popsettings() - reset target specific variables to their pre-push values.
26 * freesettings() - delete a settings list.
27 * rules_done() - free RULE and TARGET tables.
42 static void set_rule_actions( RULE *, rule_actions * );
43 static void set_rule_body ( RULE *, FUNCTION * );
45 static struct hash * targethash = 0;
49 * get_target_includes() - lazy creates a target's internal includes node
51 * The newly created node is not entered into the hash table as there should
52 * never be a need to bind them directly from a target names. If you want to
53 * access an internal includes node by name, first access the actual target and
54 * then read the internal includes node from there.
57 static TARGET * get_target_includes( TARGET * const t )
61 TARGET * const i = (TARGET *)BJAM_MALLOC( sizeof( *t ) );
62 memset( (char *)i, '\0', sizeof( *i ) );
63 i->name = object_copy( t->name );
64 i->boundname = object_copy( i->name );
65 i->flags |= T_FLAG_NOTFILE | T_FLAG_INTERNAL;
66 i->original_target = t;
74 * target_include() - adds a target to the given targe's 'included' list
75 * target_include_many() - adds targets to the given target's 'included' list
77 * Included targets are modeled as dependencies of the including target's
78 * internal include node.
81 void target_include( TARGET * const including, TARGET * const included )
83 TARGET * const internal = get_target_includes( including );
84 internal->depends = targetentry( internal->depends, included );
87 void target_include_many( TARGET * const including, LIST * const included_names
90 TARGET * const internal = get_target_includes( including );
91 internal->depends = targetlist( internal->depends, included_names );
96 * enter_rule() - return pointer to RULE, creating it if necessary in
100 static RULE * enter_rule( OBJECT * rulename, module_t * target_module )
103 RULE * const r = (RULE *)hash_insert( demand_rules( target_module ),
107 r->name = object_copy( rulename );
112 r->module = target_module;
119 * define_rule() - return pointer to RULE, creating it if necessary in
120 * target_module. Prepare it to accept a body or action originating in
124 static RULE * define_rule( module_t * src_module, OBJECT * rulename,
125 module_t * target_module )
127 RULE * const r = enter_rule( rulename, target_module );
128 if ( r->module != src_module )
130 /* If the rule was imported from elsewhere, clear it now. */
131 set_rule_body( r, 0 );
132 set_rule_actions( r, 0 );
133 /* r will be executed in the source module. */
134 r->module = src_module;
140 void rule_free( RULE * r )
142 object_free( r->name );
145 function_free( r->procedure );
148 actions_free( r->actions );
154 * bindtarget() - return pointer to TARGET, creating it if necessary.
157 TARGET * bindtarget( OBJECT * const target_name )
163 targethash = hashinit( sizeof( TARGET ), "targets" );
165 t = (TARGET *)hash_insert( targethash, target_name, &found );
168 memset( (char *)t, '\0', sizeof( *t ) );
169 t->name = object_copy( target_name );
170 t->boundname = object_copy( t->name ); /* default for T_FLAG_NOTFILE */
177 static void bind_explicitly_located_target( void * xtarget, void * data )
179 TARGET * t = (TARGET *)xtarget;
180 if ( !( t->flags & T_FLAG_NOTFILE ) )
182 /* Check if there is a setting for LOCATE. */
183 SETTINGS * s = t->settings;
184 for ( ; s ; s = s->next )
186 if ( object_equal( s->symbol, constant_LOCATE ) && ! list_empty( s->value ) )
188 set_explicit_binding( t->name, list_front( s->value ) );
196 void bind_explicitly_located_targets()
199 hashenumerate( targethash, bind_explicitly_located_target, (void *)0 );
204 * touch_target() - mark a target to simulate being new.
207 void touch_target( OBJECT * const t )
209 bindtarget( t )->flags |= T_FLAG_TOUCHED;
214 * target_scc() - returns the root of a strongly connected component that this
215 * target is a part of.
218 TARGET * target_scc( TARGET * t )
221 while ( result->scc_root )
222 result = result->scc_root;
223 while ( t->scc_root )
225 TARGET * const tmp = t->scc_root;
226 t->scc_root = result;
234 * targetlist() - turn list of target names into a TARGET chain.
237 * chain existing TARGETS to append to
238 * targets list of target names
241 TARGETS * targetlist( TARGETS * chain, LIST * target_names )
243 LISTITER iter = list_begin( target_names );
244 LISTITER const end = list_end( target_names );
245 for ( ; iter != end; iter = list_next( iter ) )
246 chain = targetentry( chain, bindtarget( list_item( iter ) ) );
252 * targetentry() - add a TARGET to a chain of TARGETS.
255 * chain existing TARGETS to append to
256 * target new target to append
259 TARGETS * targetentry( TARGETS * chain, TARGET * target )
261 TARGETS * const c = (TARGETS *)BJAM_MALLOC( sizeof( TARGETS ) );
264 if ( !chain ) chain = c;
265 else chain->tail->next = c;
274 * targetchain() - append two TARGET chains.
277 * chain existing TARGETS to append to
278 * target new target to append
281 TARGETS * targetchain( TARGETS * chain, TARGETS * targets )
283 if ( !targets ) return chain;
284 if ( !chain ) return targets;
286 chain->tail->next = targets;
287 chain->tail = targets->tail;
292 * action_free - decrement the ACTIONs refrence count and (maybe) free it.
295 void action_free( ACTION * action )
297 if ( --action->refs == 0 )
299 freetargets( action->targets );
300 freetargets( action->sources );
307 * actionlist() - append to an ACTION chain.
310 ACTIONS * actionlist( ACTIONS * chain, ACTION * action )
312 ACTIONS * const actions = (ACTIONS *)BJAM_MALLOC( sizeof( ACTIONS ) );
313 actions->action = action;
315 if ( !chain ) chain = actions;
316 else chain->tail->next = actions;
317 chain->tail = actions;
322 static SETTINGS * settings_freelist;
326 * addsettings() - add a deferred "set" command to a target.
328 * Adds a variable setting (varname=list) onto a chain of settings for a
329 * particular target. 'flag' controls the relationship between new and old
330 * values in the same way as in var_set() function (see variable.c). Returns the
331 * head of the settings chain.
334 SETTINGS * addsettings( SETTINGS * head, int flag, OBJECT * symbol,
339 /* Look for previous settings. */
340 for ( v = head; v; v = v->next )
341 if ( object_equal( v->symbol, symbol ) )
344 /* If not previously set, alloc a new. */
345 /* If appending, do so. */
346 /* Else free old and set new. */
349 v = settings_freelist;
351 settings_freelist = v->next;
353 v = (SETTINGS *)BJAM_MALLOC( sizeof( *v ) );
355 v->symbol = object_copy( symbol );
360 else if ( flag == VAR_APPEND )
362 v->value = list_append( v->value, value );
364 else if ( flag != VAR_DEFAULT )
366 list_free( v->value );
372 /* Return (new) head of list. */
378 * pushsettings() - set all target specific variables.
381 void pushsettings( struct module_t * module, SETTINGS * v )
383 for ( ; v; v = v->next )
384 v->value = var_swap( module, v->symbol, v->value );
389 * popsettings() - reset target specific variables to their pre-push values.
392 void popsettings( struct module_t * module, SETTINGS * v )
394 pushsettings( module, v ); /* just swap again */
399 * copysettings() - duplicate a settings list, returning the new copy.
402 SETTINGS * copysettings( SETTINGS * head )
406 for ( v = head; v; v = v->next )
407 copy = addsettings( copy, VAR_SET, v->symbol, list_copy( v->value ) );
413 * freetargets() - delete a targets list.
416 void freetargets( TARGETS * chain )
420 TARGETS * const n = chain->next;
428 * freeactions() - delete an action list.
431 void freeactions( ACTIONS * chain )
435 ACTIONS * const n = chain->next;
436 action_free( chain->action );
444 * freesettings() - delete a settings list.
447 void freesettings( SETTINGS * v )
451 SETTINGS * const n = v->next;
452 object_free( v->symbol );
453 list_free( v->value );
454 v->next = settings_freelist;
455 settings_freelist = v;
461 static void freetarget( void * xt, void * data )
463 TARGET * const t = (TARGET *)xt;
464 if ( t->name ) object_free ( t->name );
465 if ( t->boundname ) object_free ( t->boundname );
466 if ( t->settings ) freesettings( t->settings );
467 if ( t->depends ) freetargets ( t->depends );
468 if ( t->dependants ) freetargets ( t->dependants );
469 if ( t->parents ) freetargets ( t->parents );
470 if ( t->actions ) freeactions ( t->actions );
473 freetarget( t->includes, (void *)0 );
474 BJAM_FREE( t->includes );
480 * rules_done() - free RULE and TARGET tables.
487 hashenumerate( targethash, freetarget, 0 );
488 hashdone( targethash );
490 while ( settings_freelist )
492 SETTINGS * const n = settings_freelist->next;
493 BJAM_FREE( settings_freelist );
494 settings_freelist = n;
500 * actions_refer() - add a new reference to the given actions.
503 void actions_refer( rule_actions * a )
505 ++a->reference_count;
510 * actions_free() - release a reference to given actions.
513 void actions_free( rule_actions * a )
515 if ( --a->reference_count <= 0 )
517 function_free( a->command );
518 list_free( a->bindlist );
525 * set_rule_body() - set the argument list and procedure of the given rule.
528 static void set_rule_body( RULE * rule, FUNCTION * procedure )
531 function_refer( procedure );
532 if ( rule->procedure )
533 function_free( rule->procedure );
534 rule->procedure = procedure;
539 * global_name() - given a rule, return the name for a corresponding rule in the
543 static OBJECT * global_rule_name( RULE * r )
545 if ( r->module == root_module() )
546 return object_copy( r->name );
549 char name[ 4096 ] = "";
550 if ( r->module->name )
552 strncat( name, object_str( r->module->name ), sizeof( name ) - 1 );
553 strncat( name, ".", sizeof( name ) - 1 );
555 strncat( name, object_str( r->name ), sizeof( name ) - 1 );
556 return object_new( name );
562 * global_rule() - given a rule, produce a corresponding entry in the global
566 static RULE * global_rule( RULE * r )
568 if ( r->module == root_module() )
572 OBJECT * const name = global_rule_name( r );
573 RULE * const result = define_rule( r->module, name, root_module() );
581 * new_rule_body() - make a new rule named rulename in the given module, with
582 * the given argument list and procedure. If exported is true, the rule is
583 * exported to the global module as modulename.rulename.
586 RULE * new_rule_body( module_t * m, OBJECT * rulename, FUNCTION * procedure,
589 RULE * const local = define_rule( m, rulename, m );
590 local->exported = exported;
591 set_rule_body( local, procedure );
593 /* Mark the procedure with the global rule name, regardless of whether the
594 * rule is exported. That gives us something reasonably identifiable that we
595 * can use, e.g. in profiling output. Only do this once, since this could be
596 * called multiple times with the same procedure.
598 if ( !function_rulename( procedure ) )
599 function_set_rulename( procedure, global_rule_name( local ) );
605 static void set_rule_actions( RULE * rule, rule_actions * actions )
608 actions_refer( actions );
610 actions_free( rule->actions );
611 rule->actions = actions;
615 static rule_actions * actions_new( FUNCTION * command, LIST * bindlist,
618 rule_actions * const result = (rule_actions *)BJAM_MALLOC( sizeof(
620 function_refer( command );
621 result->command = command;
622 result->bindlist = bindlist;
623 result->flags = flags;
624 result->reference_count = 0;
629 RULE * new_rule_actions( module_t * m, OBJECT * rulename, FUNCTION * command,
630 LIST * bindlist, int flags )
632 RULE * const local = define_rule( m, rulename, m );
633 RULE * const global = global_rule( local );
634 set_rule_actions( local, actions_new( command, bindlist, flags ) );
635 set_rule_actions( global, local->actions );
641 * Looks for a rule in the specified module, and returns it, if found. First
642 * checks if the rule is present in the module's rule table. Second, if the
643 * rule's name is in the form name1.name2 and name1 is in the list of imported
644 * modules, look in module 'name1' for rule 'name2'.
647 RULE * lookup_rule( OBJECT * rulename, module_t * m, int local_only )
651 module_t * original_module = m;
653 if ( m->class_module )
656 if ( m->rules && ( r = (RULE *)hash_find( m->rules, rulename ) ) )
658 else if ( !local_only && m->imported_modules )
660 /* Try splitting the name into module and rule. */
661 char * p = strchr( object_str( rulename ), '.' ) ;
664 /* Now, r->name keeps the module name, and p + 1 keeps the rule
667 OBJECT * rule_part = object_new( p + 1 );
668 OBJECT * module_part;
672 string_append_range( buf, object_str( rulename ), p );
673 module_part = object_new( buf->value );
676 if ( hash_find( m->imported_modules, module_part ) )
677 result = lookup_rule( rule_part, bindmodule( module_part ), 1 );
678 object_free( module_part );
679 object_free( rule_part );
685 if ( local_only && !result->exported )
687 else if ( original_module != m )
689 /* Lookup started in class module. We have found a rule in class
690 * module, which is marked for execution in that module, or in some
691 * instance. Mark it for execution in the instance where we started
694 int const execute_in_class = result->module == m;
695 int const execute_in_some_instance =
696 result->module->class_module == m;
697 if ( execute_in_class || execute_in_some_instance )
698 result->module = original_module;
706 RULE * bindrule( OBJECT * rulename, module_t * m )
708 RULE * result = lookup_rule( rulename, m, 0 );
710 result = lookup_rule( rulename, root_module(), 0 );
711 /* We have only one caller, 'evaluate_rule', which will complain about
712 * calling an undefined rule. We could issue the error here, but we do not
713 * have the necessary information, such as frame.
716 result = enter_rule( rulename, m );
721 RULE * import_rule( RULE * source, module_t * m, OBJECT * name )
723 RULE * const dest = define_rule( source->module, name, m );
724 set_rule_body( dest, source->procedure );
725 set_rule_actions( dest, source->actions );
730 void rule_localize( RULE * rule, module_t * m )
733 if ( rule->procedure )
735 FUNCTION * procedure = function_unbind_variables( rule->procedure );
736 function_refer( procedure );
737 function_free( rule->procedure );
738 rule->procedure = procedure;