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 *, argument_list *, PARSE * procedure );
50 static struct hash * targethash = 0;
52 struct _located_target
57 typedef struct _located_target LOCATED_TARGET ;
59 static struct hash * located_targets = 0;
63 * target_include() - adds the 'included' TARGET to the list of targets included
64 * by the 'including' TARGET. Such targets are modeled as dependencies of the
65 * internal include node belonging to the 'including' TARGET.
68 void target_include( TARGET * including, TARGET * included )
71 if ( !including->includes )
73 including->includes = copytarget( including );
74 including->includes->original_target = including;
76 internal = including->includes;
77 internal->depends = targetentry( internal->depends, included );
82 * enter_rule() - return pointer to RULE, creating it if necessary in
86 static RULE * enter_rule( char * rulename, module_t * target_module )
93 if ( hashenter( demand_rules( target_module ), (HASHDATA * *)&r ) )
95 r->name = newstr( rulename ); /* never freed */
96 r->procedure = (PARSE *)0;
101 r->module = target_module;
103 r->python_function = 0;
111 * define_rule() - return pointer to RULE, creating it if necessary in
112 * target_module. Prepare it to accept a body or action originating in
116 static RULE * define_rule
118 module_t * src_module,
120 module_t * target_module
123 RULE * r = enter_rule( rulename, target_module );
124 if ( r->module != src_module ) /* if the rule was imported from elsewhere, clear it now */
126 set_rule_body( r, 0, 0 );
127 set_rule_actions( r, 0 );
128 r->module = src_module; /* r will be executed in the source module */
134 void rule_free( RULE * r )
138 parse_free( r->procedure );
141 args_free( r->arguments );
144 actions_free( r->actions );
150 * bindtarget() - return pointer to TARGET, creating it if necessary.
153 TARGET * bindtarget( char const * target_name )
156 TARGET * t = ⌖
159 targethash = hashinit( sizeof( TARGET ), "targets" );
161 /* Perforce added const everywhere. No time to merge that change. */
163 target_name = short_path_to_long_path( (char *)target_name );
165 t->name = (char *)target_name;
167 if ( hashenter( targethash, (HASHDATA * *)&t ) )
169 memset( (char *)t, '\0', sizeof( *t ) );
170 t->name = newstr( (char *)target_name ); /* never freed */
171 t->boundname = t->name; /* default for T_FLAG_NOTFILE */
178 static void bind_explicitly_located_target( void * xtarget, void * data )
180 TARGET * t = (TARGET *)xtarget;
181 if ( !( t->flags & T_FLAG_NOTFILE ) )
183 /* Check if there's a setting for LOCATE */
184 SETTINGS * s = t->settings;
185 for ( ; s ; s = s->next )
187 if ( strcmp( s->symbol, "LOCATE" ) == 0 )
189 pushsettings( t->settings );
190 /* We are binding a target with explicit LOCATE. So third
191 * argument is of no use: nothing will be returned through it.
193 t->boundname = search( t->name, &t->time, 0, 0 );
194 popsettings( t->settings );
202 void bind_explicitly_located_targets()
205 hashenumerate( targethash, bind_explicitly_located_target, (void *)0 );
209 /* TODO: It is probably not a good idea to use functions in other modules like
211 void call_bind_rule( char * target, char * boundname );
214 TARGET * search_for_target ( char * name, LIST * search_path )
219 LOCATED_TARGET * lta = <
226 path_parse( name, f );
231 while ( search_path )
233 f->f_root.ptr = search_path->string;
234 f->f_root.len = strlen( search_path->string );
236 string_truncate( buf, 0 );
237 path_build( f, buf, 1 );
239 lt.file_name = buf->value ;
241 if ( !located_targets )
242 located_targets = hashinit( sizeof(LOCATED_TARGET),
245 if ( hashcheck( located_targets, (HASHDATA * *)<a ) )
250 timestamp( buf->value, &time );
257 search_path = list_next( search_path );
265 string_truncate( buf, 0 );
266 path_build( f, buf, 1 );
268 timestamp( buf->value, &time );
271 result = bindtarget( name );
272 result->boundname = newstr( buf->value );
274 result->binding = time ? T_BIND_EXISTS : T_BIND_MISSING;
276 call_bind_rule( result->name, result->boundname );
285 * copytarget() - make a new target with the old target's name.
287 * Not entered into hash table -- for internal nodes.
290 TARGET * copytarget( const TARGET * ot )
292 TARGET * t = (TARGET *)BJAM_MALLOC( sizeof( *t ) );
293 memset( (char *)t, '\0', sizeof( *t ) );
294 t->name = copystr( ot->name );
295 t->boundname = t->name;
297 t->flags |= T_FLAG_NOTFILE | T_FLAG_INTERNAL;
304 * touch_target() - mark a target to simulate being new.
307 void touch_target( char * t )
309 bindtarget( t )->flags |= T_FLAG_TOUCHED;
314 * targetlist() - turn list of target names into a TARGET chain.
317 * chain existing TARGETS to append to
318 * targets list of target names
321 TARGETS * targetlist( TARGETS * chain, LIST * target_names )
323 for ( ; target_names; target_names = list_next( target_names ) )
324 chain = targetentry( chain, bindtarget( target_names->string ) );
330 * targetentry() - add a TARGET to a chain of TARGETS.
333 * chain existing TARGETS to append to
334 * target new target to append
337 TARGETS * targetentry( TARGETS * chain, TARGET * target )
339 TARGETS * c = (TARGETS *)BJAM_MALLOC( sizeof( TARGETS ) );
342 if ( !chain ) chain = c;
343 else chain->tail->next = c;
352 * targetchain() - append two TARGET chains.
355 * chain exisitng TARGETS to append to
356 * target new target to append
359 TARGETS * targetchain( TARGETS * chain, TARGETS * targets )
361 if ( !targets ) return chain;
362 if ( !chain ) return targets;
364 chain->tail->next = targets;
365 chain->tail = targets->tail;
371 * actionlist() - append to an ACTION chain.
374 ACTIONS * actionlist( ACTIONS * chain, ACTION * action )
376 ACTIONS * actions = (ACTIONS *)BJAM_MALLOC( sizeof( ACTIONS ) );
378 actions->action = action;
380 if ( !chain ) chain = actions;
381 else chain->tail->next = actions;
382 chain->tail = actions;
388 static SETTINGS * settings_freelist;
392 * addsettings() - add a deferred "set" command to a target.
394 * Adds a variable setting (varname=list) onto a chain of settings for a
395 * particular target. 'flag' controls the relationship between new and old
396 * values in the same way as in var_set() function (see variable.c). Returns
397 * the head of the settings chain.
400 SETTINGS * addsettings( SETTINGS * head, int flag, char * symbol, LIST * value )
404 /* Look for previous settings. */
405 for ( v = head; v; v = v->next )
406 if ( !strcmp( v->symbol, symbol ) )
409 /* If not previously set, alloc a new. */
410 /* If appending, do so. */
411 /* Else free old and set new. */
414 v = settings_freelist;
417 settings_freelist = v->next;
419 v = (SETTINGS *)BJAM_MALLOC( sizeof( *v ) );
421 v->symbol = newstr( symbol );
427 else if ( flag == VAR_APPEND )
429 v->value = list_append( v->value, value );
431 else if ( flag != VAR_DEFAULT )
433 list_free( v->value );
439 /* Return (new) head of list. */
445 * pushsettings() - set all target specific variables.
448 void pushsettings( SETTINGS * v )
450 for ( ; v; v = v->next )
451 v->value = var_swap( v->symbol, v->value );
456 * popsettings() - reset target specific variables to their pre-push values.
459 void popsettings( SETTINGS * v )
461 pushsettings( v ); /* just swap again */
466 * copysettings() - duplicate a settings list, returning the new copy.
469 SETTINGS * copysettings( SETTINGS * head )
473 for ( v = head; v; v = v->next )
474 copy = addsettings( copy, VAR_SET, v->symbol, list_copy( 0, v->value ) );
480 * freetargets() - delete a targets list.
483 void freetargets( TARGETS * chain )
487 TARGETS * n = chain->next;
495 * freeactions() - delete an action list.
498 void freeactions( ACTIONS * chain )
502 ACTIONS * n = chain->next;
510 * freesettings() - delete a settings list.
513 void freesettings( SETTINGS * v )
517 SETTINGS * n = v->next;
518 freestr( v->symbol );
519 list_free( v->value );
520 v->next = settings_freelist;
521 settings_freelist = v;
527 static void freetarget( void * xt, void * data )
529 TARGET * t = (TARGET *)xt;
530 if ( t->settings ) freesettings( t->settings );
531 if ( t->depends ) freetargets ( t->depends );
532 if ( t->includes ) freetarget ( t->includes, (void *)0 );
533 if ( t->actions ) freeactions ( t->actions );
538 * rules_done() - free RULE and TARGET tables.
543 hashenumerate( targethash, freetarget, 0 );
544 hashdone( targethash );
545 while ( settings_freelist )
547 SETTINGS * n = settings_freelist->next;
548 BJAM_FREE( settings_freelist );
549 settings_freelist = n;
555 * args_new() - make a new reference-counted argument list.
558 argument_list * args_new()
560 argument_list * r = (argument_list *)BJAM_MALLOC( sizeof(argument_list) );
561 r->reference_count = 0;
568 * args_refer() - add a new reference to the given argument list.
571 void args_refer( argument_list * a )
573 ++a->reference_count;
578 * args_free() - release a reference to the given argument list.
581 void args_free( argument_list * a )
583 if ( --a->reference_count <= 0 )
592 * actions_refer() - add a new reference to the given actions.
595 void actions_refer( rule_actions * a )
597 ++a->reference_count;
602 * actions_free() - release a reference to the given actions.
605 void actions_free( rule_actions * a )
607 if ( --a->reference_count <= 0 )
609 freestr( a->command );
610 list_free( a->bindlist );
617 * set_rule_body() - set the argument list and procedure of the given rule.
620 static void set_rule_body( RULE * rule, argument_list * args, PARSE * procedure )
624 if ( rule->arguments )
625 args_free( rule->arguments );
626 rule->arguments = args;
629 parse_refer( procedure );
630 if ( rule->procedure )
631 parse_free( rule->procedure );
632 rule->procedure = procedure;
637 * global_name() - given a rule, return the name for a corresponding rule in the
641 static char * global_rule_name( RULE * r )
643 if ( r->module == root_module() )
647 char name[4096] = "";
648 strncat( name, r->module->name, sizeof( name ) - 1 );
649 strncat( name, r->name, sizeof( name ) - 1 );
650 return newstr( name);
656 * global_rule() - given a rule, produce the corresponding entry in the global
660 static RULE * global_rule( RULE * r )
662 if ( r->module == root_module() )
666 char * name = global_rule_name( r );
667 RULE * result = define_rule( r->module, name, root_module() );
675 * new_rule_body() - make a new rule named rulename in the given module, with
676 * the given argument list and procedure. If exported is true, the rule is
677 * exported to the global module as modulename.rulename.
680 RULE * new_rule_body( module_t * m, char * rulename, argument_list * args, PARSE * procedure, int exported )
682 RULE * local = define_rule( m, rulename, m );
683 local->exported = exported;
684 set_rule_body( local, args, procedure );
686 /* Mark the procedure with the global rule name, regardless of whether the
687 * rule is exported. That gives us something reasonably identifiable that we
688 * can use, e.g. in profiling output. Only do this once, since this could be
689 * called multiple times with the same procedure.
691 if ( procedure->rulename == 0 )
692 procedure->rulename = global_rule_name( local );
698 static void set_rule_actions( RULE * rule, rule_actions * actions )
701 actions_refer( actions );
703 actions_free( rule->actions );
704 rule->actions = actions;
708 static rule_actions * actions_new( char * command, LIST * bindlist, int flags )
710 rule_actions * result = (rule_actions *)BJAM_MALLOC( sizeof( rule_actions ) );
711 result->command = copystr( command );
712 result->bindlist = bindlist;
713 result->flags = flags;
714 result->reference_count = 0;
719 RULE * new_rule_actions( module_t * m, char * rulename, char * command, LIST * bindlist, int flags )
721 RULE * local = define_rule( m, rulename, m );
722 RULE * global = global_rule( local );
723 set_rule_actions( local, actions_new( command, bindlist, flags ) );
724 set_rule_actions( global, local->actions );
730 * Looks for a rule in the specified module, and returns it, if found. First
731 * checks if the rule is present in the module's rule table. Second, if name of
732 * the rule is in the form name1.name2 and name1 is in the list of imported
733 * modules, look in module 'name1' for rule 'name2'.
736 RULE * lookup_rule( char * rulename, module_t * m, int local_only )
741 module_t * original_module = m;
745 if ( m->class_module )
748 if ( m->rules && hashcheck( m->rules, (HASHDATA * *)&r ) )
750 else if ( !local_only && m->imported_modules )
752 /* Try splitting the name into module and rule. */
753 char *p = strchr( r->name, '.' ) ;
757 /* Now, r->name keeps the module name, and p+1 keeps the rule name.
759 if ( hashcheck( m->imported_modules, (HASHDATA * *)&r ) )
760 result = lookup_rule( p + 1, bindmodule( rulename ), 1 );
767 if ( local_only && !result->exported )
771 /* Lookup started in class module. We have found a rule in class
772 * module, which is marked for execution in that module, or in some
773 * instances. Mark it for execution in the instance where we started
776 int execute_in_class = ( result->module == m );
777 int execute_in_some_instance = ( result->module->class_module &&
778 ( result->module->class_module == m ) );
779 if ( ( original_module != m ) &&
780 ( execute_in_class || execute_in_some_instance ) )
781 result->module = original_module;
789 RULE * bindrule( char * rulename, module_t * m )
791 RULE * result = lookup_rule( rulename, m, 0 );
793 result = lookup_rule( rulename, root_module(), 0 );
794 /* We have only one caller, 'evaluate_rule', which will complain about
795 * calling an undefined rule. We could issue the error here, but we do not
796 * have the necessary information, such as frame.
799 result = enter_rule( rulename, m );
804 RULE * import_rule( RULE * source, module_t * m, char * name )
806 RULE * dest = define_rule( source->module, name, m );
807 set_rule_body( dest, source->arguments, source->procedure );
808 set_rule_actions( dest, source->actions );