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
;
73 * target_include() - adds a target to the given targe's 'included' list
74 * target_include_many() - adds targets to the given target's 'included' list
76 * Included targets are modeled as dependencies of the including target's
77 * internal include node.
80 void target_include( TARGET
* const including
, TARGET
* const included
)
82 TARGET
* const internal
= get_target_includes( including
);
83 internal
->depends
= targetentry( internal
->depends
, included
);
86 void target_include_many( TARGET
* const including
, LIST
* const included_names
89 TARGET
* const internal
= get_target_includes( including
);
90 internal
->depends
= targetlist( internal
->depends
, included_names
);
95 * enter_rule() - return pointer to RULE, creating it if necessary in
99 static RULE
* enter_rule( OBJECT
* rulename
, module_t
* target_module
)
102 RULE
* const r
= (RULE
*)hash_insert( demand_rules( target_module
),
106 r
->name
= object_copy( rulename
);
111 r
->module
= target_module
;
118 * define_rule() - return pointer to RULE, creating it if necessary in
119 * target_module. Prepare it to accept a body or action originating in
123 static RULE
* define_rule( module_t
* src_module
, OBJECT
* rulename
,
124 module_t
* target_module
)
126 RULE
* const r
= enter_rule( rulename
, target_module
);
127 if ( r
->module
!= src_module
)
129 /* If the rule was imported from elsewhere, clear it now. */
130 set_rule_body( r
, 0 );
131 set_rule_actions( r
, 0 );
132 /* r will be executed in the source module. */
133 r
->module
= src_module
;
139 void rule_free( RULE
* r
)
141 object_free( r
->name
);
144 function_free( r
->procedure
);
147 actions_free( r
->actions
);
153 * bindtarget() - return pointer to TARGET, creating it if necessary.
156 TARGET
* bindtarget( OBJECT
* const target_name
)
162 targethash
= hashinit( sizeof( TARGET
), "targets" );
164 t
= (TARGET
*)hash_insert( targethash
, target_name
, &found
);
167 memset( (char *)t
, '\0', sizeof( *t
) );
168 t
->name
= object_copy( target_name
);
169 t
->boundname
= object_copy( t
->name
); /* default for T_FLAG_NOTFILE */
176 static void bind_explicitly_located_target( void * xtarget
, void * data
)
178 TARGET
* t
= (TARGET
*)xtarget
;
179 if ( !( t
->flags
& T_FLAG_NOTFILE
) )
181 /* Check if there is a setting for LOCATE. */
182 SETTINGS
* s
= t
->settings
;
183 for ( ; s
; s
= s
->next
)
185 if ( object_equal( s
->symbol
, constant_LOCATE
) && ! list_empty( s
->value
) )
187 set_explicit_binding( t
->name
, list_front( s
->value
) );
195 void bind_explicitly_located_targets()
198 hashenumerate( targethash
, bind_explicitly_located_target
, (void *)0 );
203 * touch_target() - mark a target to simulate being new.
206 void touch_target( OBJECT
* const t
)
208 bindtarget( t
)->flags
|= T_FLAG_TOUCHED
;
213 * target_scc() - returns the root of a strongly connected component that this
214 * target is a part of.
217 TARGET
* target_scc( TARGET
* t
)
220 while ( result
->scc_root
)
221 result
= result
->scc_root
;
222 while ( t
->scc_root
)
224 TARGET
* const tmp
= t
->scc_root
;
225 t
->scc_root
= result
;
233 * targetlist() - turn list of target names into a TARGET chain.
236 * chain existing TARGETS to append to
237 * targets list of target names
240 TARGETS
* targetlist( TARGETS
* chain
, LIST
* target_names
)
242 LISTITER iter
= list_begin( target_names
);
243 LISTITER
const end
= list_end( target_names
);
244 for ( ; iter
!= end
; iter
= list_next( iter
) )
245 chain
= targetentry( chain
, bindtarget( list_item( iter
) ) );
251 * targetentry() - add a TARGET to a chain of TARGETS.
254 * chain existing TARGETS to append to
255 * target new target to append
258 TARGETS
* targetentry( TARGETS
* chain
, TARGET
* target
)
260 TARGETS
* const c
= (TARGETS
*)BJAM_MALLOC( sizeof( TARGETS
) );
263 if ( !chain
) chain
= c
;
264 else chain
->tail
->next
= c
;
273 * targetchain() - append two TARGET chains.
276 * chain existing TARGETS to append to
277 * target new target to append
280 TARGETS
* targetchain( TARGETS
* chain
, TARGETS
* targets
)
282 if ( !targets
) return chain
;
283 if ( !chain
) return targets
;
285 chain
->tail
->next
= targets
;
286 chain
->tail
= targets
->tail
;
291 * action_free - decrement the ACTIONs refrence count and (maybe) free it.
294 void action_free( ACTION
* action
)
296 if ( --action
->refs
== 0 )
298 freetargets( action
->targets
);
299 freetargets( action
->sources
);
306 * actionlist() - append to an ACTION chain.
309 ACTIONS
* actionlist( ACTIONS
* chain
, ACTION
* action
)
311 ACTIONS
* const actions
= (ACTIONS
*)BJAM_MALLOC( sizeof( ACTIONS
) );
312 actions
->action
= action
;
314 if ( !chain
) chain
= actions
;
315 else chain
->tail
->next
= actions
;
316 chain
->tail
= actions
;
321 static SETTINGS
* settings_freelist
;
325 * addsettings() - add a deferred "set" command to a target.
327 * Adds a variable setting (varname=list) onto a chain of settings for a
328 * particular target. 'flag' controls the relationship between new and old
329 * values in the same way as in var_set() function (see variable.c). Returns the
330 * head of the settings chain.
333 SETTINGS
* addsettings( SETTINGS
* head
, int flag
, OBJECT
* symbol
,
338 /* Look for previous settings. */
339 for ( v
= head
; v
; v
= v
->next
)
340 if ( object_equal( v
->symbol
, symbol
) )
343 /* If not previously set, alloc a new. */
344 /* If appending, do so. */
345 /* Else free old and set new. */
348 v
= settings_freelist
;
350 settings_freelist
= v
->next
;
352 v
= (SETTINGS
*)BJAM_MALLOC( sizeof( *v
) );
354 v
->symbol
= object_copy( symbol
);
359 else if ( flag
== VAR_APPEND
)
361 v
->value
= list_append( v
->value
, value
);
363 else if ( flag
!= VAR_DEFAULT
)
365 list_free( v
->value
);
371 /* Return (new) head of list. */
377 * pushsettings() - set all target specific variables.
380 void pushsettings( struct module_t
* module
, SETTINGS
* v
)
382 for ( ; v
; v
= v
->next
)
383 v
->value
= var_swap( module
, v
->symbol
, v
->value
);
388 * popsettings() - reset target specific variables to their pre-push values.
391 void popsettings( struct module_t
* module
, SETTINGS
* v
)
393 pushsettings( module
, v
); /* just swap again */
398 * copysettings() - duplicate a settings list, returning the new copy.
401 SETTINGS
* copysettings( SETTINGS
* head
)
405 for ( v
= head
; v
; v
= v
->next
)
406 copy
= addsettings( copy
, VAR_SET
, v
->symbol
, list_copy( v
->value
) );
412 * freetargets() - delete a targets list.
415 void freetargets( TARGETS
* chain
)
419 TARGETS
* const n
= chain
->next
;
427 * freeactions() - delete an action list.
430 void freeactions( ACTIONS
* chain
)
434 ACTIONS
* const n
= chain
->next
;
435 action_free( chain
->action
);
443 * freesettings() - delete a settings list.
446 void freesettings( SETTINGS
* v
)
450 SETTINGS
* const n
= v
->next
;
451 object_free( v
->symbol
);
452 list_free( v
->value
);
453 v
->next
= settings_freelist
;
454 settings_freelist
= v
;
460 static void freetarget( void * xt
, void * data
)
462 TARGET
* const t
= (TARGET
*)xt
;
463 if ( t
->name
) object_free ( t
->name
);
464 if ( t
->boundname
) object_free ( t
->boundname
);
465 if ( t
->settings
) freesettings( t
->settings
);
466 if ( t
->depends
) freetargets ( t
->depends
);
467 if ( t
->dependants
) freetargets ( t
->dependants
);
468 if ( t
->parents
) freetargets ( t
->parents
);
469 if ( t
->actions
) freeactions ( t
->actions
);
472 freetarget( t
->includes
, (void *)0 );
473 BJAM_FREE( t
->includes
);
479 * rules_done() - free RULE and TARGET tables.
486 hashenumerate( targethash
, freetarget
, 0 );
487 hashdone( targethash
);
489 while ( settings_freelist
)
491 SETTINGS
* const n
= settings_freelist
->next
;
492 BJAM_FREE( settings_freelist
);
493 settings_freelist
= n
;
499 * actions_refer() - add a new reference to the given actions.
502 void actions_refer( rule_actions
* a
)
504 ++a
->reference_count
;
509 * actions_free() - release a reference to given actions.
512 void actions_free( rule_actions
* a
)
514 if ( --a
->reference_count
<= 0 )
516 function_free( a
->command
);
517 list_free( a
->bindlist
);
524 * set_rule_body() - set the argument list and procedure of the given rule.
527 static void set_rule_body( RULE
* rule
, FUNCTION
* procedure
)
530 function_refer( procedure
);
531 if ( rule
->procedure
)
532 function_free( rule
->procedure
);
533 rule
->procedure
= procedure
;
538 * global_name() - given a rule, return the name for a corresponding rule in the
542 static OBJECT
* global_rule_name( RULE
* r
)
544 if ( r
->module
== root_module() )
545 return object_copy( r
->name
);
548 char name
[ 4096 ] = "";
549 if ( r
->module
->name
)
551 strncat( name
, object_str( r
->module
->name
), sizeof( name
) - 1 );
552 strncat( name
, ".", sizeof( name
) - 1 );
554 strncat( name
, object_str( r
->name
), sizeof( name
) - 1 );
555 return object_new( name
);
561 * global_rule() - given a rule, produce a corresponding entry in the global
565 static RULE
* global_rule( RULE
* r
)
567 if ( r
->module
== root_module() )
571 OBJECT
* const name
= global_rule_name( r
);
572 RULE
* const result
= define_rule( r
->module
, name
, root_module() );
580 * new_rule_body() - make a new rule named rulename in the given module, with
581 * the given argument list and procedure. If exported is true, the rule is
582 * exported to the global module as modulename.rulename.
585 RULE
* new_rule_body( module_t
* m
, OBJECT
* rulename
, FUNCTION
* procedure
,
588 RULE
* const local
= define_rule( m
, rulename
, m
);
589 local
->exported
= exported
;
590 set_rule_body( local
, procedure
);
592 /* Mark the procedure with the global rule name, regardless of whether the
593 * rule is exported. That gives us something reasonably identifiable that we
594 * can use, e.g. in profiling output. Only do this once, since this could be
595 * called multiple times with the same procedure.
597 if ( !function_rulename( procedure
) )
598 function_set_rulename( procedure
, global_rule_name( local
) );
604 static void set_rule_actions( RULE
* rule
, rule_actions
* actions
)
607 actions_refer( actions
);
609 actions_free( rule
->actions
);
610 rule
->actions
= actions
;
614 static rule_actions
* actions_new( FUNCTION
* command
, LIST
* bindlist
,
617 rule_actions
* const result
= (rule_actions
*)BJAM_MALLOC( sizeof(
619 function_refer( command
);
620 result
->command
= command
;
621 result
->bindlist
= bindlist
;
622 result
->flags
= flags
;
623 result
->reference_count
= 0;
628 RULE
* new_rule_actions( module_t
* m
, OBJECT
* rulename
, FUNCTION
* command
,
629 LIST
* bindlist
, int flags
)
631 RULE
* const local
= define_rule( m
, rulename
, m
);
632 RULE
* const global
= global_rule( local
);
633 set_rule_actions( local
, actions_new( command
, bindlist
, flags
) );
634 set_rule_actions( global
, local
->actions
);
640 * Looks for a rule in the specified module, and returns it, if found. First
641 * checks if the rule is present in the module's rule table. Second, if the
642 * rule's name is in the form name1.name2 and name1 is in the list of imported
643 * modules, look in module 'name1' for rule 'name2'.
646 RULE
* lookup_rule( OBJECT
* rulename
, module_t
* m
, int local_only
)
650 module_t
* original_module
= m
;
652 if ( m
->class_module
)
655 if ( m
->rules
&& ( r
= (RULE
*)hash_find( m
->rules
, rulename
) ) )
657 else if ( !local_only
&& m
->imported_modules
)
659 /* Try splitting the name into module and rule. */
660 char * p
= strchr( object_str( rulename
), '.' ) ;
663 /* Now, r->name keeps the module name, and p + 1 keeps the rule
666 OBJECT
* rule_part
= object_new( p
+ 1 );
667 OBJECT
* module_part
;
671 string_append_range( buf
, object_str( rulename
), p
);
672 module_part
= object_new( buf
->value
);
675 if ( hash_find( m
->imported_modules
, module_part
) )
676 result
= lookup_rule( rule_part
, bindmodule( module_part
), 1 );
677 object_free( module_part
);
678 object_free( rule_part
);
684 if ( local_only
&& !result
->exported
)
686 else if ( original_module
!= m
)
688 /* Lookup started in class module. We have found a rule in class
689 * module, which is marked for execution in that module, or in some
690 * instance. Mark it for execution in the instance where we started
693 int const execute_in_class
= result
->module
== m
;
694 int const execute_in_some_instance
=
695 result
->module
->class_module
== m
;
696 if ( execute_in_class
|| execute_in_some_instance
)
697 result
->module
= original_module
;
705 RULE
* bindrule( OBJECT
* rulename
, module_t
* m
)
707 RULE
* result
= lookup_rule( rulename
, m
, 0 );
709 result
= lookup_rule( rulename
, root_module(), 0 );
710 /* We have only one caller, 'evaluate_rule', which will complain about
711 * calling an undefined rule. We could issue the error here, but we do not
712 * have the necessary information, such as frame.
715 result
= enter_rule( rulename
, m
);
720 RULE
* import_rule( RULE
* source
, module_t
* m
, OBJECT
* name
)
722 RULE
* const dest
= define_rule( source
->module
, name
, m
);
723 set_rule_body( dest
, source
->procedure
);
724 set_rule_actions( dest
, source
->actions
);
729 void rule_localize( RULE
* rule
, module_t
* m
)
732 if ( rule
->procedure
)
734 FUNCTION
* procedure
= function_unbind_variables( rule
->procedure
);
735 function_refer( procedure
);
736 function_free( rule
->procedure
);
737 rule
->procedure
= procedure
;