2 * Copyright 1993, 1995 Christopher Seiwald.
4 * This file is part of Jam - see jam.c for Copyright information.
10 # include "variable.h"
18 # include "timestamp.h"
21 * Copyright 2001-2004 David Abrahams.
22 * Distributed under the Boost Software License, Version 1.0.
23 * (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
27 * rules.c - access to RULEs, TARGETs, and ACTIONs
31 * bindrule() - return pointer to RULE, creating it if necessary.
32 * bindtarget() - return pointer to TARGET, creating it if necessary.
33 * touch_target() - mark a target to simulate being new.
34 * targetlist() - turn list of target names into a TARGET chain.
35 * targetentry() - add a TARGET to a chain of TARGETS.
36 * actionlist() - append to an ACTION chain.
37 * addsettings() - add a deferred "set" command to a target.
38 * pushsettings() - set all target specific variables.
39 * popsettings() - reset target specific variables to their pre-push values.
40 * freesettings() - delete a settings list.
41 * rules_done() - free RULE and TARGET tables.
43 * 04/12/94 (seiwald) - actionlist() now just appends a single action.
44 * 08/23/94 (seiwald) - Support for '+=' (append to variable)
47 static void set_rule_actions( RULE *, rule_actions * );
48 static void set_rule_body ( RULE *, FUNCTION * procedure );
50 static struct hash * targethash = 0;
54 * target_include() - adds the 'included' TARGET to the list of targets included
55 * by the 'including' TARGET. Such targets are modeled as dependencies of the
56 * internal include node belonging to the 'including' TARGET.
59 void target_include( TARGET * including, TARGET * included )
62 if ( !including->includes )
64 including->includes = copytarget( including );
65 including->includes->original_target = including;
67 internal = including->includes;
68 internal->depends = targetentry( internal->depends, included );
73 * enter_rule() - return pointer to RULE, creating it if necessary in
77 static RULE * enter_rule( OBJECT * rulename, module_t * target_module )
82 r = (RULE *)hash_insert( demand_rules(target_module), rulename, &found );
85 r->name = object_copy( rulename );
90 r->module = target_module;
97 * define_rule() - return pointer to RULE, creating it if necessary in
98 * target_module. Prepare it to accept a body or action originating in
102 static RULE * define_rule
104 module_t * src_module,
106 module_t * target_module
109 RULE * r = enter_rule( rulename, target_module );
110 if ( r->module != src_module ) /* if the rule was imported from elsewhere, clear it now */
112 set_rule_body( r, 0 );
113 set_rule_actions( r, 0 );
114 r->module = src_module; /* r will be executed in the source module */
120 void rule_free( RULE * r )
122 object_free( r->name );
125 function_free( r->procedure );
128 actions_free( r->actions );
134 * bindtarget() - return pointer to TARGET, creating it if necessary.
137 TARGET * bindtarget( OBJECT * target_name )
143 targethash = hashinit( sizeof( TARGET ), "targets" );
145 t = (TARGET *)hash_insert( targethash, target_name, &found );
148 memset( (char *)t, '\0', sizeof( *t ) );
149 t->name = object_copy( target_name );
150 t->boundname = object_copy( t->name ); /* default for T_FLAG_NOTFILE */
157 static void bind_explicitly_located_target( void * xtarget, void * data )
159 TARGET * t = (TARGET *)xtarget;
160 if ( !( t->flags & T_FLAG_NOTFILE ) )
162 /* Check if there's a setting for LOCATE */
163 SETTINGS * s = t->settings;
164 for ( ; s ; s = s->next )
166 if ( strcmp( object_str( s->symbol ), "LOCATE" ) == 0 )
168 pushsettings( root_module(), t->settings );
169 /* We are binding a target with explicit LOCATE. So third
170 * argument is of no use: nothing will be returned through it.
172 object_free( t->boundname );
173 t->boundname = search( t->name, &t->time, 0, 0 );
174 popsettings( root_module(), t->settings );
182 void bind_explicitly_located_targets()
185 hashenumerate( targethash, bind_explicitly_located_target, (void *)0 );
190 * copytarget() - make a new target with the old target's name.
192 * Not entered into hash table -- for internal nodes.
195 TARGET * copytarget( const TARGET * ot )
197 TARGET * t = (TARGET *)BJAM_MALLOC( sizeof( *t ) );
198 memset( (char *)t, '\0', sizeof( *t ) );
199 t->name = object_copy( ot->name );
200 t->boundname = object_copy( t->name );
202 t->flags |= T_FLAG_NOTFILE | T_FLAG_INTERNAL;
209 * touch_target() - mark a target to simulate being new.
212 void touch_target( OBJECT * t )
214 bindtarget( t )->flags |= T_FLAG_TOUCHED;
219 * targetlist() - turn list of target names into a TARGET chain.
222 * chain existing TARGETS to append to
223 * targets list of target names
226 TARGETS * targetlist( TARGETS * chain, LIST * target_names )
228 LISTITER iter = list_begin( target_names ), end = list_end( target_names );
229 for ( ; iter != end; iter = list_next( iter ) )
230 chain = targetentry( chain, bindtarget( list_item( iter ) ) );
236 * targetentry() - add a TARGET to a chain of TARGETS.
239 * chain existing TARGETS to append to
240 * target new target to append
243 TARGETS * targetentry( TARGETS * chain, TARGET * target )
245 TARGETS * c = (TARGETS *)BJAM_MALLOC( sizeof( TARGETS ) );
248 if ( !chain ) chain = c;
249 else chain->tail->next = c;
258 * targetchain() - append two TARGET chains.
261 * chain exisitng TARGETS to append to
262 * target new target to append
265 TARGETS * targetchain( TARGETS * chain, TARGETS * targets )
267 if ( !targets ) return chain;
268 if ( !chain ) return targets;
270 chain->tail->next = targets;
271 chain->tail = targets->tail;
277 * action_free - decrement the ACTIONs refrence count
278 * and (maybe) free it.
281 void action_free ( ACTION * action )
283 if ( --action->refs == 0 )
285 freetargets( action->targets );
286 freetargets( action->sources );
292 * actionlist() - append to an ACTION chain.
295 ACTIONS * actionlist( ACTIONS * chain, ACTION * action )
297 ACTIONS * actions = (ACTIONS *)BJAM_MALLOC( sizeof( ACTIONS ) );
299 actions->action = action;
302 if ( !chain ) chain = actions;
303 else chain->tail->next = actions;
304 chain->tail = actions;
310 static SETTINGS * settings_freelist;
314 * addsettings() - add a deferred "set" command to a target.
316 * Adds a variable setting (varname=list) onto a chain of settings for a
317 * particular target. 'flag' controls the relationship between new and old
318 * values in the same way as in var_set() function (see variable.c). Returns
319 * the head of the settings chain.
322 SETTINGS * addsettings( SETTINGS * head, int flag, OBJECT * symbol, LIST * value )
326 /* Look for previous settings. */
327 for ( v = head; v; v = v->next )
328 if ( object_equal( v->symbol, symbol ) )
331 /* If not previously set, alloc a new. */
332 /* If appending, do so. */
333 /* Else free old and set new. */
336 v = settings_freelist;
339 settings_freelist = v->next;
341 v = (SETTINGS *)BJAM_MALLOC( sizeof( *v ) );
343 v->symbol = object_copy( symbol );
348 else if ( flag == VAR_APPEND )
350 v->value = list_append( v->value, value );
352 else if ( flag != VAR_DEFAULT )
354 list_free( v->value );
360 /* Return (new) head of list. */
366 * pushsettings() - set all target specific variables.
369 void pushsettings( struct module_t * module, SETTINGS * v )
371 for ( ; v; v = v->next )
372 v->value = var_swap( module, v->symbol, v->value );
377 * popsettings() - reset target specific variables to their pre-push values.
380 void popsettings( struct module_t * module, SETTINGS * v )
382 pushsettings( module, v ); /* just swap again */
387 * copysettings() - duplicate a settings list, returning the new copy.
390 SETTINGS * copysettings( SETTINGS * head )
394 for ( v = head; v; v = v->next )
395 copy = addsettings( copy, VAR_SET, v->symbol, list_copy( v->value ) );
401 * freetargets() - delete a targets list.
404 void freetargets( TARGETS * chain )
408 TARGETS * n = chain->next;
416 * freeactions() - delete an action list.
419 void freeactions( ACTIONS * chain )
423 ACTIONS * n = chain->next;
424 action_free( chain->action );
432 * freesettings() - delete a settings list.
435 void freesettings( SETTINGS * v )
439 SETTINGS * n = v->next;
440 object_free( v->symbol );
441 list_free( v->value );
442 v->next = settings_freelist;
443 settings_freelist = v;
449 static void freetarget( void * xt, void * data )
451 TARGET * t = (TARGET *)xt;
452 if ( t->name ) object_free ( t->name );
453 if ( t->boundname ) object_free ( t->boundname );
454 if ( t->settings ) freesettings( t->settings );
455 if ( t->depends ) freetargets ( t->depends );
456 if ( t->dependants ) freetargets ( t->dependants );
457 if ( t->parents ) freetargets ( t->parents );
458 if ( t->actions ) freeactions ( t->actions );
462 freetarget( t->includes, (void *)0 );
463 BJAM_FREE( t->includes );
469 * rules_done() - free RULE and TARGET tables.
476 hashenumerate( targethash, freetarget, 0 );
477 hashdone( targethash );
479 while ( settings_freelist )
481 SETTINGS * n = settings_freelist->next;
482 BJAM_FREE( settings_freelist );
483 settings_freelist = n;
489 * actions_refer() - add a new reference to the given actions.
492 void actions_refer( rule_actions * a )
494 ++a->reference_count;
499 * actions_free() - release a reference to the given actions.
502 void actions_free( rule_actions * a )
504 if ( --a->reference_count <= 0 )
506 function_free( a->command );
507 list_free( a->bindlist );
513 * set_rule_body() - set the argument list and procedure of the given rule.
516 static void set_rule_body( RULE * rule, FUNCTION * procedure )
519 function_refer( procedure );
520 if ( rule->procedure )
521 function_free( rule->procedure );
522 rule->procedure = procedure;
527 * global_name() - given a rule, return the name for a corresponding rule in the
531 static OBJECT * global_rule_name( RULE * r )
533 if ( r->module == root_module() )
534 return object_copy( r->name );
537 char name[4096] = "";
538 if ( r->module->name )
540 strncat( name, object_str( r->module->name ), sizeof( name ) - 1 );
541 strncat( name, ".", sizeof( name ) - 1 );
543 strncat( name, object_str( r->name ), sizeof( name ) - 1 );
544 return object_new( name );
550 * global_rule() - given a rule, produce the corresponding entry in the global
554 static RULE * global_rule( RULE * r )
556 if ( r->module == root_module() )
560 OBJECT * name = global_rule_name( r );
561 RULE * result = define_rule( r->module, name, root_module() );
569 * new_rule_body() - make a new rule named rulename in the given module, with
570 * the given argument list and procedure. If exported is true, the rule is
571 * exported to the global module as modulename.rulename.
574 RULE * new_rule_body( module_t * m, OBJECT * rulename, FUNCTION * procedure, int exported )
576 RULE * local = define_rule( m, rulename, m );
577 local->exported = exported;
578 set_rule_body( local, procedure );
580 /* Mark the procedure with the global rule name, regardless of whether the
581 * rule is exported. That gives us something reasonably identifiable that we
582 * can use, e.g. in profiling output. Only do this once, since this could be
583 * called multiple times with the same procedure.
585 if ( function_rulename( procedure ) == 0 )
586 function_set_rulename( procedure, global_rule_name( local ) );
592 static void set_rule_actions( RULE * rule, rule_actions * actions )
595 actions_refer( actions );
597 actions_free( rule->actions );
598 rule->actions = actions;
602 static rule_actions * actions_new( FUNCTION * command, LIST * bindlist, int flags )
604 rule_actions * result = (rule_actions *)BJAM_MALLOC( sizeof( rule_actions ) );
605 function_refer( command );
606 result->command = command;
607 result->bindlist = bindlist;
608 result->flags = flags;
609 result->reference_count = 0;
614 RULE * new_rule_actions( module_t * m, OBJECT * rulename, FUNCTION * command, LIST * bindlist, int flags )
616 RULE * local = define_rule( m, rulename, m );
617 RULE * global = global_rule( local );
618 set_rule_actions( local, actions_new( command, bindlist, flags ) );
619 set_rule_actions( global, local->actions );
625 * Looks for a rule in the specified module, and returns it, if found. First
626 * checks if the rule is present in the module's rule table. Second, if name of
627 * the rule is in the form name1.name2 and name1 is in the list of imported
628 * modules, look in module 'name1' for rule 'name2'.
631 RULE * lookup_rule( OBJECT * rulename, module_t * m, int local_only )
635 module_t * original_module = m;
637 if ( m->class_module )
640 if ( m->rules && ( r = (RULE *)hash_find( m->rules, rulename ) ) )
642 else if ( !local_only && m->imported_modules )
644 /* Try splitting the name into module and rule. */
645 char *p = strchr( object_str( rulename ), '.' ) ;
649 OBJECT * module_part;
652 string_append_range( buf, object_str( rulename ), p );
653 module_part = object_new( buf->value );
654 rule_part = object_new( p + 1 );
655 /* Now, r->name keeps the module name, and p+1 keeps the rule name.
657 if ( hash_find( m->imported_modules, module_part ) )
658 result = lookup_rule( rule_part, bindmodule( module_part ), 1 );
659 object_free( rule_part );
660 object_free( module_part );
667 if ( local_only && !result->exported )
671 /* Lookup started in class module. We have found a rule in class
672 * module, which is marked for execution in that module, or in some
673 * instances. Mark it for execution in the instance where we started
676 int execute_in_class = ( result->module == m );
677 int execute_in_some_instance = ( result->module->class_module &&
678 ( result->module->class_module == m ) );
679 if ( ( original_module != m ) &&
680 ( execute_in_class || execute_in_some_instance ) )
681 result->module = original_module;
689 RULE * bindrule( OBJECT * rulename, module_t * m )
691 RULE * result = lookup_rule( rulename, m, 0 );
693 result = lookup_rule( rulename, root_module(), 0 );
694 /* We have only one caller, 'evaluate_rule', which will complain about
695 * calling an undefined rule. We could issue the error here, but we do not
696 * have the necessary information, such as frame.
699 result = enter_rule( rulename, m );
704 RULE * import_rule( RULE * source, module_t * m, OBJECT * name )
706 RULE * dest = define_rule( source->module, name, m );
707 set_rule_body( dest, source->procedure );
708 set_rule_actions( dest, source->actions );
713 void rule_localize( RULE * rule, module_t * m )
716 if ( rule->procedure )
718 FUNCTION * procedure = function_unbind_variables( rule->procedure );
719 function_refer( procedure );
720 function_free( rule->procedure );
721 rule->procedure = procedure;