VirtualBox

Changeset 2788 in kBuild


Ignore:
Timestamp:
Sep 6, 2015 3:43:10 PM (10 years ago)
Author:
bird
Message:

kmk_cc_exec.c: Sketched the basic makefile evaluation 'instructions'.

Location:
trunk/src/kmk
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/kmk/file.c

    r2741 r2788  
    12171217  if (f->dontcare)
    12181218    puts (_("#  A default, MAKEFILES, or -include/sinclude makefile."));
     1219#if defined (CONFIG_WITH_COMPILER) || defined (CONFIG_WITH_MAKE_STATS)
     1220  if (f->eval_count > 0)
     1221    {
     1222# ifdef CONFIG_WITH_COMPILER
     1223      if (f->evalprog)
     1224        printf (_("#  Makefile evaluated %u times - compiled\n"), f->eval_count);
     1225      else
     1226# endif
     1227        printf (_("#  Makefile evaluated %u times\n"), f->eval_count);
     1228    }
     1229#endif
     1230
    12191231  puts (f->tried_implicit
    12201232        ? _("#  Implicit rule search has been done.")
  • trunk/src/kmk/filedef.h

    r2594 r2788  
    7272    /* Pointer to next target of an explicit multi target rule. */
    7373    struct file *multi_next;
     74#endif
     75
     76#ifdef CONFIG_WITH_COMPILER
     77    struct kmk_cc_evalprog *evalprog; /* Pointer to evalval/evalctx "program". */
    7478#endif
    7579
     
    120124                                  and the expanding done in snap_deps. */
    121125#endif
     126#if defined (CONFIG_WITH_COMPILER) || defined (CONFIG_WITH_MAKE_STATS)
     127    unsigned int eval_count:14; /* Times evaluated as a makefile. */
     128#endif
    122129  };
    123130
  • trunk/src/kmk/function.c

    r2771 r2788  
    20702070        {
    20712071          install_variable_buffer (&buf, &len); /* Really necessary? */
    2072           kmk_exec_evalval (v);
     2072          kmk_exec_eval_variable (v);
    20732073          restore_variable_buffer (buf, len);
    20742074        }
  • trunk/src/kmk/kmk_cc_exec.c

    r2777 r2788  
    2626
    2727
    28 /*******************************************************************************
    29 *   Header Files                                                               *
    30 *******************************************************************************/
     28/*********************************************************************************************************************************
     29*   Header Files                                                                                                                 *
     30*********************************************************************************************************************************/
    3131#include "make.h"
    3232
     
    4343#include <assert.h>
    4444
    45 /*******************************************************************************
    46 *   Defined Constants And Macros                                               *
    47 *******************************************************************************/
     45
     46/*********************************************************************************************************************************
     47*   Defined Constants And Macros                                                                                                 *
     48*********************************************************************************************************************************/
    4849/** @def KMK_CC_WITH_STATS
    4950 * Enables the collection of extra statistics. */
     
    7576
    7677
    77 /*******************************************************************************
    78 *   Structures and Typedefs                                                    *
    79 *******************************************************************************/
     78/** @def KMK_CC_OFFSETOF
     79 * Offsetof for simple stuff.  */
     80#if defined(__GNUC__)
     81# define KMK_CC_OFFSETOF(a_Struct, a_Member)        __builtin_offsetof(a_Struct, a_Member)
     82#else
     83# define KMK_CC_OFFSETOF(a_Struct, a_Member)        ( (uintptr_t)&( ((a_Struct *)(void *)0)->a_Member) )
     84#endif
     85
     86/** def KMK_CC_SIZEOF_MEMBER   */
     87#define KMK_CC_SIZEOF_MEMBER(a_Struct, a_Member)    ( sizeof( ((a_Struct *)(void *)0x1000)->a_Member) )
     88
     89/** @def KMK_CC_SIZEOF_VAR_STRUCT
     90 * Size of a struct with a variable sized array as the final member. */
     91#define KMK_CC_SIZEOF_VAR_STRUCT(a_Struct, a_FinalArrayMember, a_cArray) \
     92    ( KMK_CC_OFFSETOF(a_Struct, a_FinalArrayMember) + KMK_CC_SIZEOF_MEMBER(a_Struct, a_FinalArrayMember) * (a_cArray) )
     93
     94
     95
     96/** @def KMK_CC_STATIC_ASSERT_EX
     97 * Compile time assertion with text.
     98 */
     99#ifdef _MSC_VER_
     100# if _MSC_VER >= 1600
     101#  define KMK_CC_STATIC_ASSERT_EX(a_Expr, a_szExpl) static_assert(a_Expr, a_szExpl)
     102# else
     103#  define KMK_CC_STATIC_ASSERT_EX(a_Expr, a_szExpl) typedef int RTASSERTVAR[(a_Expr) ? 1 : 0]
     104# endif
     105#elif defined(__GNUC__) && defined(__GXX_EXPERIMENTAL_CXX0X__)
     106# define KMK_CC_STATIC_ASSERT_EX(a_Expr, a_szExpl)     static_assert(a_Expr, a_szExpl)
     107#elif !defined(__GNUC__) && !defined(__IBMC__) && !defined(__IBMCPP__)
     108# define KMK_CC_STATIC_ASSERT_EX(a_Expr, a_szExpl)  typedef int KMK_CC_STATIC_ASSERT_EX_TYPE[(a_Expr) ? 1 : 0]
     109#else
     110# define KMK_CC_STATIC_ASSERT_EX(a_Expr, a_szExpl)  extern int KMK_CC_STATIC_ASSERT_EX_VAR[(aExpr) ? 1 : 0]
     111extern int KMK_CC_STATIC_ASSERT_EX_VAR[1];
     112#endif
     113/** @def KMK_CC_STATIC_ASSERT
     114 * Compile time assertion, simple variant.
     115 */
     116#define KMK_CC_STATIC_ASSERT(a_Expr)                KMK_CC_STATIC_ASSERT_EX(a_Expr, #a_Expr)
     117
     118
     119/*********************************************************************************************************************************
     120*   Structures and Typedefs                                                                                                      *
     121*********************************************************************************************************************************/
    80122/**
    81123 * Block of expand instructions.
     
    95137} KMKCCBLOCK;
    96138typedef KMKCCBLOCK *PKMKCCBLOCK;
     139
     140
     141/** @name String Expansion
     142 * @{*/
    97143
    98144/**
     
    131177    /** The end of valid instructions (exclusive). */
    132178    kKmkCcExpInstr_End
    133 } KMKCCEXPANDINSTR;
     179} KMKCCEXPINSTR;
    134180
    135181/** Instruction core. */
    136182typedef struct kmk_cc_exp_core
    137183{
    138     /** The instruction opcode number (KMKCCEXPANDINSTR). */
    139     KMKCCEXPANDINSTR        enmOpCode;
     184    /** The instruction opcode number (KMKCCEXPINSTR). */
     185    KMKCCEXPINSTR           enmOpCode;
    140186} KMKCCEXPCORE;
    141187typedef KMKCCEXPCORE *PKMKCCEXPCORE;
    142188
    143189/**
    144  * String expansion sub program.
    145  */
     190 * String expansion subprogram.
     191 */
     192#pragma pack(1) /* save some precious bytes */
    146193typedef struct kmk_cc_exp_subprog
    147194{
     
    151198    KMKCCEXPSTATS           Stats;
    152199} KMKCCEXPSUBPROG;
     200#pragma pack()
    153201typedef KMKCCEXPSUBPROG *PKMKCCEXPSUBPROG;
     202KMK_CC_STATIC_ASSERT(sizeof(KMKCCEXPSUBPROG) == 12 || sizeof(void *) != 8);
     203
     204
     205/**
     206 * String expansion subprogram or plain string.
     207 */
     208#pragma pack(1) /* save some precious bytes */
     209typedef struct kmk_cc_exp_subprog_or_string
     210{
     211    /** Either a plain string pointer or a subprogram.   */
     212    union
     213    {
     214        /** Subprogram for expanding this argument. */
     215        KMKCCEXPSUBPROG     Subprog;
     216        /** Pointer to the plain string. */
     217        struct
     218        {
     219            /** Pointer to the string. */
     220            const char     *psz;
     221            /** String length. */
     222            uint32_t        cch;
     223        } Plain;
     224    } u;
     225    /** Set if subprogram (u.Subprog), clear if plain string (u.Plain). */
     226    uint8_t                 fSubprog;
     227    /** Set if the plain string is kept in the variable_strcache.
     228     * @remarks Here rather than in u.Plain to make use of alignment padding. */
     229    uint8_t                 fPlainIsInVarStrCache;
     230    /** Context/user specific. */
     231    uint8_t                 bUser;
     232    /** Context/user specific #2. */
     233    uint8_t                 bUser2;
     234} KMKCCEXPSUBPROGORPLAIN;
     235#pragma pack()
     236typedef KMKCCEXPSUBPROGORPLAIN *PKMKCCEXPSUBPROGORPLAIN;
     237KMK_CC_STATIC_ASSERT(  sizeof(void *) == 8
     238                     ? sizeof(KMKCCEXPSUBPROGORPLAIN) == 16
     239                     : sizeof(void *) == 4
     240                     ? sizeof(KMKCCEXPSUBPROGORPLAIN) == 12
     241                     : 1);
    154242
    155243/**
     
    186274    /** The core instruction. */
    187275    KMKCCEXPCORE            Core;
     276    /** The subprogram that will give us the variable name. */
     277    KMKCCEXPSUBPROG         Subprog;
    188278    /** Where to continue after this instruction.  (This is necessary since the
    189279     * instructions of the subprogram are emitted after this instruction.) */
    190280    PKMKCCEXPCORE           pNext;
    191     /** The subprogram that will give us the variable name. */
    192     KMKCCEXPSUBPROG         SubProg;
    193281} KMKCCEXPDYNVAR;
    194282typedef KMKCCEXPDYNVAR *PKMKCCEXPDYNVAR;
     
    226314    KMKCCEXPCORE            Core;
    227315    /** Number of arguments. */
    228     uint32_t                cArgs;
     316    uint32_t                cArgs; /**< @todo uint16_t to save 7 bytes of unecessary alignment padding on 64-bit systems, or merge fDirty into this member. */
    229317    /** Set if the function could be modifying the input arguments. */
    230318    uint8_t                 fDirty;
     
    252340{
    253341    /** The bits comment to both plain and dynamic functions. */
    254     KMKCCEXPFUNCCORE        Core;
     342    KMKCCEXPFUNCCORE        FnCore;
    255343    /** Variable sized argument list (cArgs + 1 in length, last entry is NULL).
    256344     * The string pointers are to memory following this instruction, to memory in
     
    260348} KMKCCEXPPLAINFUNC;
    261349typedef KMKCCEXPPLAINFUNC *PKMKCCEXPPLAINFUNC;
    262 /** Calculates the size of an KMKCCEXPPLAINFUNC with a_cArgs. */
    263 #define KMKCCEXPPLAINFUNC_SIZE(a_cArgs)  (sizeof(KMKCCEXPFUNCCORE) + (a_cArgs + 1) * sizeof(const char *))
     350/** Calculates the size of an KMKCCEXPPLAINFUNC structure with the apszArgs
     351 * member holding a_cArgs entries plus a NULL terminator. */
     352#define KMKCCEXPPLAINFUNC_SIZE(a_cArgs) KMK_CC_SIZEOF_VAR_STRUCT(KMKCCEXPDYNFUNC, aArgs, (a_cArgs) + 1)
    264353
    265354/**
     
    269358{
    270359    /** The bits comment to both plain and dynamic functions. */
    271     KMKCCEXPFUNCCORE        Core;
    272     /** Variable sized argument list (cArgs + 1 in length, last entry is NULL).
    273      * The string pointers are to memory following this instruction, to memory in
    274      * the next block or to memory in the variable / makefile we're working on
    275      * (if zero terminated appropriately). */
    276     struct
    277     {
    278         /** Set if plain string argument, clear if sub program. */
    279         uint8_t             fPlain;
    280         union
    281         {
    282             /** Sub program for expanding this argument. */
    283             KMKCCEXPSUBPROG     SubProg;
    284             struct
    285             {
    286                 /** Pointer to the plain argument string.
    287                  * This is allocated in the same manner as the
    288                  * string pointed to by KMKCCEXPPLAINFUNC::apszArgs. */
    289                 const char      *pszArg;
    290             } Plain;
    291         } u;
    292     }                       aArgs[1];
     360    KMKCCEXPFUNCCORE        FnCore;
     361    /** Variable sized argument list (FnCore.cArgs in length).
     362     * The subprograms / strings are allocated after this array (or in the next
     363     * block). */
     364    KMKCCEXPSUBPROGORPLAIN  aArgs[1];
    293365} KMKCCEXPDYNFUNC;
    294366typedef KMKCCEXPDYNFUNC *PKMKCCEXPDYNFUNC;
    295 /** Calculates the size of an KMKCCEXPPLAINFUNC with a_cArgs. */
    296 #define KMKCCEXPDYNFUNC_SIZE(a_cArgs)  (  sizeof(KMKCCEXPFUNCCORE) \
    297                                         + (a_cArgs) * sizeof(((PKMKCCEXPDYNFUNC)(uintptr_t)42)->aArgs[0]) )
     367/** Calculates the size of an KMKCCEXPDYNFUNC structure with the apszArgs
     368 * member holding a_cArgs entries (no zero terminator). */
     369#define KMKCCEXPDYNFUNC_SIZE(a_cArgs)  KMK_CC_SIZEOF_VAR_STRUCT(KMKCCEXPDYNFUNC, aArgs, a_cArgs)
    298370
    299371/**
     
    331403typedef KMKCCEXPPROG *PKMKCCEXPPROG;
    332404
    333 
    334 /*******************************************************************************
    335 *   Global Variables                                                           *
    336 *******************************************************************************/
     405/** @} */
     406
     407
     408/** @name Makefile Evaluation
     409 * @{  */
     410
     411/** Pointer to a makefile evaluation program. */
     412typedef struct kmk_cc_evalprog *PKMKCCEVALPROG;
     413
     414/**
     415 * Makefile evaluation instructions.
     416 */
     417typedef enum KMKCCEVALINSTR
     418{
     419    /** Jump instruction - KMKCCEVALJUMP. */
     420    kKmkCcEvalInstr_jump = 0,
     421
     422    /** [local|override|export] variable  = value - KMKCCEVALASSIGN.
     423     * @note Can be used for target-specific variables. */
     424    kKmkCcEvalInstr_assign_recursive,
     425    /** [local|override|export] variable := value - KMKCCEVALASSIGN.
     426     * @note Can be used for target-specific variables. */
     427    kKmkCcEvalInstr_assign_simple,
     428    /** [local|override|export] variable += value - KMKCCEVALASSIGN.
     429     * @note Can be used for target-specific variables. */
     430    kKmkCcEvalInstr_assign_append,
     431    /** [local|override|export] variable -= value - KMKCCEVALASSIGN.
     432     * @note Can be used for target-specific variables. */
     433    kKmkCcEvalInstr_assign_prepend,
     434    /** [local|override|export] variable ?= value - KMKCCEVALASSIGN.
     435     * @note Can be used for target-specific variables. */
     436    kKmkCcEvalInstr_assign_if_new,
     437    /** [local|override|export] define variable ... endef - KMKCCEVALASSIGNDEF. */
     438    kKmkCcEvalInstr_assign_define,
     439
     440    /** export variable1 [variable2...] - KMKCCEVALEXPORT. */
     441    kKmkCcEvalInstr_export,
     442    /** unexport variable1 [variable2...] - KMKCCEVALEXPORT. */
     443    kKmkCcEvalInstr_unexport,
     444    /** export - KMKCCEVALCORE. */
     445    kKmkCcEvalInstr_export_all,
     446    /** unexport - KMKCCEVALCORE. */
     447    kKmkCcEvalInstr_unexport_all,
     448
     449    /** [else] ifdef variable - KMKCCEVALIFDEFPLAIN. */
     450    kKmkCcEvalInstr_ifdef_plain,
     451    /** [else] ifndef variable - KMKCCEVALIFDEFPLAIN. */
     452    kKmkCcEvalInstr_ifndef_plain,
     453    /** [else] ifdef variable - KMKCCEVALIFDEFDYNAMIC. */
     454    kKmkCcEvalInstr_ifdef_dynamic,
     455    /** [else] ifndef variable - KMKCCEVALIFDEFDYNAMIC. */
     456    kKmkCcEvalInstr_ifndef_dynamic,
     457    /** [else] ifeq (a,b) - KMKCCEVALIFEQ. */
     458    kKmkCcEvalInstr_ifeq,
     459    /** [else] ifeq (a,b) - KMKCCEVALIFEQ. */
     460    kKmkCcEvalInstr_ifneq,
     461    /** [else] if1of (set-a,set-b) - KMKCCEVALIF1OF. */
     462    kKmkCcEvalInstr_if1of,
     463    /** [else] ifn1of (set-a,set-b) - KMKCCEVALIF1OF. */
     464    kKmkCcEvalInstr_ifn1of,
     465    /** [else] if expr - KMKCCEVALIFEXPR. */
     466    kKmkCcEvalInstr_if,
     467
     468    /** include file1 [file2...] - KMKCCEVALINCLUDE. */
     469    kKmkCcEvalInstr_include,
     470    /** [sinclude|-include] file1 [file2...]  - KMKCCEVALINCLUDE. */
     471    kKmkCcEvalInstr_include_silent,
     472    /** includedep file1 [file2...] - KMKCCEVALINCLUDE. */
     473    kKmkCcEvalInstr_includedep,
     474    /** includedep-queue file1 [file2...] - KMKCCEVALINCLUDE. */
     475    kKmkCcEvalInstr_includedep_queue,
     476    /** includedep-flush file1 [file2...] - KMKCCEVALINCLUDE. */
     477    kKmkCcEvalInstr_includedep_flush,
     478
     479    /** Recipe without commands (defines dependencies) - KMKCCEVALRECIPE. */
     480    kKmkCcEvalInstr_recipe_no_commands,
     481    /** Recipe with commands (defines dependencies) - KMKCCEVALRECIPE. */
     482    kKmkCcEvalInstr_recipe_start_normal,
     483    /** Recipe with commands (defines dependencies) - KMKCCEVALRECIPE. */
     484    kKmkCcEvalInstr_recipe_start_double_colon,
     485    /** Recipe with commands (defines dependencies) - KMKCCEVALRECIPE. */
     486    kKmkCcEvalInstr_recipe_start_pattern,
     487    /** Adds more commands to the current recipe - KMKCCEVALRECIPECOMMANDS. */
     488    kKmkCcEvalInstr_recipe_commands,
     489    /** Adds more commands to the current recipe - KMKCCEVALRECIPECOMMANDS. */
     490    kKmkCcEvalInstr_recipe_vari,
     491    /** Special instruction for indicating the end of the recipe commands - KMKCCEVALCORE. */
     492    kKmkCcEvalInstr_recipe_end,
     493    /** Cancel previously defined pattern rule - KMKCCEVALRECIPE.  */
     494    kKmkCcEvalInstr_recipe_cancel_pattern,
     495
     496    /** vpath pattern directories - KMKCCEVALVPATH. */
     497    kKmkCcEvalInstr_vpath,
     498    /** vpath pattern directories - KMKCCEVALVPATH. */
     499    kKmkCcEvalInstr_vpath_clear_pattern,
     500    /** vpath - KMKCCEVALCORE. */
     501    kKmkCcEvalInstr_vpath_clear_all,
     502
     503    /** The end of valid instructions (exclusive). */
     504    kKmkCcEvalInstr_End
     505} KMKCCEVALINSTR;
     506
     507/**
     508 * Instruction core common to all instructions.
     509 */
     510typedef struct kmk_cc_eval_core
     511{
     512    /** The instruction opcode number (KMKCCEVALINSTR). */
     513    KMKCCEVALINSTR          enmOpCode;
     514    /** The line number in the source this statement is associated with. */
     515    unsigned                iLine;
     516} KMKCCEVALCORE;
     517/** Pointer to an instruction core structure. */
     518typedef KMKCCEVALCORE *PKMKCCEVALCORE;
     519
     520/**
     521 * Instruction format for kKmkCcEvalInstr_jump.
     522 */
     523typedef struct kmk_cc_eval_jump
     524{
     525    /** The core instruction. */
     526    KMKCCEVALCORE           Core;
     527    /** Where to jump to (new instruction block or endif, typically). */
     528    PKMKCCEVALCORE          pNext;
     529} KMKCCEVALJUMP;
     530typedef KMKCCEVALJUMP *PKMKCCEVALJUMP;
     531
     532/**
     533 * Instruction format for kKmkCcEvalInstr_assign_recursive,
     534 * kKmkCcEvalInstr_assign_simple, kKmkCcEvalInstr_assign_append,
     535 * kKmkCcEvalInstr_assign_prepend and kKmkCcEvalInstr_assign_if_new.
     536 */
     537typedef struct kmk_cc_eval_assign
     538{
     539    /** The core instruction. */
     540    KMKCCEVALCORE           Core;
     541    /** Whether the 'export' directive was used. */
     542    uint8_t                 fExport;
     543    /** Whether the 'override' directive was used. */
     544    uint8_t                 fOverride;
     545    /** Whether the 'local' directive was used. */
     546    uint8_t                 fLocal;
     547    /** The variable name.
     548     * @remarks Plain text names are in variable_strcache. */
     549    KMKCCEXPSUBPROGORPLAIN  Variable;
     550    /** The value or value expression. */
     551    KMKCCEXPSUBPROGORPLAIN  Value;
     552    /** Pointer to the next instruction. */
     553    PKMKCCEVALCORE          pNext;
     554} KMKCCEVALASSIGN;
     555typedef KMKCCEVALASSIGN *PKMKCCEVALASSIGN;
     556
     557/**
     558 * Instruction format for kKmkCcEvalInstr_assign_define.
     559 */
     560typedef struct kmk_cc_eval_assign_define
     561{
     562    /** The assignment core structure. */
     563    KMKCCEVALASSIGN         AssignCore;
     564    /** Makefile evaluation program compiled from the define.
     565     * NULL if it does not compile.
     566     * @todo Let's see if this is actually doable... */
     567    PKMKCCEVALPROG          pEvalProg;
     568} KMKCCEVALASSIGNDEF;
     569typedef KMKCCEVALASSIGNDEF *PKMKCCEVALASSIGNDEF;
     570
     571/**
     572 * Instruction format for kKmkCcEvalInstr_export and kKmkCcEvalInstr_unexport.
     573 */
     574typedef struct kmk_cc_eval_export
     575{
     576    /** The core instruction. */
     577    KMKCCEVALCORE           Core;
     578    /** The number of variables named in aVars. */
     579    uint32_t                cVars;
     580    /** Pointer to the next instruction. */
     581    PKMKCCEVALCORE          pNext;
     582    /** The variable names.
     583     * Expressions will be expanded and split on space.
     584     * @remarks Plain text names are in variable_strcache. */
     585    KMKCCEXPSUBPROGORPLAIN  aVars[1];
     586} KMKCCEVALEXPORT;
     587typedef KMKCCEVALEXPORT *PKMKCCEVALEXPORT;
     588/** Calculates the size of an KMKCCEVALEXPORT structure for @a a_cVars. */
     589#define KMKCCEVALEXPORT_SIZE(a_cVars) KMK_CC_SIZEOF_VAR_STRUCT(KMKCCEVALVPATH, aVars, a_cVars)
     590
     591/**
     592 * Core structure for all conditionals (kKmkCcEvalInstr_if*).
     593 */
     594typedef struct kmk_cc_eval_if_core
     595{
     596    /** The core instruction. */
     597    KMKCCEVALCORE           Core;
     598    /** Condition true: Pointer to the next instruction. */
     599    PKMKCCEVALCORE          pNextTrue;
     600    /** Condition false: Pointer to the next instruction (i.e. 'else if*'
     601     * or whatever follows 'else' / 'endif'. */
     602    PKMKCCEVALCORE          pNextFalse;
     603    /** Pointer to the previous conditional for 'else if*' directives.
     604     * This is to assist the compilation process. */
     605    PKMKCCEVALCORE          pPrevCond;
     606} KMKCCEVALIFCORE;
     607typedef KMKCCEVALIFCORE *PKMKCCEVALIFCORE;
     608
     609/**
     610 * Instruction format for kKmkCcEvalInstr_ifdef_plain and
     611 * kKmkCcEvalInstr_ifndef_plain.
     612 * The variable name is known at compilation time.
     613 */
     614typedef struct kmk_cc_eval_ifdef_plain
     615{
     616    /** The 'if' core structure. */
     617    KMKCCEVALIFCORE         IfCore;
     618    /** The name of the variable (points into variable_strcache). */
     619    const char             *pszName;
     620} KMKCCEVALIFDEFPLAIN;
     621typedef KMKCCEVALIFDEFPLAIN *PKMKCCEVALIFDEFPLAIN;
     622
     623/**
     624 * Instruction format for kKmkCcEvalInstr_ifdef_dynamic and
     625 * kKmkCcEvalInstr_ifndef_dynamic.
     626 * The variable name is dynamically expanded at run time.
     627 */
     628typedef struct kmk_cc_eval_ifdef_dynamic
     629{
     630    /** The 'if' core structure. */
     631    KMKCCEVALIFCORE         IfCore;
     632    /** The subprogram that will give us the variable name. */
     633    KMKCCEXPSUBPROG         NameSubProg;
     634} KMKCCEVALIFDEFDYNAMIC;
     635KMK_CC_STATIC_ASSERT(sizeof(KMKCCEVALIFDEFDYNAMIC) == 48 || sizeof(void *) != 8);
     636typedef KMKCCEVALIFDEFDYNAMIC *PKMKCCEVALIFDEFDYNAMIC;
     637
     638/**
     639 * Instruction format for kKmkCcEvalInstr_ifeq and kKmkCcEvalInstr_ifneq.
     640 */
     641typedef struct kmk_cc_eval_ifeq
     642{
     643    /** The 'if' core structure. */
     644    KMKCCEVALIFCORE         IfCore;
     645    /** The left hand side string expression (dynamic or plain). */
     646    KMKCCEXPSUBPROGORPLAIN  Left;
     647    /** The rigth hand side string expression (dynamic or plain). */
     648    KMKCCEXPSUBPROGORPLAIN  Right;
     649} KMKCCEVALIFEQ;
     650typedef KMKCCEVALIFEQ *PKMKCCEVALIFEQ;
     651
     652/**
     653 * Instruction format for kKmkCcEvalInstr_if1of and kKmkCcEvalInstr_ifn1of.
     654 *
     655 * @todo This can be optimized further by pre-hashing plain text items.  One of
     656 *       the sides are usually plain text.
     657 */
     658typedef struct kmk_cc_eval_if1of
     659{
     660    /** The 'if' core structure. */
     661    KMKCCEVALIFCORE         IfCore;
     662    /** The left hand side string expression (dynamic or plain). */
     663    KMKCCEXPSUBPROGORPLAIN  Left;
     664    /** The rigth hand side string expression (dynamic or plain). */
     665    KMKCCEXPSUBPROGORPLAIN  Right;
     666} KMKCCEVALIF1OF;
     667typedef KMKCCEVALIF1OF *PKMKCCEVALIF1OF;
     668
     669/**
     670 * Instruction format for kKmkCcEvalInstr_if.
     671 *
     672 * @todo Parse and compile the expression.  At least strip whitespace in it.
     673 */
     674typedef struct kmk_cc_eval_if_expr
     675{
     676    /** The 'if' core structure. */
     677    KMKCCEVALIFCORE         IfCore;
     678    /** The expression string length. */
     679    uint16_t                cchExpr;
     680    /** The expression string. */
     681    char                    szExpr[1];
     682} KMKCCEVALIFEXPR;
     683typedef KMKCCEVALIFEXPR *PKMKCCEVALIFEXPR;
     684/** Calculates the size of an KMKCCEVALIFEXPR structure for @a a_cchExpr long
     685 * expression string (terminator is automatically added).  */
     686#define KMKCCEVALIFEXPR_SIZE(a_cchExpr) KMK_CC_SIZEOF_VAR_STRUCT(KMKCCEVALIFEXPR, szExpr, (a_cchExpr) + 1)
     687
     688/**
     689 * Instruction format for kKmkCcEvalInstr_include,
     690 * kKmkCcEvalInstr_include_silent, kKmkCcEvalInstr_includedep,
     691 * kKmkCcEvalInstr_includedep_queue, kKmkCcEvalInstr_includedep_flush.
     692 */
     693typedef struct kmk_cc_eval_include
     694{
     695    /** The core instruction. */
     696    KMKCCEVALCORE           Core;
     697    /** The number of files. */
     698    uint32_t                cFiles;
     699    /** Pointer to the next instruction (subprogs and strings after this one). */
     700    PKMKCCEVALCORE          pNext;
     701    /** The files to be included.
     702     * Expressions will be expanded and split on space.
     703     * @todo Plain text file name could be replaced by file string cache entries. */
     704    KMKCCEXPSUBPROGORPLAIN  aFiles[1];
     705} KMKCCEVALINCLUDE;
     706typedef KMKCCEVALINCLUDE *PKMKCCEVALINCLUDE;
     707/** Calculates the size of an KMKCCEVALINCLUDE structure for @a a_cFiles files. */
     708#define KMKCCEVALINCLUDE_SIZE(a_cFiles) KMK_CC_SIZEOF_VAR_STRUCT(KMKCCEVALINCLUDE, aFiles, a_cFiles)
     709
     710/**
     711 * Instruction format for kKmkCcEvalInstr_recipe_no_commands,
     712 * kKmkCcEvalInstr_recipe_start_normal,
     713 * kKmkCcEvalInstr_recipe_start_double_colon, kKmkCcEvalInstr_includedep_queue,
     714 * kKmkCcEvalInstr_recipe_start_pattern.
     715 */
     716typedef struct kmk_cc_eval_recipe
     717{
     718    /** The core instruction. */
     719    KMKCCEVALCORE           Core;
     720    /** The total number of files and dependencies in aFilesAndDeps. */
     721    uint16_t                cFilesAndDeps;
     722
     723    /** Number of targets (from index 0).
     724     * This is always 1 if this is an explicit multitarget or pattern recipe,
     725     * indicating the main target. */
     726    uint16_t                cTargets;
     727    /** Explicit multitarget & patterns: First always made target. */
     728    uint16_t                iFirstAlwaysMadeTargets;
     729    /** Explicit multitarget & patterns: Number of always targets. */
     730    uint16_t                cAlwaysMadeTargets;
     731    /** Explicit multitarget: First maybe made target. */
     732    uint16_t                iFirstMaybeTarget;
     733    /** Explicit multitarget: Number of maybe made targets. */
     734    uint16_t                cMaybeTargets;
     735
     736    /** First dependency. */
     737    uint16_t                iFirstDep;
     738    /** Number of ordinary dependnecies. */
     739    uint16_t                cDeps;
     740    /** First order only dependency. */
     741    uint16_t                iFirstOrderOnlyDep;
     742    /** Number of ordinary dependnecies. */
     743    uint16_t                cOrderOnlyDeps;
     744
     745    /** Pointer to the next instruction (subprogs and strings after this one). */
     746    PKMKCCEVALCORE          pNext;
     747    /** The .MUST_MAKE variable value, if present.
     748     * If not present, this is a zero length plain string. */
     749    KMKCCEXPSUBPROGORPLAIN  MustMake;
     750    /** The target files and dependencies.
     751     * This is sorted into several sections, as defined by the above indexes and
     752     * counts.  Expressions will be expanded and split on space.
     753     *
     754     * The KMKCCEXPSUBPROGORPLAIN::bUser member is used to indicate secondary
     755     * expansion for a plain text entry.
     756     *
     757     * @todo Plain text file name could be replaced by file string cache entries. */
     758    KMKCCEXPSUBPROGORPLAIN  aFilesAndDeps[1];
     759} KMKCCEVALRECIPE;
     760typedef KMKCCEVALRECIPE *PKMKCCEVALRECIPE;
     761/** Calculates the size of an KMKCCEVALRECIPE structure for @a a_cFiles
     762 *  files. */
     763#define KMKCCEVALRECIPE_SIZE(a_cFilesAndDeps) KMK_CC_SIZEOF_VAR_STRUCT(KMKCCEVALRECIPE, aFilesAndDeps, a_cFilesAndDeps)
     764
     765/**
     766 * Instruction format for kKmkCcEvalInstr_recipe_commands.
     767 */
     768typedef struct kmk_cc_eval_recipe_commands
     769{
     770    /** The core instruction. */
     771    KMKCCEVALCORE           Core;
     772    /** The number of search directories. */
     773    uint32_t                cCommands;
     774    /** Pointer to the next instruction (subprogs and strings after this one). */
     775    PKMKCCEVALCORE          pNext;
     776    /** Commands to add to the current recipe.
     777     * Expressions will be expanded and split on space. */
     778    KMKCCEXPSUBPROGORPLAIN  aCommands[1];
     779} KMKCCEVALRECIPECOMMANDS;
     780typedef KMKCCEVALRECIPECOMMANDS *PKMKCCEVALRECIPECOMMANDS;
     781/** Calculates the size of an KMKCCEVALRECIPECOMMANDS structure for
     782 * @a a_cCommands commands. */
     783#define KMKCCEVALRECIPECOMMANDS_SIZE(a_cCommands) KMK_CC_SIZEOF_VAR_STRUCT(KMKCCEVALRECIPECOMMANDS, aCommands, a_cCommands)
     784
     785/**
     786 * Instruction format for kKmkCcEvalInstr_vpath and
     787 * kKmkCcEvalInstr_vpath_clear_pattern.
     788 */
     789typedef struct kmk_cc_eval_vpath
     790{
     791    /** The core instruction. */
     792    KMKCCEVALCORE           Core;
     793    /** The number of search directories.
     794     * This will be zero for kKmkCcEvalInstr_vpath_clear_pattern. */
     795    uint32_t                cDirs;
     796    /** Pointer to the next instruction (subprogs and strings after this one). */
     797    PKMKCCEVALCORE          pNext;
     798    /** The pattern. */
     799    KMKCCEXPSUBPROGORPLAIN  Pattern;
     800    /** The directory. Expressions will be expanded and split on space. */
     801    KMKCCEXPSUBPROGORPLAIN  aDirs[1];
     802} KMKCCEVALVPATH;
     803typedef KMKCCEVALVPATH *PKMKCCEVALVPATH;
     804/** Calculates the size of an KMKCCEVALVPATH structure for @a a_cFiles files. */
     805#define KMKCCEVALVPATH_SIZE(a_cFiles) KMK_CC_SIZEOF_VAR_STRUCT(KMKCCEVALVPATH, aDirs, a_cDirs)
     806
     807
     808/**
     809 * Makefile evaluation program.
     810 */
     811typedef struct kmk_cc_evalprog
     812{
     813    /** Pointer to the first instruction for this program. */
     814    PKMKCCEVALCORE          pFirstInstr;
     815    /** List of blocks for this program (LIFO). */
     816    PKMKCCBLOCK             pBlockTail;
     817
     818} KMKCCEVALPROG;
     819
     820/** @} */
     821
     822
     823/*********************************************************************************************************************************
     824*   Global Variables                                                                                                             *
     825*********************************************************************************************************************************/
    337826static uint32_t g_cVarForExpandCompilations = 0;
    338827static uint32_t g_cVarForExpandExecs = 0;
     
    349838
    350839
    351 /*******************************************************************************
    352 *   Internal Functions                                                         *
    353 *******************************************************************************/
     840/*********************************************************************************************************************************
     841*   Internal Functions                                                                                                           *
     842*********************************************************************************************************************************/
    354843static int kmk_cc_exp_compile_subprog(PKMKCCBLOCK *ppBlockTail, const char *pchStr, uint32_t cchStr, PKMKCCEXPSUBPROG pSubProg);
    355844static char *kmk_exec_expand_subprog_to_tmp(PKMKCCEXPSUBPROG pSubProg, uint32_t *pcch);
     
    373862    printf(_("# Variables compiled for string expansion: %6u\n"), g_cVarForExpandCompilations);
    374863    printf(_("# Variables string expansion runs:         %6u\n"), g_cVarForExpandExecs);
    375     printf(_("# String expansion runs per compile:       %6u\n"), g_cVarForExpandExecs / g_cVarForExpandExecs);
     864    printf(_("# String expansion runs per compile:       %6u\n"), g_cVarForExpandExecs / g_cVarForExpandCompilations);
    376865#ifdef KMK_CC_WITH_STATS
    377866    printf(_("#          Single alloc block exp progs:   %6u (%u%%)\n"
     
    7351224}
    7361225
    737 
    738 /*
     1226   /*
    7391227 *
    7401228 * The string expansion compiler.
     
    8261314    uint32_t            cActualArgs = cArgs <= cMaxArgs || !cMaxArgs ? cArgs : cMaxArgs;
    8271315    PKMKCCEXPDYNFUNC    pInstr  = (PKMKCCEXPDYNFUNC)kmk_cc_block_alloc_exp(ppBlockTail, KMKCCEXPDYNFUNC_SIZE(cActualArgs));
    828     pInstr->Core.Core.enmOpCode = kKmkCcExpInstr_DynamicFunction;
    829     pInstr->Core.cArgs          = cActualArgs;
    830     pInstr->Core.pfnFunction    = pfnFunction;
    831     pInstr->Core.pszFuncName    = pszFunction;
    832     pInstr->Core.fDirty         = kmk_cc_is_dirty_function(pszFunction);
     1316    pInstr->FnCore.Core.enmOpCode = kKmkCcExpInstr_DynamicFunction;
     1317    pInstr->FnCore.cArgs          = cActualArgs;
     1318    pInstr->FnCore.pfnFunction    = pfnFunction;
     1319    pInstr->FnCore.pszFuncName    = pszFunction;
     1320    pInstr->FnCore.fDirty         = kmk_cc_is_dirty_function(pszFunction);
    8331321
    8341322    /*
     
    8651353        }
    8661354
    867         pInstr->aArgs[iArg].fPlain = !fDollar;
     1355        pInstr->aArgs[iArg].fSubprog = fDollar;
    8681356        if (fDollar)
    8691357        {
     
    8711359            int rc;
    8721360            kmk_cc_block_realign(ppBlockTail);
    873             rc = kmk_cc_exp_compile_subprog(ppBlockTail, pchArgs, cchThisArg, &pInstr->aArgs[iArg].u.SubProg);
     1361            rc = kmk_cc_exp_compile_subprog(ppBlockTail, pchArgs, cchThisArg, &pInstr->aArgs[iArg].u.Subprog);
    8741362            if (rc != 0)
    8751363                return rc;
     
    8781366        {
    8791367            /* Duplicate it. */
    880             pInstr->aArgs[iArg].u.Plain.pszArg = kmk_cc_block_strdup(ppBlockTail, pchArgs, cchThisArg);
     1368            pInstr->aArgs[iArg].u.Plain.psz = kmk_cc_block_strdup(ppBlockTail, pchArgs, cchThisArg);
     1369            pInstr->aArgs[iArg].u.Plain.cch = cchThisArg;
    8811370        }
    8821371        iArg++;
     
    8921381     */
    8931382    kmk_cc_block_realign(ppBlockTail);
    894     pInstr->Core.pNext = (PKMKCCEXPCORE)kmk_cc_block_get_next_ptr(*ppBlockTail);
     1383    pInstr->FnCore.pNext = (PKMKCCEXPCORE)kmk_cc_block_get_next_ptr(*ppBlockTail);
    8951384    return 0;
    8961385}
     
    9261415    uint32_t            cActualArgs = cArgs <= cMaxArgs || !cMaxArgs ? cArgs : cMaxArgs;
    9271416    PKMKCCEXPPLAINFUNC  pInstr  = (PKMKCCEXPPLAINFUNC)kmk_cc_block_alloc_exp(ppBlockTail, KMKCCEXPPLAINFUNC_SIZE(cActualArgs));
    928     pInstr->Core.Core.enmOpCode = kKmkCcExpInstr_PlainFunction;
    929     pInstr->Core.cArgs          = cActualArgs;
    930     pInstr->Core.pfnFunction    = pfnFunction;
    931     pInstr->Core.pszFuncName    = pszFunction;
    932     pInstr->Core.fDirty         = kmk_cc_is_dirty_function(pszFunction);
     1417    pInstr->FnCore.Core.enmOpCode = kKmkCcExpInstr_PlainFunction;
     1418    pInstr->FnCore.cArgs          = cActualArgs;
     1419    pInstr->FnCore.pfnFunction    = pfnFunction;
     1420    pInstr->FnCore.pszFuncName    = pszFunction;
     1421    pInstr->FnCore.fDirty         = kmk_cc_is_dirty_function(pszFunction);
    9331422
    9341423    /*
     
    9761465     */
    9771466    kmk_cc_block_realign(ppBlockTail);
    978     pInstr->Core.pNext = (PKMKCCEXPCORE)kmk_cc_block_get_next_ptr(*ppBlockTail);
     1467    pInstr->FnCore.pNext = (PKMKCCEXPCORE)kmk_cc_block_get_next_ptr(*ppBlockTail);
    9791468}
    9801469
     
    9991488    pInstr->Core.enmOpCode = kKmkCcExpInstr_DynamicVariable;
    10001489
    1001     rc = kmk_cc_exp_compile_subprog(ppBlockTail, pchNameExpr, cchNameExpr, &pInstr->SubProg);
     1490    rc = kmk_cc_exp_compile_subprog(ppBlockTail, pchNameExpr, cchNameExpr, &pInstr->Subprog);
    10021491
    10031492    pInstr->pNext = (PKMKCCEXPCORE)kmk_cc_block_get_next_ptr(*ppBlockTail);
     
    14101899
    14111900/**
    1412  * Compiles a string expansion sub program.
     1901 * Compiles a string expansion subprogram.
    14131902 *
    14141903 * The caller typically make a call to kmk_cc_block_get_next_ptr after this
     
    14221911 * @param   cchStr              The length of the string to compile. Expected to
    14231912 *                              be at least on char long.
    1424  * @param   pSubProg            The sub program structure to initialize.
     1913 * @param   pSubProg            The subprogram structure to initialize.
    14251914 */
    14261915static int kmk_cc_exp_compile_subprog(PKMKCCBLOCK *ppBlockTail, const char *pchStr, uint32_t cchStr, PKMKCCEXPSUBPROG pSubProg)
     
    14651954
    14661955        /*
    1467          * Join forces with the sub program compilation code.
     1956         * Join forces with the subprogram compilation code.
    14681957         */
    14691958        if (kmk_cc_exp_compile_common(&pProg->pBlockTail, pchStr, cchStr) == 0)
     
    14931982
    14941983/**
    1495  * Compiles a variable direct evaluation as is, setting v->evalprog on success.
    1496  *
    1497  * @returns Pointer to the program on success, NULL if no program was created.
    1498  * @param   pVar        Pointer to the variable.
    1499  */
    1500 struct kmk_cc_evalprog   *kmk_cc_compile_variable_for_eval(struct variable *pVar)
    1501 {
    1502     return NULL;
    1503 }
    1504 
    1505 
    1506 /**
    15071984 * Updates the recursive_without_dollar member of a variable structure.
    15081985 *
     
    16212098                struct variable *pVar;
    16222099                uint32_t         cchName;
    1623                 char            *pszName = kmk_exec_expand_subprog_to_tmp(&pInstr->SubProg, &cchName);
     2100                char            *pszName = kmk_exec_expand_subprog_to_tmp(&pInstr->Subprog, &cchName);
    16242101                char            *pszColon = (char *)memchr(pszName, ':', cchName);
    16252102                char            *pszEqual;
     
    17172194                PKMKCCEXPPLAINFUNC pInstr = (PKMKCCEXPPLAINFUNC)pInstrCore;
    17182195                uint32_t iArg;
    1719                 if (!pInstr->Core.fDirty)
     2196                if (!pInstr->FnCore.fDirty)
    17202197                {
    17212198#ifdef KMK_CC_STRICT
    17222199                    uint32_t uCrcBefore = 0;
    17232200                    uint32_t uCrcAfter = 0;
    1724                     iArg = pInstr->Core.cArgs;
     2201                    iArg = pInstr->FnCore.cArgs;
    17252202                    while (iArg-- > 0)
    17262203                        uCrcBefore = kmk_cc_debug_string_hash(uCrcBefore, pInstr->apszArgs[iArg]);
    17272204#endif
    17282205
    1729                     pchDst = pInstr->Core.pfnFunction(pchDst, (char **)&pInstr->apszArgs[0], pInstr->Core.pszFuncName);
     2206                    pchDst = pInstr->FnCore.pfnFunction(pchDst, (char **)&pInstr->apszArgs[0], pInstr->FnCore.pszFuncName);
    17302207
    17312208#ifdef KMK_CC_STRICT
    1732                     iArg = pInstr->Core.cArgs;
     2209                    iArg = pInstr->FnCore.cArgs;
    17332210                    while (iArg-- > 0)
    17342211                        uCrcAfter = kmk_cc_debug_string_hash(uCrcAfter, pInstr->apszArgs[iArg]);
     
    17382215                else
    17392216                {
    1740                     char **papszShadowArgs = xmalloc((pInstr->Core.cArgs * 2 + 1) * sizeof(papszShadowArgs[0]));
    1741                     char **papszArgs = &papszShadowArgs[pInstr->Core.cArgs];
    1742 
    1743                     iArg = pInstr->Core.cArgs;
     2217                    char **papszShadowArgs = xmalloc((pInstr->FnCore.cArgs * 2 + 1) * sizeof(papszShadowArgs[0]));
     2218                    char **papszArgs = &papszShadowArgs[pInstr->FnCore.cArgs];
     2219
     2220                    iArg = pInstr->FnCore.cArgs;
    17442221                    papszArgs[iArg] = NULL;
    17452222                    while (iArg-- > 0)
    17462223                        papszArgs[iArg] = papszShadowArgs[iArg] = xstrdup(pInstr->apszArgs[iArg]);
    17472224
    1748                     pchDst = pInstr->Core.pfnFunction(pchDst, (char **)&pInstr->apszArgs[0], pInstr->Core.pszFuncName);
    1749 
    1750                     iArg = pInstr->Core.cArgs;
     2225                    pchDst = pInstr->FnCore.pfnFunction(pchDst, (char **)&pInstr->apszArgs[0], pInstr->FnCore.pszFuncName);
     2226
     2227                    iArg = pInstr->FnCore.cArgs;
    17512228                    while (iArg-- > 0)
    17522229                        free(papszShadowArgs[iArg]);
     
    17542231                }
    17552232
    1756                 pInstrCore = pInstr->Core.pNext;
     2233                pInstrCore = pInstr->FnCore.pNext;
    17572234                break;
    17582235            }
     
    17612238            {
    17622239                PKMKCCEXPDYNFUNC pInstr = (PKMKCCEXPDYNFUNC)pInstrCore;
    1763                 char           **papszArgsShadow = xmalloc( (pInstr->Core.cArgs * 2 + 1) * sizeof(char *));
    1764                 char           **papszArgs = &papszArgsShadow[pInstr->Core.cArgs];
     2240                char           **papszArgsShadow = xmalloc( (pInstr->FnCore.cArgs * 2 + 1) * sizeof(char *));
     2241                char           **papszArgs = &papszArgsShadow[pInstr->FnCore.cArgs];
    17652242                uint32_t         iArg;
    17662243
    1767                 if (!pInstr->Core.fDirty)
     2244                if (!pInstr->FnCore.fDirty)
    17682245                {
    17692246#ifdef KMK_CC_STRICT
     
    17712248                    uint32_t    uCrcAfter = 0;
    17722249#endif
    1773                     iArg = pInstr->Core.cArgs;
     2250                    iArg = pInstr->FnCore.cArgs;
    17742251                    papszArgs[iArg] = NULL;
    17752252                    while (iArg-- > 0)
    17762253                    {
    17772254                        char *pszArg;
    1778                         if (!pInstr->aArgs[iArg].fPlain)
    1779                             pszArg = kmk_exec_expand_subprog_to_tmp(&pInstr->aArgs[iArg].u.SubProg, NULL);
     2255                        if (pInstr->aArgs[iArg].fSubprog)
     2256                            pszArg = kmk_exec_expand_subprog_to_tmp(&pInstr->aArgs[iArg].u.Subprog, NULL);
    17802257                        else
    1781                             pszArg = (char *)pInstr->aArgs[iArg].u.Plain.pszArg;
     2258                            pszArg = (char *)pInstr->aArgs[iArg].u.Plain.psz;
    17822259                        papszArgsShadow[iArg] = pszArg;
    17832260                        papszArgs[iArg]       = pszArg;
     
    17862263#endif
    17872264                    }
    1788                     pchDst = pInstr->Core.pfnFunction(pchDst, papszArgs, pInstr->Core.pszFuncName);
    1789 
    1790                     iArg = pInstr->Core.cArgs;
     2265                    pchDst = pInstr->FnCore.pfnFunction(pchDst, papszArgs, pInstr->FnCore.pszFuncName);
     2266
     2267                    iArg = pInstr->FnCore.cArgs;
    17912268                    while (iArg-- > 0)
    17922269                    {
     
    17952272                        uCrcAfter = kmk_cc_debug_string_hash(uCrcAfter, papszArgsShadow[iArg]);
    17962273#endif
    1797                         if (!pInstr->aArgs[iArg].fPlain)
     2274                        if (pInstr->aArgs[iArg].fSubprog)
    17982275                            free(papszArgsShadow[iArg]);
    17992276                    }
     
    18022279                else
    18032280                {
    1804                     iArg = pInstr->Core.cArgs;
     2281                    iArg = pInstr->FnCore.cArgs;
    18052282                    papszArgs[iArg] = NULL;
    18062283                    while (iArg-- > 0)
    18072284                    {
    18082285                        char *pszArg;
    1809                         if (!pInstr->aArgs[iArg].fPlain)
    1810                             pszArg = kmk_exec_expand_subprog_to_tmp(&pInstr->aArgs[iArg].u.SubProg, NULL);
     2286                        if (pInstr->aArgs[iArg].fSubprog)
     2287                            pszArg = kmk_exec_expand_subprog_to_tmp(&pInstr->aArgs[iArg].u.Subprog, NULL);
    18112288                        else
    1812                             pszArg = xstrdup(pInstr->aArgs[iArg].u.Plain.pszArg);
     2289                            pszArg = xstrdup(pInstr->aArgs[iArg].u.Plain.psz);
    18132290                        papszArgsShadow[iArg] = pszArg;
    18142291                        papszArgs[iArg]       = pszArg;
    18152292                    }
    18162293
    1817                     pchDst = pInstr->Core.pfnFunction(pchDst, papszArgs, pInstr->Core.pszFuncName);
    1818 
    1819                     iArg = pInstr->Core.cArgs;
     2294                    pchDst = pInstr->FnCore.pfnFunction(pchDst, papszArgs, pInstr->FnCore.pszFuncName);
     2295
     2296                    iArg = pInstr->FnCore.cArgs;
    18202297                    while (iArg-- > 0)
    18212298                        free(papszArgsShadow[iArg]);
     
    18232300                free(papszArgsShadow);
    18242301
    1825                 pInstrCore = pInstr->Core.pNext;
     2302                pInstrCore = pInstr->FnCore.pNext;
    18262303                break;
    18272304            }
     
    18632340
    18642341/**
    1865  * Execute a string expansion sub-program, outputting to a new heap buffer.
     2342 * Execute a string expansion subprogram, outputting to a new heap buffer.
    18662343 *
    18672344 * @returns Pointer to the output buffer (hand to free when done).
    1868  * @param   pSubProg          The sub-program to execute.
     2345 * @param   pSubProg          The subprogram to execute.
    18692346 * @param   pcchResult        Where to return the size of the result. Optional.
    18702347 */
     
    18792356    /*
    18802357     * Temporarily replace the variable buffer while executing the instruction
    1881      * stream for this sub program.
     2358     * stream for this subprogram.
    18822359     */
    18832360    pchDst = install_variable_buffer_with_hint(&pchOldVarBuf, &cbOldVarBuf,
     
    19382415
    19392416/**
    1940  * Equivalent of eval_buffer, only it's using the evalprog of the variable.
    1941  *
    1942  * @param   pVar        Pointer to the variable. Must have a program.
    1943  */
    1944 void kmk_exec_evalval(struct variable *pVar)
    1945 {
    1946     KMK_CC_ASSERT(pVar->evalprog);
    1947     assert(0);
    1948 }
    1949 
    1950 
    1951 /**
    19522417 * Expands a variable into a variable buffer using its expandprog.
    19532418 *
     
    19622427    return kmk_exec_expand_prog_to_var_buf(pVar->expandprog, pchDst);
    19632428}
     2429
     2430
     2431
     2432
     2433
     2434/*
     2435 *
     2436 * Makefile evaluation programs.
     2437 * Makefile evaluation programs.
     2438 * Makefile evaluation programs.
     2439 *
     2440 */
     2441/*#define KMK_CC_EVAL_ENABLE*/
     2442
     2443
     2444/**
     2445 * Compiles a variable direct evaluation as is, setting v->evalprog on success.
     2446 *
     2447 * @returns Pointer to the program on success, NULL if no program was created.
     2448 * @param   pVar        Pointer to the variable.
     2449 */
     2450struct kmk_cc_evalprog   *kmk_cc_compile_variable_for_eval(struct variable *pVar)
     2451{
     2452    return NULL;
     2453}
     2454
     2455
     2456/**
     2457 * Compiles a makefile for
     2458 *
     2459 * @returns Pointer to the program on success, NULL if no program was created.
     2460 * @param   pVar        Pointer to the variable.
     2461 */
     2462struct kmk_cc_evalprog   *kmk_cc_compile_file_for_eval(FILE *pFile, const char *pszFilename)
     2463{
     2464#ifdef KMK_CC_EVAL_ENABLE
     2465    /*
     2466     * Read the entire file into a zero terminate memory buffer.
     2467     */
     2468    size_t      cchContent = 0;
     2469    char       *pszContent = NULL;
     2470    struct stat st;
     2471    if (!fstat(fileno(pFile), &st))
     2472    {
     2473        if (   st.st_size > (off_t)16*1024*1024
     2474            && st.st_size < 0)
     2475            fatal(NULL, _("Makefile too large to compile: %ld bytes (%#lx) - max 16MB"), (long)st.st_size, (long)st.st_size);
     2476        cchContent = (size_t)st.st_size;
     2477        pszContent = (char *)xmalloc(cchContent + 1);
     2478
     2479        cchContent = fread(pszContent, 1, cchContent, pFile);
     2480        if (ferror(pFile))
     2481            fatal(NULL, _("Read error: %s"), strerror(errno));
     2482    }
     2483    else
     2484    {
     2485        size_t cbAllocated = 2048;
     2486        do
     2487        {
     2488            cbAllocated *= 2;
     2489            if (cbAllocated > 16*1024*1024)
     2490                fatal(NULL, _("Makefile too large to compile: max 16MB"));
     2491            pszContent = (char *)xrealloc(pszContent, cbAllocated);
     2492            cchContent += fread(&pszContent[cchContent], 1, cbAllocated - 1 - cchContent, pFile);
     2493            if (ferror(pFile))
     2494                fatal(NULL, _("Read error: %s"), strerror(errno));
     2495        } while (!feof(pFile));
     2496    }
     2497    pszContent[cchContent] = '\0';
     2498
     2499    /*
     2500     * Call common function to do the compilation.
     2501     */
     2502    //kmk_cc_eval_compile_common()
     2503
     2504    free(pszContent);
     2505    return NULL;
     2506#else
     2507    return NULL;
     2508#endif
     2509}
     2510
     2511
     2512/**
     2513 * Equivalent of eval_buffer, only it's using the evalprog of the variable.
     2514 *
     2515 * @param   pVar        Pointer to the variable. Must have a program.
     2516 */
     2517void kmk_exec_eval_variable(struct variable *pVar)
     2518{
     2519    KMK_CC_ASSERT(pVar->evalprog);
     2520    assert(0);
     2521}
     2522
     2523
     2524/**
     2525 * Worker for eval_makefile.
     2526 *
     2527 * @param   pEvalProg   The program pointer.
     2528 */
     2529void kmk_exec_eval_file(struct kmk_cc_evalprog *pEvalProg)
     2530{
     2531    KMK_CC_ASSERT(pEvalProg);
     2532    assert(0);
     2533}
     2534
     2535
     2536
     2537/*
     2538 *
     2539 * Program destruction hooks.
     2540 * Program destruction hooks.
     2541 * Program destruction hooks.
     2542 *
     2543 */
    19642544
    19652545
     
    20242604
    20252605
     2606
     2607
     2608
     2609
     2610
    20262611#endif /* CONFIG_WITH_COMPILER */
    20272612
  • trunk/src/kmk/kmk_cc_exec.h

    r2773 r2788  
    2828#ifdef CONFIG_WITH_COMPILER
    2929
     30#include <stdio.h>
    3031
    3132
     
    3435
    3536struct variable;
     37extern struct kmk_cc_expandprog *kmk_cc_compile_variable_for_expand(struct variable *pVar);
    3638extern struct kmk_cc_evalprog   *kmk_cc_compile_variable_for_eval(struct variable *pVar);
    37 extern struct kmk_cc_expandprog *kmk_cc_compile_variable_for_expand(struct variable *pVar);
     39extern struct kmk_cc_evalprog   *kmk_cc_compile_file_for_eval(FILE *pFile, const char *pszFilename);
    3840extern char *kmk_exec_expand_to_var_buf(struct variable *pVar, char *pchDst);
    39 extern void kmk_exec_evalval(struct variable *pVar);
     41extern void kmk_exec_eval_file(struct kmk_cc_evalprog *pProg);
     42extern void kmk_exec_eval_variable(struct variable *pVar);
    4043extern void kmk_cc_variable_changed(struct variable *pVar);
    4144extern void kmk_cc_variable_deleted(struct variable *pVar);
  • trunk/src/kmk/main.c

    r2771 r2788  
    38493849  printf (_("\n# Make statistics, printed on %s"), ctime (&when));
    38503850
    3851   print_variable_stats ();
    3852   print_file_stats ();
    3853 # ifdef KMK
    3854   print_kbuild_define_stats ();
    3855 # endif
     3851  /* Aallocators: */
    38563852# ifndef CONFIG_WITH_STRCACHE2
    38573853  strcache_print_stats ("#");
     
    38633859# endif
    38643860  print_heap_stats ();
     3861
     3862  /* Make stuff: */
     3863  print_variable_stats ();
     3864  print_file_stats ();
     3865# ifdef KMK
     3866  print_kbuild_define_stats ();
     3867# endif
     3868# ifdef CONFIG_WITH_COMPILER
     3869  kmk_cc_print_stats ();
     3870# endif
    38653871
    38663872  when = time ((time_t *) 0);
  • trunk/src/kmk/read.c

    r2770 r2788  
    500500  do_variable_definition (&ebuf.floc, "MAKEFILE_LIST", filename, o_file,
    501501                          f_append, 0);
     502
     503#ifdef CONFIG_WITH_COMPILER
     504  /* Execute compiled version if repeatedly evaluating this file.
     505     ASSUMES file content is unmodified since compilation. */
     506  deps->file->eval_count++;
     507  if (   deps->file->evalprog
     508      || (   deps->file->eval_count == 3
     509          && (deps->file->evalprog = kmk_cc_compile_file_for_eval (ebuf.fp, filename)) != NULL) )
     510    {
     511      curfile = reading_file;
     512      reading_file = &ebuf.floc;
     513
     514      kmk_exec_eval_file (deps->file->evalprog);
     515
     516      reading_file = curfile;
     517      fclose (ebuf.fp);
     518      alloca (0);
     519      return 1;
     520    }
     521#elif defined (CONFIG_WITH_MAKE_STATS)
     522  deps->file->eval_count++;
     523#endif
    502524
    503525#ifdef KMK
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette