]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/tools/build/src/engine/compile.cpp
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / boost / tools / build / src / engine / compile.cpp
CommitLineData
7c673cae
FG
1/*
2 * Copyright 1993, 2000 Christopher Seiwald.
3 *
4 * This file is part of Jam - see jam.c for Copyright information.
5 */
6
7/* This file is ALSO:
1e59de90 8 * Copyright 2022 René Ferdinand Rivera Morell
7c673cae
FG
9 * Copyright 2001-2004 David Abrahams.
10 * Distributed under the Boost Software License, Version 1.0.
1e59de90 11 * (See accompanying file LICENSE.txt or https://www.bfgroup.xyz/b2/LICENSE.txt)
7c673cae
FG
12 */
13
14/*
15 * compile.c - compile parsed jam statements
16 *
17 * External routines:
18 * evaluate_rule() - execute a rule invocation
19 *
20 * Internal routines:
21 * debug_compile() - printf with indent to show rule expansion
22 */
23
24#include "jam.h"
25#include "compile.h"
26
27#include "builtins.h"
28#include "class.h"
29#include "constants.h"
30#include "hash.h"
31#include "hdrmacro.h"
32#include "make.h"
33#include "modules.h"
34#include "parse.h"
35#include "rules.h"
36#include "search.h"
f67539c2 37#include "jam_strings.h"
7c673cae
FG
38#include "variable.h"
39#include "output.h"
40
41#include <assert.h>
42#include <stdarg.h>
43#include <string.h>
44
45
46static void debug_compile( int which, char const * s, FRAME * );
47
48/* Internal functions from builtins.c */
49void backtrace( FRAME * );
50void backtrace_line( FRAME * );
51void print_source_line( FRAME * );
52void unknown_rule( FRAME *, char const * key, module_t *, OBJECT * rule_name );
53
54
55/*
56 * evaluate_rule() - execute a rule invocation
57 */
58
59LIST * evaluate_rule( RULE * rule, OBJECT * rulename, FRAME * frame )
60{
61 LIST * result = L0;
62 profile_frame prof[ 1 ];
63 module_t * prev_module = frame->module;
64
65 if ( DEBUG_COMPILE )
66 {
67 /* Try hard to indicate in which module the rule is going to execute. */
68 char buf[ 256 ] = "";
69 if ( rule->module->name )
70 {
71 strncat( buf, object_str( rule->module->name ), sizeof( buf ) -
72 1 );
73 strncat( buf, ".", sizeof( buf ) - 1 );
74 if ( strncmp( buf, object_str( rule->name ), strlen( buf ) ) == 0 )
75 {
76 buf[ 0 ] = 0;
77 }
78 }
79 strncat( buf, object_str( rule->name ), sizeof( buf ) - 1 );
80 debug_compile( 1, buf, frame );
81
82 lol_print( frame->args );
83 out_printf( "\n" );
84 }
85
86 if ( rule->procedure && rule->module != prev_module )
87 {
88 /* Propagate current module to nested rule invocations. */
89 frame->module = rule->module;
90 }
91
92 /* Record current rule name in frame. */
93 if ( rule->procedure )
94 {
95 frame->rulename = object_str( rulename );
96 /* And enter record profile info. */
97 if ( DEBUG_PROFILE )
98 profile_enter( function_rulename( rule->procedure ), prof );
99 }
100
101 /* Check traditional targets $(<) and sources $(>). */
102 if ( !rule->actions && !rule->procedure )
11fdf7f2 103 unknown_rule( frame, NULL, frame->module, rulename );
7c673cae
FG
104
105 /* If this rule will be executed for updating the targets then construct the
106 * action for make().
107 */
108 if ( rule->actions )
109 {
1e59de90 110 targets_ptr t;
7c673cae
FG
111
112 /* The action is associated with this instance of this rule. */
1e59de90 113 ACTION * const action = b2::jam::make_ptr<ACTION>();
7c673cae
FG
114
115 action->rule = rule;
1e59de90
TL
116 action->targets.reset(); targetlist( action->targets, lol_get( frame->args, 0 ) );
117 action->sources.reset(); targetlist( action->sources, lol_get( frame->args, 1 ) );
7c673cae
FG
118 action->refs = 1;
119
120 /* If we have a group of targets all being built using the same action
121 * and any of these targets is updated, then we have to consider them
122 * all to be out-dated. We do this by adding a REBUILDS in both directions
123 * between the first target and all the other targets.
124 */
125 if ( action->targets )
126 {
127 TARGET * const t0 = action->targets->target;
1e59de90 128 for ( t = action->targets->next.get(); t; t = t->next.get() )
7c673cae 129 {
1e59de90
TL
130 targetentry( t->target->rebuilds, t0 );
131 targetentry( t0->rebuilds, t->target );
7c673cae
FG
132 }
133 }
134
135 /* Append this action to the actions of each target. */
1e59de90 136 for ( t = action->targets.get(); t; t = t->next.get() )
7c673cae
FG
137 t->target->actions = actionlist( t->target->actions, action );
138
139 action_free( action );
140 }
141
142 /* Now recursively compile any parse tree associated with this rule.
143 * function_refer()/function_free() call pair added to ensure the rule does
144 * not get freed while in use.
145 */
146 if ( rule->procedure )
147 {
1e59de90
TL
148 auto function = b2::jam::make_unique_bare_jptr( rule->procedure, function_refer, function_free );
149 result = function_run( function.get(), frame, stack_global() );
7c673cae
FG
150 }
151
152 if ( DEBUG_PROFILE && rule->procedure )
153 profile_exit( prof );
154
155 if ( DEBUG_COMPILE )
156 debug_compile( -1, 0, frame );
157
158 return result;
159}
160
161
162/*
163 * Call the given rule with the specified parameters. The parameters should be
164 * of type LIST* and end with a NULL pointer. This differs from 'evaluate_rule'
165 * in that frame for the called rule is prepared inside 'call_rule'.
166 *
167 * This function is useful when a builtin rule (in C) wants to call another rule
168 * which might be implemented in Jam.
169 */
170
171LIST * call_rule( OBJECT * rulename, FRAME * caller_frame, ... )
172{
173 va_list va;
174 LIST * result;
175
176 FRAME inner[ 1 ];
177 frame_init( inner );
178 inner->prev = caller_frame;
179 inner->prev_user = caller_frame->module->user_module
180 ? caller_frame
181 : caller_frame->prev_user;
182 inner->module = caller_frame->module;
183
184 va_start( va, caller_frame );
185 for ( ; ; )
186 {
187 LIST * const l = va_arg( va, LIST * );
188 if ( !l )
189 break;
190 lol_add( inner->args, l );
191 }
192 va_end( va );
193
194 result = evaluate_rule( bindrule( rulename, inner->module ), rulename, inner );
195
196 frame_free( inner );
197
198 return result;
199}
200
201
202/*
203 * debug_compile() - printf with indent to show rule expansion
204 */
205
206static void debug_compile( int which, char const * s, FRAME * frame )
207{
208 static int level = 0;
209 static char indent[ 36 ] = ">>>>|>>>>|>>>>|>>>>|>>>>|>>>>|>>>>|";
210
211 if ( which >= 0 )
212 {
213 int i;
214
215 print_source_line( frame );
216
217 i = ( level + 1 ) * 2;
218 while ( i > 35 )
219 {
220 out_puts( indent );
221 i -= 35;
222 }
223
224 out_printf( "%*.*s ", i, i, indent );
225 }
226
227 if ( s )
228 out_printf( "%s ", s );
229
230 level += which;
231}