Imported Upstream version 1.57.0
[platform/upstream/boost.git] / tools / build / src / engine / rules.c
1 /*
2  * Copyright 1993, 1995 Christopher Seiwald.
3  *
4  * This file is part of Jam - see jam.c for Copyright information.
5  */
6
7 /*  This file is ALSO:
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)
11  */
12
13 /*
14  * rules.c - access to RULEs, TARGETs, and ACTIONs
15  *
16  * External routines:
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.
28  */
29
30 #include "jam.h"
31 #include "rules.h"
32
33 #include "hash.h"
34 #include "lists.h"
35 #include "object.h"
36 #include "parse.h"
37 #include "pathsys.h"
38 #include "search.h"
39 #include "variable.h"
40
41
42 static void set_rule_actions( RULE *, rule_actions * );
43 static void set_rule_body   ( RULE *, FUNCTION * );
44
45 static struct hash * targethash = 0;
46
47
48 /*
49  * get_target_includes() - lazy creates a target's internal includes node
50  *
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.
55  */
56
57 static TARGET * get_target_includes( TARGET * const t )
58 {
59     if ( !t->includes )
60     {
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;
67         t->includes = i;
68     }
69     return t->includes;
70 }
71
72
73 /*
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
76  *
77  * Included targets are modeled as dependencies of the including target's
78  * internal include node.
79  */
80
81 void target_include( TARGET * const including, TARGET * const included )
82 {
83     TARGET * const internal = get_target_includes( including );
84     internal->depends = targetentry( internal->depends, included );
85 }
86
87 void target_include_many( TARGET * const including, LIST * const included_names
88     )
89 {
90     TARGET * const internal = get_target_includes( including );
91     internal->depends = targetlist( internal->depends, included_names );
92 }
93
94
95 /*
96  * enter_rule() - return pointer to RULE, creating it if necessary in
97  * target_module.
98  */
99
100 static RULE * enter_rule( OBJECT * rulename, module_t * target_module )
101 {
102     int found;
103     RULE * const r = (RULE *)hash_insert( demand_rules( target_module ),
104         rulename, &found );
105     if ( !found )
106     {
107         r->name = object_copy( rulename );
108         r->procedure = 0;
109         r->module = 0;
110         r->actions = 0;
111         r->exported = 0;
112         r->module = target_module;
113     }
114     return r;
115 }
116
117
118 /*
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
121  * src_module.
122  */
123
124 static RULE * define_rule( module_t * src_module, OBJECT * rulename,
125     module_t * target_module )
126 {
127     RULE * const r = enter_rule( rulename, target_module );
128     if ( r->module != src_module )
129     {
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;
135     }
136     return r;
137 }
138
139
140 void rule_free( RULE * r )
141 {
142     object_free( r->name );
143     r->name = 0;
144     if ( r->procedure )
145         function_free( r->procedure );
146     r->procedure = 0;
147     if ( r->actions )
148         actions_free( r->actions );
149     r->actions = 0;
150 }
151
152
153 /*
154  * bindtarget() - return pointer to TARGET, creating it if necessary.
155  */
156
157 TARGET * bindtarget( OBJECT * const target_name )
158 {
159     int found;
160     TARGET * t;
161
162     if ( !targethash )
163         targethash = hashinit( sizeof( TARGET ), "targets" );
164
165     t = (TARGET *)hash_insert( targethash, target_name, &found );
166     if ( !found )
167     {
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 */
171     }
172
173     return t;
174 }
175
176
177 static void bind_explicitly_located_target( void * xtarget, void * data )
178 {
179     TARGET * t = (TARGET *)xtarget;
180     if ( !( t->flags & T_FLAG_NOTFILE ) )
181     {
182         /* Check if there is a setting for LOCATE. */
183         SETTINGS * s = t->settings;
184         for ( ; s ; s = s->next )
185         {
186             if ( object_equal( s->symbol, constant_LOCATE ) && ! list_empty( s->value ) )
187             {
188                 set_explicit_binding( t->name, list_front( s->value ) );
189                 break;
190             }
191         }
192     }
193 }
194
195
196 void bind_explicitly_located_targets()
197 {
198     if ( targethash )
199         hashenumerate( targethash, bind_explicitly_located_target, (void *)0 );
200 }
201
202
203 /*
204  * touch_target() - mark a target to simulate being new.
205  */
206
207 void touch_target( OBJECT * const t )
208 {
209     bindtarget( t )->flags |= T_FLAG_TOUCHED;
210 }
211
212
213 /*
214  * target_scc() - returns the root of a strongly connected component that this
215  * target is a part of.
216  */
217
218 TARGET * target_scc( TARGET * t )
219 {
220     TARGET * result = t;
221     while ( result->scc_root )
222         result = result->scc_root;
223     while ( t->scc_root )
224     {
225         TARGET * const tmp = t->scc_root;
226         t->scc_root = result;
227         t = tmp;
228     }
229     return result;
230 }
231
232
233 /*
234  * targetlist() - turn list of target names into a TARGET chain.
235  *
236  * Inputs:
237  *  chain    existing TARGETS to append to
238  *  targets  list of target names
239  */
240
241 TARGETS * targetlist( TARGETS * chain, LIST * target_names )
242 {
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 ) ) );
247     return chain;
248 }
249
250
251 /*
252  * targetentry() - add a TARGET to a chain of TARGETS.
253  *
254  * Inputs:
255  *  chain   existing TARGETS to append to
256  *  target  new target to append
257  */
258
259 TARGETS * targetentry( TARGETS * chain, TARGET * target )
260 {
261     TARGETS * const c = (TARGETS *)BJAM_MALLOC( sizeof( TARGETS ) );
262     c->target = target;
263
264     if ( !chain ) chain = c;
265     else chain->tail->next = c;
266     chain->tail = c;
267     c->next = 0;
268
269     return chain;
270 }
271
272
273 /*
274  * targetchain() - append two TARGET chains.
275  *
276  * Inputs:
277  *  chain   existing TARGETS to append to
278  *  target  new target to append
279  */
280
281 TARGETS * targetchain( TARGETS * chain, TARGETS * targets )
282 {
283     if ( !targets ) return chain;
284     if ( !chain ) return targets;
285
286     chain->tail->next = targets;
287     chain->tail = targets->tail;
288     return chain;
289 }
290
291 /*
292  * action_free - decrement the ACTIONs refrence count and (maybe) free it.
293  */
294
295 void action_free( ACTION * action )
296 {
297     if ( --action->refs == 0 )
298     {
299         freetargets( action->targets );
300         freetargets( action->sources );
301         BJAM_FREE( action );
302     }
303 }
304
305
306 /*
307  * actionlist() - append to an ACTION chain.
308  */
309
310 ACTIONS * actionlist( ACTIONS * chain, ACTION * action )
311 {
312     ACTIONS * const actions = (ACTIONS *)BJAM_MALLOC( sizeof( ACTIONS ) );
313     actions->action = action;
314     ++action->refs;
315     if ( !chain ) chain = actions;
316     else chain->tail->next = actions;
317     chain->tail = actions;
318     actions->next = 0;
319     return chain;
320 }
321
322 static SETTINGS * settings_freelist;
323
324
325 /*
326  * addsettings() - add a deferred "set" command to a target.
327  *
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.
332  */
333
334 SETTINGS * addsettings( SETTINGS * head, int flag, OBJECT * symbol,
335     LIST * value )
336 {
337     SETTINGS * v;
338
339     /* Look for previous settings. */
340     for ( v = head; v; v = v->next )
341         if ( object_equal( v->symbol, symbol ) )
342             break;
343
344     /* If not previously set, alloc a new. */
345     /* If appending, do so. */
346     /* Else free old and set new. */
347     if ( !v )
348     {
349         v = settings_freelist;
350         if ( v )
351             settings_freelist = v->next;
352         else
353             v = (SETTINGS *)BJAM_MALLOC( sizeof( *v ) );
354
355         v->symbol = object_copy( symbol );
356         v->value = value;
357         v->next = head;
358         head = v;
359     }
360     else if ( flag == VAR_APPEND )
361     {
362         v->value = list_append( v->value, value );
363     }
364     else if ( flag != VAR_DEFAULT )
365     {
366         list_free( v->value );
367         v->value = value;
368     }
369     else
370         list_free( value );
371
372     /* Return (new) head of list. */
373     return head;
374 }
375
376
377 /*
378  * pushsettings() - set all target specific variables.
379  */
380
381 void pushsettings( struct module_t * module, SETTINGS * v )
382 {
383     for ( ; v; v = v->next )
384         v->value = var_swap( module, v->symbol, v->value );
385 }
386
387
388 /*
389  * popsettings() - reset target specific variables to their pre-push values.
390  */
391
392 void popsettings( struct module_t * module, SETTINGS * v )
393 {
394     pushsettings( module, v );  /* just swap again */
395 }
396
397
398 /*
399  * copysettings() - duplicate a settings list, returning the new copy.
400  */
401
402 SETTINGS * copysettings( SETTINGS * head )
403 {
404     SETTINGS * copy = 0;
405     SETTINGS * v;
406     for ( v = head; v; v = v->next )
407         copy = addsettings( copy, VAR_SET, v->symbol, list_copy( v->value ) );
408     return copy;
409 }
410
411
412 /*
413  * freetargets() - delete a targets list.
414  */
415
416 void freetargets( TARGETS * chain )
417 {
418     while ( chain )
419     {
420         TARGETS * const n = chain->next;
421         BJAM_FREE( chain );
422         chain = n;
423     }
424 }
425
426
427 /*
428  * freeactions() - delete an action list.
429  */
430
431 void freeactions( ACTIONS * chain )
432 {
433     while ( chain )
434     {
435         ACTIONS * const n = chain->next;
436         action_free( chain->action );
437         BJAM_FREE( chain );
438         chain = n;
439     }
440 }
441
442
443 /*
444  * freesettings() - delete a settings list.
445  */
446
447 void freesettings( SETTINGS * v )
448 {
449     while ( v )
450     {
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;
456         v = n;
457     }
458 }
459
460
461 static void freetarget( void * xt, void * data )
462 {
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    );
471     if ( t->includes   )
472     {
473         freetarget( t->includes, (void *)0 );
474         BJAM_FREE( t->includes );
475     }
476 }
477
478
479 /*
480  * rules_done() - free RULE and TARGET tables.
481  */
482
483 void rules_done()
484 {
485     if ( targethash )
486     {
487         hashenumerate( targethash, freetarget, 0 );
488         hashdone( targethash );
489     }
490     while ( settings_freelist )
491     {
492         SETTINGS * const n = settings_freelist->next;
493         BJAM_FREE( settings_freelist );
494         settings_freelist = n;
495     }
496 }
497
498
499 /*
500  * actions_refer() - add a new reference to the given actions.
501  */
502
503 void actions_refer( rule_actions * a )
504 {
505     ++a->reference_count;
506 }
507
508
509 /*
510  * actions_free() - release a reference to given actions.
511  */
512
513 void actions_free( rule_actions * a )
514 {
515     if ( --a->reference_count <= 0 )
516     {
517         function_free( a->command );
518         list_free( a->bindlist );
519         BJAM_FREE( a );
520     }
521 }
522
523
524 /*
525  * set_rule_body() - set the argument list and procedure of the given rule.
526  */
527
528 static void set_rule_body( RULE * rule, FUNCTION * procedure )
529 {
530     if ( procedure )
531         function_refer( procedure );
532     if ( rule->procedure )
533         function_free( rule->procedure );
534     rule->procedure = procedure;
535 }
536
537
538 /*
539  * global_name() - given a rule, return the name for a corresponding rule in the
540  * global module.
541  */
542
543 static OBJECT * global_rule_name( RULE * r )
544 {
545     if ( r->module == root_module() )
546         return object_copy( r->name );
547
548     {
549         char name[ 4096 ] = "";
550         if ( r->module->name )
551         {
552             strncat( name, object_str( r->module->name ), sizeof( name ) - 1 );
553             strncat( name, ".", sizeof( name ) - 1 );
554         }
555         strncat( name, object_str( r->name ), sizeof( name ) - 1 );
556         return object_new( name );
557     }
558 }
559
560
561 /*
562  * global_rule() - given a rule, produce a corresponding entry in the global
563  * module.
564  */
565
566 static RULE * global_rule( RULE * r )
567 {
568     if ( r->module == root_module() )
569         return r;
570
571     {
572         OBJECT * const name = global_rule_name( r );
573         RULE * const result = define_rule( r->module, name, root_module() );
574         object_free( name );
575         return result;
576     }
577 }
578
579
580 /*
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.
584  */
585
586 RULE * new_rule_body( module_t * m, OBJECT * rulename, FUNCTION * procedure,
587     int exported )
588 {
589     RULE * const local = define_rule( m, rulename, m );
590     local->exported = exported;
591     set_rule_body( local, procedure );
592
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.
597      */
598     if ( !function_rulename( procedure ) )
599         function_set_rulename( procedure, global_rule_name( local ) );
600
601     return local;
602 }
603
604
605 static void set_rule_actions( RULE * rule, rule_actions * actions )
606 {
607     if ( actions )
608         actions_refer( actions );
609     if ( rule->actions )
610         actions_free( rule->actions );
611     rule->actions = actions;
612 }
613
614
615 static rule_actions * actions_new( FUNCTION * command, LIST * bindlist,
616     int flags )
617 {
618     rule_actions * const result = (rule_actions *)BJAM_MALLOC( sizeof(
619         rule_actions ) );
620     function_refer( command );
621     result->command = command;
622     result->bindlist = bindlist;
623     result->flags = flags;
624     result->reference_count = 0;
625     return result;
626 }
627
628
629 RULE * new_rule_actions( module_t * m, OBJECT * rulename, FUNCTION * command,
630     LIST * bindlist, int flags )
631 {
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 );
636     return local;
637 }
638
639
640 /*
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'.
645  */
646
647 RULE * lookup_rule( OBJECT * rulename, module_t * m, int local_only )
648 {
649     RULE     * r;
650     RULE     * result = 0;
651     module_t * original_module = m;
652
653     if ( m->class_module )
654         m = m->class_module;
655
656     if ( m->rules && ( r = (RULE *)hash_find( m->rules, rulename ) ) )
657         result = r;
658     else if ( !local_only && m->imported_modules )
659     {
660         /* Try splitting the name into module and rule. */
661         char * p = strchr( object_str( rulename ), '.' ) ;
662         if ( p )
663         {
664             /* Now, r->name keeps the module name, and p + 1 keeps the rule
665              * name.
666              */
667             OBJECT * rule_part = object_new( p + 1 );
668             OBJECT * module_part;
669             {
670                 string buf[ 1 ];
671                 string_new( buf );
672                 string_append_range( buf, object_str( rulename ), p );
673                 module_part = object_new( buf->value );
674                 string_free( buf );
675             }
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 );
680         }
681     }
682
683     if ( result )
684     {
685         if ( local_only && !result->exported )
686             result = 0;
687         else if ( original_module != m )
688         {
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
692              * the lookup.
693              */
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;
699         }
700     }
701
702     return result;
703 }
704
705
706 RULE * bindrule( OBJECT * rulename, module_t * m )
707 {
708     RULE * result = lookup_rule( rulename, m, 0 );
709     if ( !result )
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.
714      */
715     if ( !result )
716         result = enter_rule( rulename, m );
717     return result;
718 }
719
720
721 RULE * import_rule( RULE * source, module_t * m, OBJECT * name )
722 {
723     RULE * const dest = define_rule( source->module, name, m );
724     set_rule_body( dest, source->procedure );
725     set_rule_actions( dest, source->actions );
726     return dest;
727 }
728
729
730 void rule_localize( RULE * rule, module_t * m )
731 {
732     rule->module = m;
733     if ( rule->procedure )
734     {
735         FUNCTION * procedure = function_unbind_variables( rule->procedure );
736         function_refer( procedure );
737         function_free( rule->procedure );
738         rule->procedure = procedure;
739     }
740 }