0 | 0 |
#ifdef CONFIG_WITH_COMPILER
|
1 | |
/* $Id: kmk_cc_exec.c 2777 2015-02-03 21:06:31Z bird $ */
|
|
1 |
/* $Id: kmk_cc_exec.c 2788 2015-09-06 15:43:10Z bird $ */
|
2 | 2 |
/** @file
|
3 | 3 |
* kmk_cc - Make "Compiler".
|
4 | 4 |
*/
|
|
24 | 24 |
*/
|
25 | 25 |
|
26 | 26 |
|
27 | |
/*******************************************************************************
|
28 | |
* Header Files *
|
29 | |
*******************************************************************************/
|
|
27 |
/*********************************************************************************************************************************
|
|
28 |
* Header Files *
|
|
29 |
*********************************************************************************************************************************/
|
30 | 30 |
#include "make.h"
|
31 | 31 |
|
32 | 32 |
#include "dep.h"
|
|
41 | 41 |
#include <stdarg.h>
|
42 | 42 |
#include <assert.h>
|
43 | 43 |
|
44 | |
/*******************************************************************************
|
45 | |
* Defined Constants And Macros *
|
46 | |
*******************************************************************************/
|
|
44 |
|
|
45 |
/*********************************************************************************************************************************
|
|
46 |
* Defined Constants And Macros *
|
|
47 |
*********************************************************************************************************************************/
|
47 | 48 |
/** @def KMK_CC_WITH_STATS
|
48 | 49 |
* Enables the collection of extra statistics. */
|
49 | 50 |
#ifndef KMK_CC_WITH_STATS
|
|
73 | 74 |
KMK_CC_ASSERT( ((a_uValue) & ((a_uAlignment) - 1)) == 0 )
|
74 | 75 |
|
75 | 76 |
|
76 | |
/*******************************************************************************
|
77 | |
* Structures and Typedefs *
|
78 | |
*******************************************************************************/
|
|
77 |
/** @def KMK_CC_OFFSETOF
|
|
78 |
* Offsetof for simple stuff. */
|
|
79 |
#if defined(__GNUC__)
|
|
80 |
# define KMK_CC_OFFSETOF(a_Struct, a_Member) __builtin_offsetof(a_Struct, a_Member)
|
|
81 |
#else
|
|
82 |
# define KMK_CC_OFFSETOF(a_Struct, a_Member) ( (uintptr_t)&( ((a_Struct *)(void *)0)->a_Member) )
|
|
83 |
#endif
|
|
84 |
|
|
85 |
/** def KMK_CC_SIZEOF_MEMBER */
|
|
86 |
#define KMK_CC_SIZEOF_MEMBER(a_Struct, a_Member) ( sizeof( ((a_Struct *)(void *)0x1000)->a_Member) )
|
|
87 |
|
|
88 |
/** @def KMK_CC_SIZEOF_VAR_STRUCT
|
|
89 |
* Size of a struct with a variable sized array as the final member. */
|
|
90 |
#define KMK_CC_SIZEOF_VAR_STRUCT(a_Struct, a_FinalArrayMember, a_cArray) \
|
|
91 |
( KMK_CC_OFFSETOF(a_Struct, a_FinalArrayMember) + KMK_CC_SIZEOF_MEMBER(a_Struct, a_FinalArrayMember) * (a_cArray) )
|
|
92 |
|
|
93 |
|
|
94 |
|
|
95 |
/** @def KMK_CC_STATIC_ASSERT_EX
|
|
96 |
* Compile time assertion with text.
|
|
97 |
*/
|
|
98 |
#ifdef _MSC_VER_
|
|
99 |
# if _MSC_VER >= 1600
|
|
100 |
# define KMK_CC_STATIC_ASSERT_EX(a_Expr, a_szExpl) static_assert(a_Expr, a_szExpl)
|
|
101 |
# else
|
|
102 |
# define KMK_CC_STATIC_ASSERT_EX(a_Expr, a_szExpl) typedef int RTASSERTVAR[(a_Expr) ? 1 : 0]
|
|
103 |
# endif
|
|
104 |
#elif defined(__GNUC__) && defined(__GXX_EXPERIMENTAL_CXX0X__)
|
|
105 |
# define KMK_CC_STATIC_ASSERT_EX(a_Expr, a_szExpl) static_assert(a_Expr, a_szExpl)
|
|
106 |
#elif !defined(__GNUC__) && !defined(__IBMC__) && !defined(__IBMCPP__)
|
|
107 |
# define KMK_CC_STATIC_ASSERT_EX(a_Expr, a_szExpl) typedef int KMK_CC_STATIC_ASSERT_EX_TYPE[(a_Expr) ? 1 : 0]
|
|
108 |
#else
|
|
109 |
# define KMK_CC_STATIC_ASSERT_EX(a_Expr, a_szExpl) extern int KMK_CC_STATIC_ASSERT_EX_VAR[(aExpr) ? 1 : 0]
|
|
110 |
extern int KMK_CC_STATIC_ASSERT_EX_VAR[1];
|
|
111 |
#endif
|
|
112 |
/** @def KMK_CC_STATIC_ASSERT
|
|
113 |
* Compile time assertion, simple variant.
|
|
114 |
*/
|
|
115 |
#define KMK_CC_STATIC_ASSERT(a_Expr) KMK_CC_STATIC_ASSERT_EX(a_Expr, #a_Expr)
|
|
116 |
|
|
117 |
|
|
118 |
/*********************************************************************************************************************************
|
|
119 |
* Structures and Typedefs *
|
|
120 |
*********************************************************************************************************************************/
|
79 | 121 |
/**
|
80 | 122 |
* Block of expand instructions.
|
81 | 123 |
*
|
|
93 | 135 |
uint32_t offNext;
|
94 | 136 |
} KMKCCBLOCK;
|
95 | 137 |
typedef KMKCCBLOCK *PKMKCCBLOCK;
|
|
138 |
|
|
139 |
|
|
140 |
/** @name String Expansion
|
|
141 |
* @{*/
|
96 | 142 |
|
97 | 143 |
/**
|
98 | 144 |
* String expansion statistics.
|
|
129 | 175 |
kKmkCcExpInstr_Return,
|
130 | 176 |
/** The end of valid instructions (exclusive). */
|
131 | 177 |
kKmkCcExpInstr_End
|
132 | |
} KMKCCEXPANDINSTR;
|
|
178 |
} KMKCCEXPINSTR;
|
133 | 179 |
|
134 | 180 |
/** Instruction core. */
|
135 | 181 |
typedef struct kmk_cc_exp_core
|
136 | 182 |
{
|
137 | |
/** The instruction opcode number (KMKCCEXPANDINSTR). */
|
138 | |
KMKCCEXPANDINSTR enmOpCode;
|
|
183 |
/** The instruction opcode number (KMKCCEXPINSTR). */
|
|
184 |
KMKCCEXPINSTR enmOpCode;
|
139 | 185 |
} KMKCCEXPCORE;
|
140 | 186 |
typedef KMKCCEXPCORE *PKMKCCEXPCORE;
|
141 | 187 |
|
142 | 188 |
/**
|
143 | |
* String expansion sub program.
|
144 | |
*/
|
|
189 |
* String expansion subprogram.
|
|
190 |
*/
|
|
191 |
#pragma pack(1) /* save some precious bytes */
|
145 | 192 |
typedef struct kmk_cc_exp_subprog
|
146 | 193 |
{
|
147 | 194 |
/** Pointer to the first instruction. */
|
|
149 | 196 |
/** Statistics. */
|
150 | 197 |
KMKCCEXPSTATS Stats;
|
151 | 198 |
} KMKCCEXPSUBPROG;
|
|
199 |
#pragma pack()
|
152 | 200 |
typedef KMKCCEXPSUBPROG *PKMKCCEXPSUBPROG;
|
|
201 |
KMK_CC_STATIC_ASSERT(sizeof(KMKCCEXPSUBPROG) == 12 || sizeof(void *) != 8);
|
|
202 |
|
|
203 |
|
|
204 |
/**
|
|
205 |
* String expansion subprogram or plain string.
|
|
206 |
*/
|
|
207 |
#pragma pack(1) /* save some precious bytes */
|
|
208 |
typedef struct kmk_cc_exp_subprog_or_string
|
|
209 |
{
|
|
210 |
/** Either a plain string pointer or a subprogram. */
|
|
211 |
union
|
|
212 |
{
|
|
213 |
/** Subprogram for expanding this argument. */
|
|
214 |
KMKCCEXPSUBPROG Subprog;
|
|
215 |
/** Pointer to the plain string. */
|
|
216 |
struct
|
|
217 |
{
|
|
218 |
/** Pointer to the string. */
|
|
219 |
const char *psz;
|
|
220 |
/** String length. */
|
|
221 |
uint32_t cch;
|
|
222 |
} Plain;
|
|
223 |
} u;
|
|
224 |
/** Set if subprogram (u.Subprog), clear if plain string (u.Plain). */
|
|
225 |
uint8_t fSubprog;
|
|
226 |
/** Set if the plain string is kept in the variable_strcache.
|
|
227 |
* @remarks Here rather than in u.Plain to make use of alignment padding. */
|
|
228 |
uint8_t fPlainIsInVarStrCache;
|
|
229 |
/** Context/user specific. */
|
|
230 |
uint8_t bUser;
|
|
231 |
/** Context/user specific #2. */
|
|
232 |
uint8_t bUser2;
|
|
233 |
} KMKCCEXPSUBPROGORPLAIN;
|
|
234 |
#pragma pack()
|
|
235 |
typedef KMKCCEXPSUBPROGORPLAIN *PKMKCCEXPSUBPROGORPLAIN;
|
|
236 |
KMK_CC_STATIC_ASSERT( sizeof(void *) == 8
|
|
237 |
? sizeof(KMKCCEXPSUBPROGORPLAIN) == 16
|
|
238 |
: sizeof(void *) == 4
|
|
239 |
? sizeof(KMKCCEXPSUBPROGORPLAIN) == 12
|
|
240 |
: 1);
|
153 | 241 |
|
154 | 242 |
/**
|
155 | 243 |
* kKmkCcExpInstr_CopyString instruction format.
|
|
184 | 272 |
{
|
185 | 273 |
/** The core instruction. */
|
186 | 274 |
KMKCCEXPCORE Core;
|
|
275 |
/** The subprogram that will give us the variable name. */
|
|
276 |
KMKCCEXPSUBPROG Subprog;
|
187 | 277 |
/** Where to continue after this instruction. (This is necessary since the
|
188 | 278 |
* instructions of the subprogram are emitted after this instruction.) */
|
189 | 279 |
PKMKCCEXPCORE pNext;
|
190 | |
/** The subprogram that will give us the variable name. */
|
191 | |
KMKCCEXPSUBPROG SubProg;
|
192 | 280 |
} KMKCCEXPDYNVAR;
|
193 | 281 |
typedef KMKCCEXPDYNVAR *PKMKCCEXPDYNVAR;
|
194 | 282 |
|
|
224 | 312 |
/** The core instruction. */
|
225 | 313 |
KMKCCEXPCORE Core;
|
226 | 314 |
/** Number of arguments. */
|
227 | |
uint32_t cArgs;
|
|
315 |
uint32_t cArgs; /**< @todo uint16_t to save 7 bytes of unecessary alignment padding on 64-bit systems, or merge fDirty into this member. */
|
228 | 316 |
/** Set if the function could be modifying the input arguments. */
|
229 | 317 |
uint8_t fDirty;
|
230 | 318 |
/** Where to continue after this instruction. (This is necessary since the
|
|
250 | 338 |
typedef struct kmk_cc_exp_plain_function
|
251 | 339 |
{
|
252 | 340 |
/** The bits comment to both plain and dynamic functions. */
|
253 | |
KMKCCEXPFUNCCORE Core;
|
|
341 |
KMKCCEXPFUNCCORE FnCore;
|
254 | 342 |
/** Variable sized argument list (cArgs + 1 in length, last entry is NULL).
|
255 | 343 |
* The string pointers are to memory following this instruction, to memory in
|
256 | 344 |
* the next block or to memory in the variable / makefile we're working on
|
|
258 | 346 |
const char *apszArgs[1];
|
259 | 347 |
} KMKCCEXPPLAINFUNC;
|
260 | 348 |
typedef KMKCCEXPPLAINFUNC *PKMKCCEXPPLAINFUNC;
|
261 | |
/** Calculates the size of an KMKCCEXPPLAINFUNC with a_cArgs. */
|
262 | |
#define KMKCCEXPPLAINFUNC_SIZE(a_cArgs) (sizeof(KMKCCEXPFUNCCORE) + (a_cArgs + 1) * sizeof(const char *))
|
|
349 |
/** Calculates the size of an KMKCCEXPPLAINFUNC structure with the apszArgs
|
|
350 |
* member holding a_cArgs entries plus a NULL terminator. */
|
|
351 |
#define KMKCCEXPPLAINFUNC_SIZE(a_cArgs) KMK_CC_SIZEOF_VAR_STRUCT(KMKCCEXPDYNFUNC, aArgs, (a_cArgs) + 1)
|
263 | 352 |
|
264 | 353 |
/**
|
265 | 354 |
* Instruction format for kKmkCcExpInstr_DynamicFunction.
|
|
267 | 356 |
typedef struct kmk_cc_exp_dyn_function
|
268 | 357 |
{
|
269 | 358 |
/** The bits comment to both plain and dynamic functions. */
|
270 | |
KMKCCEXPFUNCCORE Core;
|
271 | |
/** Variable sized argument list (cArgs + 1 in length, last entry is NULL).
|
272 | |
* The string pointers are to memory following this instruction, to memory in
|
273 | |
* the next block or to memory in the variable / makefile we're working on
|
274 | |
* (if zero terminated appropriately). */
|
275 | |
struct
|
276 | |
{
|
277 | |
/** Set if plain string argument, clear if sub program. */
|
278 | |
uint8_t fPlain;
|
279 | |
union
|
280 | |
{
|
281 | |
/** Sub program for expanding this argument. */
|
282 | |
KMKCCEXPSUBPROG SubProg;
|
283 | |
struct
|
284 | |
{
|
285 | |
/** Pointer to the plain argument string.
|
286 | |
* This is allocated in the same manner as the
|
287 | |
* string pointed to by KMKCCEXPPLAINFUNC::apszArgs. */
|
288 | |
const char *pszArg;
|
289 | |
} Plain;
|
290 | |
} u;
|
291 | |
} aArgs[1];
|
|
359 |
KMKCCEXPFUNCCORE FnCore;
|
|
360 |
/** Variable sized argument list (FnCore.cArgs in length).
|
|
361 |
* The subprograms / strings are allocated after this array (or in the next
|
|
362 |
* block). */
|
|
363 |
KMKCCEXPSUBPROGORPLAIN aArgs[1];
|
292 | 364 |
} KMKCCEXPDYNFUNC;
|
293 | 365 |
typedef KMKCCEXPDYNFUNC *PKMKCCEXPDYNFUNC;
|
294 | |
/** Calculates the size of an KMKCCEXPPLAINFUNC with a_cArgs. */
|
295 | |
#define KMKCCEXPDYNFUNC_SIZE(a_cArgs) ( sizeof(KMKCCEXPFUNCCORE) \
|
296 | |
+ (a_cArgs) * sizeof(((PKMKCCEXPDYNFUNC)(uintptr_t)42)->aArgs[0]) )
|
|
366 |
/** Calculates the size of an KMKCCEXPDYNFUNC structure with the apszArgs
|
|
367 |
* member holding a_cArgs entries (no zero terminator). */
|
|
368 |
#define KMKCCEXPDYNFUNC_SIZE(a_cArgs) KMK_CC_SIZEOF_VAR_STRUCT(KMKCCEXPDYNFUNC, aArgs, a_cArgs)
|
297 | 369 |
|
298 | 370 |
/**
|
299 | 371 |
* Instruction format for kKmkCcExpInstr_Jump.
|
|
329 | 401 |
/** Pointer to a string expansion program. */
|
330 | 402 |
typedef KMKCCEXPPROG *PKMKCCEXPPROG;
|
331 | 403 |
|
332 | |
|
333 | |
/*******************************************************************************
|
334 | |
* Global Variables *
|
335 | |
*******************************************************************************/
|
|
404 |
/** @} */
|
|
405 |
|
|
406 |
|
|
407 |
/** @name Makefile Evaluation
|
|
408 |
* @{ */
|
|
409 |
|
|
410 |
/** Pointer to a makefile evaluation program. */
|
|
411 |
typedef struct kmk_cc_evalprog *PKMKCCEVALPROG;
|
|
412 |
|
|
413 |
/**
|
|
414 |
* Makefile evaluation instructions.
|
|
415 |
*/
|
|
416 |
typedef enum KMKCCEVALINSTR
|
|
417 |
{
|
|
418 |
/** Jump instruction - KMKCCEVALJUMP. */
|
|
419 |
kKmkCcEvalInstr_jump = 0,
|
|
420 |
|
|
421 |
/** [local|override|export] variable = value - KMKCCEVALASSIGN.
|
|
422 |
* @note Can be used for target-specific variables. */
|
|
423 |
kKmkCcEvalInstr_assign_recursive,
|
|
424 |
/** [local|override|export] variable := value - KMKCCEVALASSIGN.
|
|
425 |
* @note Can be used for target-specific variables. */
|
|
426 |
kKmkCcEvalInstr_assign_simple,
|
|
427 |
/** [local|override|export] variable += value - KMKCCEVALASSIGN.
|
|
428 |
* @note Can be used for target-specific variables. */
|
|
429 |
kKmkCcEvalInstr_assign_append,
|
|
430 |
/** [local|override|export] variable -= value - KMKCCEVALASSIGN.
|
|
431 |
* @note Can be used for target-specific variables. */
|
|
432 |
kKmkCcEvalInstr_assign_prepend,
|
|
433 |
/** [local|override|export] variable ?= value - KMKCCEVALASSIGN.
|
|
434 |
* @note Can be used for target-specific variables. */
|
|
435 |
kKmkCcEvalInstr_assign_if_new,
|
|
436 |
/** [local|override|export] define variable ... endef - KMKCCEVALASSIGNDEF. */
|
|
437 |
kKmkCcEvalInstr_assign_define,
|
|
438 |
|
|
439 |
/** export variable1 [variable2...] - KMKCCEVALEXPORT. */
|
|
440 |
kKmkCcEvalInstr_export,
|
|
441 |
/** unexport variable1 [variable2...] - KMKCCEVALEXPORT. */
|
|
442 |
kKmkCcEvalInstr_unexport,
|
|
443 |
/** export - KMKCCEVALCORE. */
|
|
444 |
kKmkCcEvalInstr_export_all,
|
|
445 |
/** unexport - KMKCCEVALCORE. */
|
|
446 |
kKmkCcEvalInstr_unexport_all,
|
|
447 |
|
|
448 |
/** [else] ifdef variable - KMKCCEVALIFDEFPLAIN. */
|
|
449 |
kKmkCcEvalInstr_ifdef_plain,
|
|
450 |
/** [else] ifndef variable - KMKCCEVALIFDEFPLAIN. */
|
|
451 |
kKmkCcEvalInstr_ifndef_plain,
|
|
452 |
/** [else] ifdef variable - KMKCCEVALIFDEFDYNAMIC. */
|
|
453 |
kKmkCcEvalInstr_ifdef_dynamic,
|
|
454 |
/** [else] ifndef variable - KMKCCEVALIFDEFDYNAMIC. */
|
|
455 |
kKmkCcEvalInstr_ifndef_dynamic,
|
|
456 |
/** [else] ifeq (a,b) - KMKCCEVALIFEQ. */
|
|
457 |
kKmkCcEvalInstr_ifeq,
|
|
458 |
/** [else] ifeq (a,b) - KMKCCEVALIFEQ. */
|
|
459 |
kKmkCcEvalInstr_ifneq,
|
|
460 |
/** [else] if1of (set-a,set-b) - KMKCCEVALIF1OF. */
|
|
461 |
kKmkCcEvalInstr_if1of,
|
|
462 |
/** [else] ifn1of (set-a,set-b) - KMKCCEVALIF1OF. */
|
|
463 |
kKmkCcEvalInstr_ifn1of,
|
|
464 |
/** [else] if expr - KMKCCEVALIFEXPR. */
|
|
465 |
kKmkCcEvalInstr_if,
|
|
466 |
|
|
467 |
/** include file1 [file2...] - KMKCCEVALINCLUDE. */
|
|
468 |
kKmkCcEvalInstr_include,
|
|
469 |
/** [sinclude|-include] file1 [file2...] - KMKCCEVALINCLUDE. */
|
|
470 |
kKmkCcEvalInstr_include_silent,
|
|
471 |
/** includedep file1 [file2...] - KMKCCEVALINCLUDE. */
|
|
472 |
kKmkCcEvalInstr_includedep,
|
|
473 |
/** includedep-queue file1 [file2...] - KMKCCEVALINCLUDE. */
|
|
474 |
kKmkCcEvalInstr_includedep_queue,
|
|
475 |
/** includedep-flush file1 [file2...] - KMKCCEVALINCLUDE. */
|
|
476 |
kKmkCcEvalInstr_includedep_flush,
|
|
477 |
|
|
478 |
/** Recipe without commands (defines dependencies) - KMKCCEVALRECIPE. */
|
|
479 |
kKmkCcEvalInstr_recipe_no_commands,
|
|
480 |
/** Recipe with commands (defines dependencies) - KMKCCEVALRECIPE. */
|
|
481 |
kKmkCcEvalInstr_recipe_start_normal,
|
|
482 |
/** Recipe with commands (defines dependencies) - KMKCCEVALRECIPE. */
|
|
483 |
kKmkCcEvalInstr_recipe_start_double_colon,
|
|
484 |
/** Recipe with commands (defines dependencies) - KMKCCEVALRECIPE. */
|
|
485 |
kKmkCcEvalInstr_recipe_start_pattern,
|
|
486 |
/** Adds more commands to the current recipe - KMKCCEVALRECIPECOMMANDS. */
|
|
487 |
kKmkCcEvalInstr_recipe_commands,
|
|
488 |
/** Adds more commands to the current recipe - KMKCCEVALRECIPECOMMANDS. */
|
|
489 |
kKmkCcEvalInstr_recipe_vari,
|
|
490 |
/** Special instruction for indicating the end of the recipe commands - KMKCCEVALCORE. */
|
|
491 |
kKmkCcEvalInstr_recipe_end,
|
|
492 |
/** Cancel previously defined pattern rule - KMKCCEVALRECIPE. */
|
|
493 |
kKmkCcEvalInstr_recipe_cancel_pattern,
|
|
494 |
|
|
495 |
/** vpath pattern directories - KMKCCEVALVPATH. */
|
|
496 |
kKmkCcEvalInstr_vpath,
|
|
497 |
/** vpath pattern directories - KMKCCEVALVPATH. */
|
|
498 |
kKmkCcEvalInstr_vpath_clear_pattern,
|
|
499 |
/** vpath - KMKCCEVALCORE. */
|
|
500 |
kKmkCcEvalInstr_vpath_clear_all,
|
|
501 |
|
|
502 |
/** The end of valid instructions (exclusive). */
|
|
503 |
kKmkCcEvalInstr_End
|
|
504 |
} KMKCCEVALINSTR;
|
|
505 |
|
|
506 |
/**
|
|
507 |
* Instruction core common to all instructions.
|
|
508 |
*/
|
|
509 |
typedef struct kmk_cc_eval_core
|
|
510 |
{
|
|
511 |
/** The instruction opcode number (KMKCCEVALINSTR). */
|
|
512 |
KMKCCEVALINSTR enmOpCode;
|
|
513 |
/** The line number in the source this statement is associated with. */
|
|
514 |
unsigned iLine;
|
|
515 |
} KMKCCEVALCORE;
|
|
516 |
/** Pointer to an instruction core structure. */
|
|
517 |
typedef KMKCCEVALCORE *PKMKCCEVALCORE;
|
|
518 |
|
|
519 |
/**
|
|
520 |
* Instruction format for kKmkCcEvalInstr_jump.
|
|
521 |
*/
|
|
522 |
typedef struct kmk_cc_eval_jump
|
|
523 |
{
|
|
524 |
/** The core instruction. */
|
|
525 |
KMKCCEVALCORE Core;
|
|
526 |
/** Where to jump to (new instruction block or endif, typically). */
|
|
527 |
PKMKCCEVALCORE pNext;
|
|
528 |
} KMKCCEVALJUMP;
|
|
529 |
typedef KMKCCEVALJUMP *PKMKCCEVALJUMP;
|
|
530 |
|
|
531 |
/**
|
|
532 |
* Instruction format for kKmkCcEvalInstr_assign_recursive,
|
|
533 |
* kKmkCcEvalInstr_assign_simple, kKmkCcEvalInstr_assign_append,
|
|
534 |
* kKmkCcEvalInstr_assign_prepend and kKmkCcEvalInstr_assign_if_new.
|
|
535 |
*/
|
|
536 |
typedef struct kmk_cc_eval_assign
|
|
537 |
{
|
|
538 |
/** The core instruction. */
|
|
539 |
KMKCCEVALCORE Core;
|
|
540 |
/** Whether the 'export' directive was used. */
|
|
541 |
uint8_t fExport;
|
|
542 |
/** Whether the 'override' directive was used. */
|
|
543 |
uint8_t fOverride;
|
|
544 |
/** Whether the 'local' directive was used. */
|
|
545 |
uint8_t fLocal;
|
|
546 |
/** The variable name.
|
|
547 |
* @remarks Plain text names are in variable_strcache. */
|
|
548 |
KMKCCEXPSUBPROGORPLAIN Variable;
|
|
549 |
/** The value or value expression. */
|
|
550 |
KMKCCEXPSUBPROGORPLAIN Value;
|
|
551 |
/** Pointer to the next instruction. */
|
|
552 |
PKMKCCEVALCORE pNext;
|
|
553 |
} KMKCCEVALASSIGN;
|
|
554 |
typedef KMKCCEVALASSIGN *PKMKCCEVALASSIGN;
|
|
555 |
|
|
556 |
/**
|
|
557 |
* Instruction format for kKmkCcEvalInstr_assign_define.
|
|
558 |
*/
|
|
559 |
typedef struct kmk_cc_eval_assign_define
|
|
560 |
{
|
|
561 |
/** The assignment core structure. */
|
|
562 |
KMKCCEVALASSIGN AssignCore;
|
|
563 |
/** Makefile evaluation program compiled from the define.
|
|
564 |
* NULL if it does not compile.
|
|
565 |
* @todo Let's see if this is actually doable... */
|
|
566 |
PKMKCCEVALPROG pEvalProg;
|
|
567 |
} KMKCCEVALASSIGNDEF;
|
|
568 |
typedef KMKCCEVALASSIGNDEF *PKMKCCEVALASSIGNDEF;
|
|
569 |
|
|
570 |
/**
|
|
571 |
* Instruction format for kKmkCcEvalInstr_export and kKmkCcEvalInstr_unexport.
|
|
572 |
*/
|
|
573 |
typedef struct kmk_cc_eval_export
|
|
574 |
{
|
|
575 |
/** The core instruction. */
|
|
576 |
KMKCCEVALCORE Core;
|
|
577 |
/** The number of variables named in aVars. */
|
|
578 |
uint32_t cVars;
|
|
579 |
/** Pointer to the next instruction. */
|
|
580 |
PKMKCCEVALCORE pNext;
|
|
581 |
/** The variable names.
|
|
582 |
* Expressions will be expanded and split on space.
|
|
583 |
* @remarks Plain text names are in variable_strcache. */
|
|
584 |
KMKCCEXPSUBPROGORPLAIN aVars[1];
|
|
585 |
} KMKCCEVALEXPORT;
|
|
586 |
typedef KMKCCEVALEXPORT *PKMKCCEVALEXPORT;
|
|
587 |
/** Calculates the size of an KMKCCEVALEXPORT structure for @a a_cVars. */
|
|
588 |
#define KMKCCEVALEXPORT_SIZE(a_cVars) KMK_CC_SIZEOF_VAR_STRUCT(KMKCCEVALVPATH, aVars, a_cVars)
|
|
589 |
|
|
590 |
/**
|
|
591 |
* Core structure for all conditionals (kKmkCcEvalInstr_if*).
|
|
592 |
*/
|
|
593 |
typedef struct kmk_cc_eval_if_core
|
|
594 |
{
|
|
595 |
/** The core instruction. */
|
|
596 |
KMKCCEVALCORE Core;
|
|
597 |
/** Condition true: Pointer to the next instruction. */
|
|
598 |
PKMKCCEVALCORE pNextTrue;
|
|
599 |
/** Condition false: Pointer to the next instruction (i.e. 'else if*'
|
|
600 |
* or whatever follows 'else' / 'endif'. */
|
|
601 |
PKMKCCEVALCORE pNextFalse;
|
|
602 |
/** Pointer to the previous conditional for 'else if*' directives.
|
|
603 |
* This is to assist the compilation process. */
|
|
604 |
PKMKCCEVALCORE pPrevCond;
|
|
605 |
} KMKCCEVALIFCORE;
|
|
606 |
typedef KMKCCEVALIFCORE *PKMKCCEVALIFCORE;
|
|
607 |
|
|
608 |
/**
|
|
609 |
* Instruction format for kKmkCcEvalInstr_ifdef_plain and
|
|
610 |
* kKmkCcEvalInstr_ifndef_plain.
|
|
611 |
* The variable name is known at compilation time.
|
|
612 |
*/
|
|
613 |
typedef struct kmk_cc_eval_ifdef_plain
|
|
614 |
{
|
|
615 |
/** The 'if' core structure. */
|
|
616 |
KMKCCEVALIFCORE IfCore;
|
|
617 |
/** The name of the variable (points into variable_strcache). */
|
|
618 |
const char *pszName;
|
|
619 |
} KMKCCEVALIFDEFPLAIN;
|
|
620 |
typedef KMKCCEVALIFDEFPLAIN *PKMKCCEVALIFDEFPLAIN;
|
|
621 |
|
|
622 |
/**
|
|
623 |
* Instruction format for kKmkCcEvalInstr_ifdef_dynamic and
|
|
624 |
* kKmkCcEvalInstr_ifndef_dynamic.
|
|
625 |
* The variable name is dynamically expanded at run time.
|
|
626 |
*/
|
|
627 |
typedef struct kmk_cc_eval_ifdef_dynamic
|
|
628 |
{
|
|
629 |
/** The 'if' core structure. */
|
|
630 |
KMKCCEVALIFCORE IfCore;
|
|
631 |
/** The subprogram that will give us the variable name. */
|
|
632 |
KMKCCEXPSUBPROG NameSubProg;
|
|
633 |
} KMKCCEVALIFDEFDYNAMIC;
|
|
634 |
KMK_CC_STATIC_ASSERT(sizeof(KMKCCEVALIFDEFDYNAMIC) == 48 || sizeof(void *) != 8);
|
|
635 |
typedef KMKCCEVALIFDEFDYNAMIC *PKMKCCEVALIFDEFDYNAMIC;
|
|
636 |
|
|
637 |
/**
|
|
638 |
* Instruction format for kKmkCcEvalInstr_ifeq and kKmkCcEvalInstr_ifneq.
|
|
639 |
*/
|
|
640 |
typedef struct kmk_cc_eval_ifeq
|
|
641 |
{
|
|
642 |
/** The 'if' core structure. */
|
|
643 |
KMKCCEVALIFCORE IfCore;
|
|
644 |
/** The left hand side string expression (dynamic or plain). */
|
|
645 |
KMKCCEXPSUBPROGORPLAIN Left;
|
|
646 |
/** The rigth hand side string expression (dynamic or plain). */
|
|
647 |
KMKCCEXPSUBPROGORPLAIN Right;
|
|
648 |
} KMKCCEVALIFEQ;
|
|
649 |
typedef KMKCCEVALIFEQ *PKMKCCEVALIFEQ;
|
|
650 |
|
|
651 |
/**
|
|
652 |
* Instruction format for kKmkCcEvalInstr_if1of and kKmkCcEvalInstr_ifn1of.
|
|
653 |
*
|
|
654 |
* @todo This can be optimized further by pre-hashing plain text items. One of
|
|
655 |
* the sides are usually plain text.
|
|
656 |
*/
|
|
657 |
typedef struct kmk_cc_eval_if1of
|
|
658 |
{
|
|
659 |
/** The 'if' core structure. */
|
|
660 |
KMKCCEVALIFCORE IfCore;
|
|
661 |
/** The left hand side string expression (dynamic or plain). */
|
|
662 |
KMKCCEXPSUBPROGORPLAIN Left;
|
|
663 |
/** The rigth hand side string expression (dynamic or plain). */
|
|
664 |
KMKCCEXPSUBPROGORPLAIN Right;
|
|
665 |
} KMKCCEVALIF1OF;
|
|
666 |
typedef KMKCCEVALIF1OF *PKMKCCEVALIF1OF;
|
|
667 |
|
|
668 |
/**
|
|
669 |
* Instruction format for kKmkCcEvalInstr_if.
|
|
670 |
*
|
|
671 |
* @todo Parse and compile the expression. At least strip whitespace in it.
|
|
672 |
*/
|
|
673 |
typedef struct kmk_cc_eval_if_expr
|
|
674 |
{
|
|
675 |
/** The 'if' core structure. */
|
|
676 |
KMKCCEVALIFCORE IfCore;
|
|
677 |
/** The expression string length. */
|
|
678 |
uint16_t cchExpr;
|
|
679 |
/** The expression string. */
|
|
680 |
char szExpr[1];
|
|
681 |
} KMKCCEVALIFEXPR;
|
|
682 |
typedef KMKCCEVALIFEXPR *PKMKCCEVALIFEXPR;
|
|
683 |
/** Calculates the size of an KMKCCEVALIFEXPR structure for @a a_cchExpr long
|
|
684 |
* expression string (terminator is automatically added). */
|
|
685 |
#define KMKCCEVALIFEXPR_SIZE(a_cchExpr) KMK_CC_SIZEOF_VAR_STRUCT(KMKCCEVALIFEXPR, szExpr, (a_cchExpr) + 1)
|
|
686 |
|
|
687 |
/**
|
|
688 |
* Instruction format for kKmkCcEvalInstr_include,
|
|
689 |
* kKmkCcEvalInstr_include_silent, kKmkCcEvalInstr_includedep,
|
|
690 |
* kKmkCcEvalInstr_includedep_queue, kKmkCcEvalInstr_includedep_flush.
|
|
691 |
*/
|
|
692 |
typedef struct kmk_cc_eval_include
|
|
693 |
{
|
|
694 |
/** The core instruction. */
|
|
695 |
KMKCCEVALCORE Core;
|
|
696 |
/** The number of files. */
|
|
697 |
uint32_t cFiles;
|
|
698 |
/** Pointer to the next instruction (subprogs and strings after this one). */
|
|
699 |
PKMKCCEVALCORE pNext;
|
|
700 |
/** The files to be included.
|
|
701 |
* Expressions will be expanded and split on space.
|
|
702 |
* @todo Plain text file name could be replaced by file string cache entries. */
|
|
703 |
KMKCCEXPSUBPROGORPLAIN aFiles[1];
|
|
704 |
} KMKCCEVALINCLUDE;
|
|
705 |
typedef KMKCCEVALINCLUDE *PKMKCCEVALINCLUDE;
|
|
706 |
/** Calculates the size of an KMKCCEVALINCLUDE structure for @a a_cFiles files. */
|
|
707 |
#define KMKCCEVALINCLUDE_SIZE(a_cFiles) KMK_CC_SIZEOF_VAR_STRUCT(KMKCCEVALINCLUDE, aFiles, a_cFiles)
|
|
708 |
|
|
709 |
/**
|
|
710 |
* Instruction format for kKmkCcEvalInstr_recipe_no_commands,
|
|
711 |
* kKmkCcEvalInstr_recipe_start_normal,
|
|
712 |
* kKmkCcEvalInstr_recipe_start_double_colon, kKmkCcEvalInstr_includedep_queue,
|
|
713 |
* kKmkCcEvalInstr_recipe_start_pattern.
|
|
714 |
*/
|
|
715 |
typedef struct kmk_cc_eval_recipe
|
|
716 |
{
|
|
717 |
/** The core instruction. */
|
|
718 |
KMKCCEVALCORE Core;
|
|
719 |
/** The total number of files and dependencies in aFilesAndDeps. */
|
|
720 |
uint16_t cFilesAndDeps;
|
|
721 |
|
|
722 |
/** Number of targets (from index 0).
|
|
723 |
* This is always 1 if this is an explicit multitarget or pattern recipe,
|
|
724 |
* indicating the main target. */
|
|
725 |
uint16_t cTargets;
|
|
726 |
/** Explicit multitarget & patterns: First always made target. */
|
|
727 |
uint16_t iFirstAlwaysMadeTargets;
|
|
728 |
/** Explicit multitarget & patterns: Number of always targets. */
|
|
729 |
uint16_t cAlwaysMadeTargets;
|
|
730 |
/** Explicit multitarget: First maybe made target. */
|
|
731 |
uint16_t iFirstMaybeTarget;
|
|
732 |
/** Explicit multitarget: Number of maybe made targets. */
|
|
733 |
uint16_t cMaybeTargets;
|
|
734 |
|
|
735 |
/** First dependency. */
|
|
736 |
uint16_t iFirstDep;
|
|
737 |
/** Number of ordinary dependnecies. */
|
|
738 |
uint16_t cDeps;
|
|
739 |
/** First order only dependency. */
|
|
740 |
uint16_t iFirstOrderOnlyDep;
|
|
741 |
/** Number of ordinary dependnecies. */
|
|
742 |
uint16_t cOrderOnlyDeps;
|
|
743 |
|
|
744 |
/** Pointer to the next instruction (subprogs and strings after this one). */
|
|
745 |
PKMKCCEVALCORE pNext;
|
|
746 |
/** The .MUST_MAKE variable value, if present.
|
|
747 |
* If not present, this is a zero length plain string. */
|
|
748 |
KMKCCEXPSUBPROGORPLAIN MustMake;
|
|
749 |
/** The target files and dependencies.
|
|
750 |
* This is sorted into several sections, as defined by the above indexes and
|
|
751 |
* counts. Expressions will be expanded and split on space.
|
|
752 |
*
|
|
753 |
* The KMKCCEXPSUBPROGORPLAIN::bUser member is used to indicate secondary
|
|
754 |
* expansion for a plain text entry.
|
|
755 |
*
|
|
756 |
* @todo Plain text file name could be replaced by file string cache entries. */
|
|
757 |
KMKCCEXPSUBPROGORPLAIN aFilesAndDeps[1];
|
|
758 |
} KMKCCEVALRECIPE;
|
|
759 |
typedef KMKCCEVALRECIPE *PKMKCCEVALRECIPE;
|
|
760 |
/** Calculates the size of an KMKCCEVALRECIPE structure for @a a_cFiles
|
|
761 |
* files. */
|
|
762 |
#define KMKCCEVALRECIPE_SIZE(a_cFilesAndDeps) KMK_CC_SIZEOF_VAR_STRUCT(KMKCCEVALRECIPE, aFilesAndDeps, a_cFilesAndDeps)
|
|
763 |
|
|
764 |
/**
|
|
765 |
* Instruction format for kKmkCcEvalInstr_recipe_commands.
|
|
766 |
*/
|
|
767 |
typedef struct kmk_cc_eval_recipe_commands
|
|
768 |
{
|
|
769 |
/** The core instruction. */
|
|
770 |
KMKCCEVALCORE Core;
|
|
771 |
/** The number of search directories. */
|
|
772 |
uint32_t cCommands;
|
|
773 |
/** Pointer to the next instruction (subprogs and strings after this one). */
|
|
774 |
PKMKCCEVALCORE pNext;
|
|
775 |
/** Commands to add to the current recipe.
|
|
776 |
* Expressions will be expanded and split on space. */
|
|
777 |
KMKCCEXPSUBPROGORPLAIN aCommands[1];
|
|
778 |
} KMKCCEVALRECIPECOMMANDS;
|
|
779 |
typedef KMKCCEVALRECIPECOMMANDS *PKMKCCEVALRECIPECOMMANDS;
|
|
780 |
/** Calculates the size of an KMKCCEVALRECIPECOMMANDS structure for
|
|
781 |
* @a a_cCommands commands. */
|
|
782 |
#define KMKCCEVALRECIPECOMMANDS_SIZE(a_cCommands) KMK_CC_SIZEOF_VAR_STRUCT(KMKCCEVALRECIPECOMMANDS, aCommands, a_cCommands)
|
|
783 |
|
|
784 |
/**
|
|
785 |
* Instruction format for kKmkCcEvalInstr_vpath and
|
|
786 |
* kKmkCcEvalInstr_vpath_clear_pattern.
|
|
787 |
*/
|
|
788 |
typedef struct kmk_cc_eval_vpath
|
|
789 |
{
|
|
790 |
/** The core instruction. */
|
|
791 |
KMKCCEVALCORE Core;
|
|
792 |
/** The number of search directories.
|
|
793 |
* This will be zero for kKmkCcEvalInstr_vpath_clear_pattern. */
|
|
794 |
uint32_t cDirs;
|
|
795 |
/** Pointer to the next instruction (subprogs and strings after this one). */
|
|
796 |
PKMKCCEVALCORE pNext;
|
|
797 |
/** The pattern. */
|
|
798 |
KMKCCEXPSUBPROGORPLAIN Pattern;
|
|
799 |
/** The directory. Expressions will be expanded and split on space. */
|
|
800 |
KMKCCEXPSUBPROGORPLAIN aDirs[1];
|
|
801 |
} KMKCCEVALVPATH;
|
|
802 |
typedef KMKCCEVALVPATH *PKMKCCEVALVPATH;
|
|
803 |
/** Calculates the size of an KMKCCEVALVPATH structure for @a a_cFiles files. */
|
|
804 |
#define KMKCCEVALVPATH_SIZE(a_cFiles) KMK_CC_SIZEOF_VAR_STRUCT(KMKCCEVALVPATH, aDirs, a_cDirs)
|
|
805 |
|
|
806 |
|
|
807 |
/**
|
|
808 |
* Makefile evaluation program.
|
|
809 |
*/
|
|
810 |
typedef struct kmk_cc_evalprog
|
|
811 |
{
|
|
812 |
/** Pointer to the first instruction for this program. */
|
|
813 |
PKMKCCEVALCORE pFirstInstr;
|
|
814 |
/** List of blocks for this program (LIFO). */
|
|
815 |
PKMKCCBLOCK pBlockTail;
|
|
816 |
|
|
817 |
} KMKCCEVALPROG;
|
|
818 |
|
|
819 |
/** @} */
|
|
820 |
|
|
821 |
|
|
822 |
/*********************************************************************************************************************************
|
|
823 |
* Global Variables *
|
|
824 |
*********************************************************************************************************************************/
|
336 | 825 |
static uint32_t g_cVarForExpandCompilations = 0;
|
337 | 826 |
static uint32_t g_cVarForExpandExecs = 0;
|
338 | 827 |
#ifdef KMK_CC_WITH_STATS
|
|
347 | 836 |
#endif
|
348 | 837 |
|
349 | 838 |
|
350 | |
/*******************************************************************************
|
351 | |
* Internal Functions *
|
352 | |
*******************************************************************************/
|
|
839 |
/*********************************************************************************************************************************
|
|
840 |
* Internal Functions *
|
|
841 |
*********************************************************************************************************************************/
|
353 | 842 |
static int kmk_cc_exp_compile_subprog(PKMKCCBLOCK *ppBlockTail, const char *pchStr, uint32_t cchStr, PKMKCCEXPSUBPROG pSubProg);
|
354 | 843 |
static char *kmk_exec_expand_subprog_to_tmp(PKMKCCEXPSUBPROG pSubProg, uint32_t *pcch);
|
355 | 844 |
|
|
371 | 860 |
|
372 | 861 |
printf(_("# Variables compiled for string expansion: %6u\n"), g_cVarForExpandCompilations);
|
373 | 862 |
printf(_("# Variables string expansion runs: %6u\n"), g_cVarForExpandExecs);
|
374 | |
printf(_("# String expansion runs per compile: %6u\n"), g_cVarForExpandExecs / g_cVarForExpandExecs);
|
|
863 |
printf(_("# String expansion runs per compile: %6u\n"), g_cVarForExpandExecs / g_cVarForExpandCompilations);
|
375 | 864 |
#ifdef KMK_CC_WITH_STATS
|
376 | 865 |
printf(_("# Single alloc block exp progs: %6u (%u%%)\n"
|
377 | 866 |
"# Two alloc block exp progs: %6u (%u%%)\n"
|
|
733 | 1222 |
}
|
734 | 1223 |
}
|
735 | 1224 |
|
736 | |
|
737 | |
/*
|
|
1225 |
/*
|
738 | 1226 |
*
|
739 | 1227 |
* The string expansion compiler.
|
740 | 1228 |
* The string expansion compiler.
|
|
824 | 1312 |
*/
|
825 | 1313 |
uint32_t cActualArgs = cArgs <= cMaxArgs || !cMaxArgs ? cArgs : cMaxArgs;
|
826 | 1314 |
PKMKCCEXPDYNFUNC pInstr = (PKMKCCEXPDYNFUNC)kmk_cc_block_alloc_exp(ppBlockTail, KMKCCEXPDYNFUNC_SIZE(cActualArgs));
|
827 | |
pInstr->Core.Core.enmOpCode = kKmkCcExpInstr_DynamicFunction;
|
828 | |
pInstr->Core.cArgs = cActualArgs;
|
829 | |
pInstr->Core.pfnFunction = pfnFunction;
|
830 | |
pInstr->Core.pszFuncName = pszFunction;
|
831 | |
pInstr->Core.fDirty = kmk_cc_is_dirty_function(pszFunction);
|
|
1315 |
pInstr->FnCore.Core.enmOpCode = kKmkCcExpInstr_DynamicFunction;
|
|
1316 |
pInstr->FnCore.cArgs = cActualArgs;
|
|
1317 |
pInstr->FnCore.pfnFunction = pfnFunction;
|
|
1318 |
pInstr->FnCore.pszFuncName = pszFunction;
|
|
1319 |
pInstr->FnCore.fDirty = kmk_cc_is_dirty_function(pszFunction);
|
832 | 1320 |
|
833 | 1321 |
/*
|
834 | 1322 |
* Parse the arguments. Plain arguments gets duplicated in the program
|
|
863 | 1351 |
cchThisArg++;
|
864 | 1352 |
}
|
865 | 1353 |
|
866 | |
pInstr->aArgs[iArg].fPlain = !fDollar;
|
|
1354 |
pInstr->aArgs[iArg].fSubprog = fDollar;
|
867 | 1355 |
if (fDollar)
|
868 | 1356 |
{
|
869 | 1357 |
/* Compile it. */
|
870 | 1358 |
int rc;
|
871 | 1359 |
kmk_cc_block_realign(ppBlockTail);
|
872 | |
rc = kmk_cc_exp_compile_subprog(ppBlockTail, pchArgs, cchThisArg, &pInstr->aArgs[iArg].u.SubProg);
|
|
1360 |
rc = kmk_cc_exp_compile_subprog(ppBlockTail, pchArgs, cchThisArg, &pInstr->aArgs[iArg].u.Subprog);
|
873 | 1361 |
if (rc != 0)
|
874 | 1362 |
return rc;
|
875 | 1363 |
}
|
876 | 1364 |
else
|
877 | 1365 |
{
|
878 | 1366 |
/* Duplicate it. */
|
879 | |
pInstr->aArgs[iArg].u.Plain.pszArg = kmk_cc_block_strdup(ppBlockTail, pchArgs, cchThisArg);
|
|
1367 |
pInstr->aArgs[iArg].u.Plain.psz = kmk_cc_block_strdup(ppBlockTail, pchArgs, cchThisArg);
|
|
1368 |
pInstr->aArgs[iArg].u.Plain.cch = cchThisArg;
|
880 | 1369 |
}
|
881 | 1370 |
iArg++;
|
882 | 1371 |
if (ch != ',')
|
|
890 | 1379 |
* Realign the allocator and take down the address of the next instruction.
|
891 | 1380 |
*/
|
892 | 1381 |
kmk_cc_block_realign(ppBlockTail);
|
893 | |
pInstr->Core.pNext = (PKMKCCEXPCORE)kmk_cc_block_get_next_ptr(*ppBlockTail);
|
|
1382 |
pInstr->FnCore.pNext = (PKMKCCEXPCORE)kmk_cc_block_get_next_ptr(*ppBlockTail);
|
894 | 1383 |
return 0;
|
895 | 1384 |
}
|
896 | 1385 |
|
|
924 | 1413 |
*/
|
925 | 1414 |
uint32_t cActualArgs = cArgs <= cMaxArgs || !cMaxArgs ? cArgs : cMaxArgs;
|
926 | 1415 |
PKMKCCEXPPLAINFUNC pInstr = (PKMKCCEXPPLAINFUNC)kmk_cc_block_alloc_exp(ppBlockTail, KMKCCEXPPLAINFUNC_SIZE(cActualArgs));
|
927 | |
pInstr->Core.Core.enmOpCode = kKmkCcExpInstr_PlainFunction;
|
928 | |
pInstr->Core.cArgs = cActualArgs;
|
929 | |
pInstr->Core.pfnFunction = pfnFunction;
|
930 | |
pInstr->Core.pszFuncName = pszFunction;
|
931 | |
pInstr->Core.fDirty = kmk_cc_is_dirty_function(pszFunction);
|
|
1416 |
pInstr->FnCore.Core.enmOpCode = kKmkCcExpInstr_PlainFunction;
|
|
1417 |
pInstr->FnCore.cArgs = cActualArgs;
|
|
1418 |
pInstr->FnCore.pfnFunction = pfnFunction;
|
|
1419 |
pInstr->FnCore.pszFuncName = pszFunction;
|
|
1420 |
pInstr->FnCore.fDirty = kmk_cc_is_dirty_function(pszFunction);
|
932 | 1421 |
|
933 | 1422 |
/*
|
934 | 1423 |
* Parse the arguments. Plain arguments gets duplicated in the program
|
|
974 | 1463 |
* Realign the allocator and take down the address of the next instruction.
|
975 | 1464 |
*/
|
976 | 1465 |
kmk_cc_block_realign(ppBlockTail);
|
977 | |
pInstr->Core.pNext = (PKMKCCEXPCORE)kmk_cc_block_get_next_ptr(*ppBlockTail);
|
|
1466 |
pInstr->FnCore.pNext = (PKMKCCEXPCORE)kmk_cc_block_get_next_ptr(*ppBlockTail);
|
978 | 1467 |
}
|
979 | 1468 |
|
980 | 1469 |
|
|
997 | 1486 |
pInstr = (PKMKCCEXPDYNVAR)kmk_cc_block_alloc_exp(ppBlockTail, sizeof(*pInstr));
|
998 | 1487 |
pInstr->Core.enmOpCode = kKmkCcExpInstr_DynamicVariable;
|
999 | 1488 |
|
1000 | |
rc = kmk_cc_exp_compile_subprog(ppBlockTail, pchNameExpr, cchNameExpr, &pInstr->SubProg);
|
|
1489 |
rc = kmk_cc_exp_compile_subprog(ppBlockTail, pchNameExpr, cchNameExpr, &pInstr->Subprog);
|
1001 | 1490 |
|
1002 | 1491 |
pInstr->pNext = (PKMKCCEXPCORE)kmk_cc_block_get_next_ptr(*ppBlockTail);
|
1003 | 1492 |
return rc;
|
|
1408 | 1897 |
|
1409 | 1898 |
|
1410 | 1899 |
/**
|
1411 | |
* Compiles a string expansion sub program.
|
|
1900 |
* Compiles a string expansion subprogram.
|
1412 | 1901 |
*
|
1413 | 1902 |
* The caller typically make a call to kmk_cc_block_get_next_ptr after this
|
1414 | 1903 |
* function returns to figure out where to continue executing.
|
|
1420 | 1909 |
* lifetime of the program).
|
1421 | 1910 |
* @param cchStr The length of the string to compile. Expected to
|
1422 | 1911 |
* be at least on char long.
|
1423 | |
* @param pSubProg The sub program structure to initialize.
|
|
1912 |
* @param pSubProg The subprogram structure to initialize.
|
1424 | 1913 |
*/
|
1425 | 1914 |
static int kmk_cc_exp_compile_subprog(PKMKCCBLOCK *ppBlockTail, const char *pchStr, uint32_t cchStr, PKMKCCEXPSUBPROG pSubProg)
|
1426 | 1915 |
{
|
|
1463 | 1952 |
#endif
|
1464 | 1953 |
|
1465 | 1954 |
/*
|
1466 | |
* Join forces with the sub program compilation code.
|
|
1955 |
* Join forces with the subprogram compilation code.
|
1467 | 1956 |
*/
|
1468 | 1957 |
if (kmk_cc_exp_compile_common(&pProg->pBlockTail, pchStr, cchStr) == 0)
|
1469 | 1958 |
{
|
|
1491 | 1980 |
|
1492 | 1981 |
|
1493 | 1982 |
/**
|
1494 | |
* Compiles a variable direct evaluation as is, setting v->evalprog on success.
|
1495 | |
*
|
1496 | |
* @returns Pointer to the program on success, NULL if no program was created.
|
1497 | |
* @param pVar Pointer to the variable.
|
1498 | |
*/
|
1499 | |
struct kmk_cc_evalprog *kmk_cc_compile_variable_for_eval(struct variable *pVar)
|
1500 | |
{
|
1501 | |
return NULL;
|
1502 | |
}
|
1503 | |
|
1504 | |
|
1505 | |
/**
|
1506 | 1983 |
* Updates the recursive_without_dollar member of a variable structure.
|
1507 | 1984 |
*
|
1508 | 1985 |
* This avoid compiling string expansion programs without only a CopyString
|
|
1619 | 2096 |
PKMKCCEXPDYNVAR pInstr = (PKMKCCEXPDYNVAR)pInstrCore;
|
1620 | 2097 |
struct variable *pVar;
|
1621 | 2098 |
uint32_t cchName;
|
1622 | |
char *pszName = kmk_exec_expand_subprog_to_tmp(&pInstr->SubProg, &cchName);
|
|
2099 |
char *pszName = kmk_exec_expand_subprog_to_tmp(&pInstr->Subprog, &cchName);
|
1623 | 2100 |
char *pszColon = (char *)memchr(pszName, ':', cchName);
|
1624 | 2101 |
char *pszEqual;
|
1625 | 2102 |
if ( pszColon == NULL
|
|
1715 | 2192 |
{
|
1716 | 2193 |
PKMKCCEXPPLAINFUNC pInstr = (PKMKCCEXPPLAINFUNC)pInstrCore;
|
1717 | 2194 |
uint32_t iArg;
|
1718 | |
if (!pInstr->Core.fDirty)
|
|
2195 |
if (!pInstr->FnCore.fDirty)
|
1719 | 2196 |
{
|
1720 | 2197 |
#ifdef KMK_CC_STRICT
|
1721 | 2198 |
uint32_t uCrcBefore = 0;
|
1722 | 2199 |
uint32_t uCrcAfter = 0;
|
1723 | |
iArg = pInstr->Core.cArgs;
|
|
2200 |
iArg = pInstr->FnCore.cArgs;
|
1724 | 2201 |
while (iArg-- > 0)
|
1725 | 2202 |
uCrcBefore = kmk_cc_debug_string_hash(uCrcBefore, pInstr->apszArgs[iArg]);
|
1726 | 2203 |
#endif
|
1727 | 2204 |
|
1728 | |
pchDst = pInstr->Core.pfnFunction(pchDst, (char **)&pInstr->apszArgs[0], pInstr->Core.pszFuncName);
|
|
2205 |
pchDst = pInstr->FnCore.pfnFunction(pchDst, (char **)&pInstr->apszArgs[0], pInstr->FnCore.pszFuncName);
|
1729 | 2206 |
|
1730 | 2207 |
#ifdef KMK_CC_STRICT
|
1731 | |
iArg = pInstr->Core.cArgs;
|
|
2208 |
iArg = pInstr->FnCore.cArgs;
|
1732 | 2209 |
while (iArg-- > 0)
|
1733 | 2210 |
uCrcAfter = kmk_cc_debug_string_hash(uCrcAfter, pInstr->apszArgs[iArg]);
|
1734 | 2211 |
KMK_CC_ASSERT(uCrcBefore == uCrcAfter);
|
|
1736 | 2213 |
}
|
1737 | 2214 |
else
|
1738 | 2215 |
{
|
1739 | |
char **papszShadowArgs = xmalloc((pInstr->Core.cArgs * 2 + 1) * sizeof(papszShadowArgs[0]));
|
1740 | |
char **papszArgs = &papszShadowArgs[pInstr->Core.cArgs];
|
1741 | |
|
1742 | |
iArg = pInstr->Core.cArgs;
|
|
2216 |
char **papszShadowArgs = xmalloc((pInstr->FnCore.cArgs * 2 + 1) * sizeof(papszShadowArgs[0]));
|
|
2217 |
char **papszArgs = &papszShadowArgs[pInstr->FnCore.cArgs];
|
|
2218 |
|
|
2219 |
iArg = pInstr->FnCore.cArgs;
|
1743 | 2220 |
papszArgs[iArg] = NULL;
|
1744 | 2221 |
while (iArg-- > 0)
|
1745 | 2222 |
papszArgs[iArg] = papszShadowArgs[iArg] = xstrdup(pInstr->apszArgs[iArg]);
|
1746 | 2223 |
|
1747 | |
pchDst = pInstr->Core.pfnFunction(pchDst, (char **)&pInstr->apszArgs[0], pInstr->Core.pszFuncName);
|
1748 | |
|
1749 | |
iArg = pInstr->Core.cArgs;
|
|
2224 |
pchDst = pInstr->FnCore.pfnFunction(pchDst, (char **)&pInstr->apszArgs[0], pInstr->FnCore.pszFuncName);
|
|
2225 |
|
|
2226 |
iArg = pInstr->FnCore.cArgs;
|
1750 | 2227 |
while (iArg-- > 0)
|
1751 | 2228 |
free(papszShadowArgs[iArg]);
|
1752 | 2229 |
free(papszShadowArgs);
|
1753 | 2230 |
}
|
1754 | 2231 |
|
1755 | |
pInstrCore = pInstr->Core.pNext;
|
|
2232 |
pInstrCore = pInstr->FnCore.pNext;
|
1756 | 2233 |
break;
|
1757 | 2234 |
}
|
1758 | 2235 |
|
1759 | 2236 |
case kKmkCcExpInstr_DynamicFunction:
|
1760 | 2237 |
{
|
1761 | 2238 |
PKMKCCEXPDYNFUNC pInstr = (PKMKCCEXPDYNFUNC)pInstrCore;
|
1762 | |
char **papszArgsShadow = xmalloc( (pInstr->Core.cArgs * 2 + 1) * sizeof(char *));
|
1763 | |
char **papszArgs = &papszArgsShadow[pInstr->Core.cArgs];
|
|
2239 |
char **papszArgsShadow = xmalloc( (pInstr->FnCore.cArgs * 2 + 1) * sizeof(char *));
|
|
2240 |
char **papszArgs = &papszArgsShadow[pInstr->FnCore.cArgs];
|
1764 | 2241 |
uint32_t iArg;
|
1765 | 2242 |
|
1766 | |
if (!pInstr->Core.fDirty)
|
|
2243 |
if (!pInstr->FnCore.fDirty)
|
1767 | 2244 |
{
|
1768 | 2245 |
#ifdef KMK_CC_STRICT
|
1769 | 2246 |
uint32_t uCrcBefore = 0;
|
1770 | 2247 |
uint32_t uCrcAfter = 0;
|
1771 | 2248 |
#endif
|
1772 | |
iArg = pInstr->Core.cArgs;
|
|
2249 |
iArg = pInstr->FnCore.cArgs;
|
1773 | 2250 |
papszArgs[iArg] = NULL;
|
1774 | 2251 |
while (iArg-- > 0)
|
1775 | 2252 |
{
|
1776 | 2253 |
char *pszArg;
|
1777 | |
if (!pInstr->aArgs[iArg].fPlain)
|
1778 | |
pszArg = kmk_exec_expand_subprog_to_tmp(&pInstr->aArgs[iArg].u.SubProg, NULL);
|
|
2254 |
if (pInstr->aArgs[iArg].fSubprog)
|
|
2255 |
pszArg = kmk_exec_expand_subprog_to_tmp(&pInstr->aArgs[iArg].u.Subprog, NULL);
|
1779 | 2256 |
else
|
1780 | |
pszArg = (char *)pInstr->aArgs[iArg].u.Plain.pszArg;
|
|
2257 |
pszArg = (char *)pInstr->aArgs[iArg].u.Plain.psz;
|
1781 | 2258 |
papszArgsShadow[iArg] = pszArg;
|
1782 | 2259 |
papszArgs[iArg] = pszArg;
|
1783 | 2260 |
#ifdef KMK_CC_STRICT
|
1784 | 2261 |
uCrcBefore = kmk_cc_debug_string_hash(uCrcBefore, pszArg);
|
1785 | 2262 |
#endif
|
1786 | 2263 |
}
|
1787 | |
pchDst = pInstr->Core.pfnFunction(pchDst, papszArgs, pInstr->Core.pszFuncName);
|
1788 | |
|
1789 | |
iArg = pInstr->Core.cArgs;
|
|
2264 |
pchDst = pInstr->FnCore.pfnFunction(pchDst, papszArgs, pInstr->FnCore.pszFuncName);
|
|
2265 |
|
|
2266 |
iArg = pInstr->FnCore.cArgs;
|
1790 | 2267 |
while (iArg-- > 0)
|
1791 | 2268 |
{
|
1792 | 2269 |
#ifdef KMK_CC_STRICT
|
1793 | 2270 |
KMK_CC_ASSERT(papszArgsShadow[iArg] == papszArgs[iArg]);
|
1794 | 2271 |
uCrcAfter = kmk_cc_debug_string_hash(uCrcAfter, papszArgsShadow[iArg]);
|
1795 | 2272 |
#endif
|
1796 | |
if (!pInstr->aArgs[iArg].fPlain)
|
|
2273 |
if (pInstr->aArgs[iArg].fSubprog)
|
1797 | 2274 |
free(papszArgsShadow[iArg]);
|
1798 | 2275 |
}
|
1799 | 2276 |
KMK_CC_ASSERT(uCrcBefore == uCrcAfter);
|
1800 | 2277 |
}
|
1801 | 2278 |
else
|
1802 | 2279 |
{
|
1803 | |
iArg = pInstr->Core.cArgs;
|
|
2280 |
iArg = pInstr->FnCore.cArgs;
|
1804 | 2281 |
papszArgs[iArg] = NULL;
|
1805 | 2282 |
while (iArg-- > 0)
|
1806 | 2283 |
{
|
1807 | 2284 |
char *pszArg;
|
1808 | |
if (!pInstr->aArgs[iArg].fPlain)
|
1809 | |
pszArg = kmk_exec_expand_subprog_to_tmp(&pInstr->aArgs[iArg].u.SubProg, NULL);
|
|
2285 |
if (pInstr->aArgs[iArg].fSubprog)
|
|
2286 |
pszArg = kmk_exec_expand_subprog_to_tmp(&pInstr->aArgs[iArg].u.Subprog, NULL);
|
1810 | 2287 |
else
|
1811 | |
pszArg = xstrdup(pInstr->aArgs[iArg].u.Plain.pszArg);
|
|
2288 |
pszArg = xstrdup(pInstr->aArgs[iArg].u.Plain.psz);
|
1812 | 2289 |
papszArgsShadow[iArg] = pszArg;
|
1813 | 2290 |
papszArgs[iArg] = pszArg;
|
1814 | 2291 |
}
|
1815 | 2292 |
|
1816 | |
pchDst = pInstr->Core.pfnFunction(pchDst, papszArgs, pInstr->Core.pszFuncName);
|
1817 | |
|
1818 | |
iArg = pInstr->Core.cArgs;
|
|
2293 |
pchDst = pInstr->FnCore.pfnFunction(pchDst, papszArgs, pInstr->FnCore.pszFuncName);
|
|
2294 |
|
|
2295 |
iArg = pInstr->FnCore.cArgs;
|
1819 | 2296 |
while (iArg-- > 0)
|
1820 | 2297 |
free(papszArgsShadow[iArg]);
|
1821 | 2298 |
}
|
1822 | 2299 |
free(papszArgsShadow);
|
1823 | 2300 |
|
1824 | |
pInstrCore = pInstr->Core.pNext;
|
|
2301 |
pInstrCore = pInstr->FnCore.pNext;
|
1825 | 2302 |
break;
|
1826 | 2303 |
}
|
1827 | 2304 |
|
|
1861 | 2338 |
|
1862 | 2339 |
|
1863 | 2340 |
/**
|
1864 | |
* Execute a string expansion sub-program, outputting to a new heap buffer.
|
|
2341 |
* Execute a string expansion subprogram, outputting to a new heap buffer.
|
1865 | 2342 |
*
|
1866 | 2343 |
* @returns Pointer to the output buffer (hand to free when done).
|
1867 | |
* @param pSubProg The sub-program to execute.
|
|
2344 |
* @param pSubProg The subprogram to execute.
|
1868 | 2345 |
* @param pcchResult Where to return the size of the result. Optional.
|
1869 | 2346 |
*/
|
1870 | 2347 |
static char *kmk_exec_expand_subprog_to_tmp(PKMKCCEXPSUBPROG pSubProg, uint32_t *pcchResult)
|
|
1877 | 2354 |
|
1878 | 2355 |
/*
|
1879 | 2356 |
* Temporarily replace the variable buffer while executing the instruction
|
1880 | |
* stream for this sub program.
|
|
2357 |
* stream for this subprogram.
|
1881 | 2358 |
*/
|
1882 | 2359 |
pchDst = install_variable_buffer_with_hint(&pchOldVarBuf, &cbOldVarBuf,
|
1883 | 2360 |
pSubProg->Stats.cchAvg ? pSubProg->Stats.cchAvg + 32 : 256);
|
|
1936 | 2413 |
|
1937 | 2414 |
|
1938 | 2415 |
/**
|
1939 | |
* Equivalent of eval_buffer, only it's using the evalprog of the variable.
|
1940 | |
*
|
1941 | |
* @param pVar Pointer to the variable. Must have a program.
|
1942 | |
*/
|
1943 | |
void kmk_exec_evalval(struct variable *pVar)
|
1944 | |
{
|
1945 | |
KMK_CC_ASSERT(pVar->evalprog);
|
1946 | |
assert(0);
|
1947 | |
}
|
1948 | |
|
1949 | |
|
1950 | |
/**
|
1951 | 2416 |
* Expands a variable into a variable buffer using its expandprog.
|
1952 | 2417 |
*
|
1953 | 2418 |
* @returns The new variable buffer position.
|
|
1960 | 2425 |
KMK_CC_ASSERT(pVar->expandprog->uInputHash == kmk_cc_debug_string_hash(0, pVar->value));
|
1961 | 2426 |
return kmk_exec_expand_prog_to_var_buf(pVar->expandprog, pchDst);
|
1962 | 2427 |
}
|
|
2428 |
|
|
2429 |
|
|
2430 |
|
|
2431 |
|
|
2432 |
|
|
2433 |
/*
|
|
2434 |
*
|
|
2435 |
* Makefile evaluation programs.
|
|
2436 |
* Makefile evaluation programs.
|
|
2437 |
* Makefile evaluation programs.
|
|
2438 |
*
|
|
2439 |
*/
|
|
2440 |
/*#define KMK_CC_EVAL_ENABLE*/
|
|
2441 |
|
|
2442 |
|
|
2443 |
/**
|
|
2444 |
* Compiles a variable direct evaluation as is, setting v->evalprog on success.
|
|
2445 |
*
|
|
2446 |
* @returns Pointer to the program on success, NULL if no program was created.
|
|
2447 |
* @param pVar Pointer to the variable.
|
|
2448 |
*/
|
|
2449 |
struct kmk_cc_evalprog *kmk_cc_compile_variable_for_eval(struct variable *pVar)
|
|
2450 |
{
|
|
2451 |
return NULL;
|
|
2452 |
}
|
|
2453 |
|
|
2454 |
|
|
2455 |
/**
|
|
2456 |
* Compiles a makefile for
|
|
2457 |
*
|
|
2458 |
* @returns Pointer to the program on success, NULL if no program was created.
|
|
2459 |
* @param pVar Pointer to the variable.
|
|
2460 |
*/
|
|
2461 |
struct kmk_cc_evalprog *kmk_cc_compile_file_for_eval(FILE *pFile, const char *pszFilename)
|
|
2462 |
{
|
|
2463 |
#ifdef KMK_CC_EVAL_ENABLE
|
|
2464 |
/*
|
|
2465 |
* Read the entire file into a zero terminate memory buffer.
|
|
2466 |
*/
|
|
2467 |
size_t cchContent = 0;
|
|
2468 |
char *pszContent = NULL;
|
|
2469 |
struct stat st;
|
|
2470 |
if (!fstat(fileno(pFile), &st))
|
|
2471 |
{
|
|
2472 |
if ( st.st_size > (off_t)16*1024*1024
|
|
2473 |
&& st.st_size < 0)
|
|
2474 |
fatal(NULL, _("Makefile too large to compile: %ld bytes (%#lx) - max 16MB"), (long)st.st_size, (long)st.st_size);
|
|
2475 |
cchContent = (size_t)st.st_size;
|
|
2476 |
pszContent = (char *)xmalloc(cchContent + 1);
|
|
2477 |
|
|
2478 |
cchContent = fread(pszContent, 1, cchContent, pFile);
|
|
2479 |
if (ferror(pFile))
|
|
2480 |
fatal(NULL, _("Read error: %s"), strerror(errno));
|
|
2481 |
}
|
|
2482 |
else
|
|
2483 |
{
|
|
2484 |
size_t cbAllocated = 2048;
|
|
2485 |
do
|
|
2486 |
{
|
|
2487 |
cbAllocated *= 2;
|
|
2488 |
if (cbAllocated > 16*1024*1024)
|
|
2489 |
fatal(NULL, _("Makefile too large to compile: max 16MB"));
|
|
2490 |
pszContent = (char *)xrealloc(pszContent, cbAllocated);
|
|
2491 |
cchContent += fread(&pszContent[cchContent], 1, cbAllocated - 1 - cchContent, pFile);
|
|
2492 |
if (ferror(pFile))
|
|
2493 |
fatal(NULL, _("Read error: %s"), strerror(errno));
|
|
2494 |
} while (!feof(pFile));
|
|
2495 |
}
|
|
2496 |
pszContent[cchContent] = '\0';
|
|
2497 |
|
|
2498 |
/*
|
|
2499 |
* Call common function to do the compilation.
|
|
2500 |
*/
|
|
2501 |
//kmk_cc_eval_compile_common()
|
|
2502 |
|
|
2503 |
free(pszContent);
|
|
2504 |
return NULL;
|
|
2505 |
#else
|
|
2506 |
return NULL;
|
|
2507 |
#endif
|
|
2508 |
}
|
|
2509 |
|
|
2510 |
|
|
2511 |
/**
|
|
2512 |
* Equivalent of eval_buffer, only it's using the evalprog of the variable.
|
|
2513 |
*
|
|
2514 |
* @param pVar Pointer to the variable. Must have a program.
|
|
2515 |
*/
|
|
2516 |
void kmk_exec_eval_variable(struct variable *pVar)
|
|
2517 |
{
|
|
2518 |
KMK_CC_ASSERT(pVar->evalprog);
|
|
2519 |
assert(0);
|
|
2520 |
}
|
|
2521 |
|
|
2522 |
|
|
2523 |
/**
|
|
2524 |
* Worker for eval_makefile.
|
|
2525 |
*
|
|
2526 |
* @param pEvalProg The program pointer.
|
|
2527 |
*/
|
|
2528 |
void kmk_exec_eval_file(struct kmk_cc_evalprog *pEvalProg)
|
|
2529 |
{
|
|
2530 |
KMK_CC_ASSERT(pEvalProg);
|
|
2531 |
assert(0);
|
|
2532 |
}
|
|
2533 |
|
|
2534 |
|
|
2535 |
|
|
2536 |
/*
|
|
2537 |
*
|
|
2538 |
* Program destruction hooks.
|
|
2539 |
* Program destruction hooks.
|
|
2540 |
* Program destruction hooks.
|
|
2541 |
*
|
|
2542 |
*/
|
1963 | 2543 |
|
1964 | 2544 |
|
1965 | 2545 |
/**
|
|
2022 | 2602 |
}
|
2023 | 2603 |
|
2024 | 2604 |
|
|
2605 |
|
|
2606 |
|
|
2607 |
|
|
2608 |
|
|
2609 |
|
2025 | 2610 |
#endif /* CONFIG_WITH_COMPILER */
|
2026 | 2611 |
|