VirtualBox

Changeset 2549 in kBuild


Ignore:
Timestamp:
Nov 9, 2011 1:22:04 AM (13 years ago)
Author:
bird
Message:

kmk: hacking on a new kmk/kBuild language extension...

Location:
trunk/src/kmk
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/kmk/kbuild-read.c

    r2548 r2549  
    7676    /** The kind of define. */
    7777    enum kBuildDef              enmKind;
    78     /** Pointer to the element below us on the stack. */
    79     struct kbuild_eval_data    *pDown;
    80 
    8178    /** The bare name of the define. */
    8279    char                       *pszName;
     80    /** The file location where this define was declared. */
     81    struct floc                 FileLoc;
     82
     83    /** Pointer to the next element in the global list. */
     84    struct kbuild_eval_data    *pGlobalNext;
     85    /** Pointer to the element below us on the stack. */
     86    struct kbuild_eval_data    *pStackDown;
     87
     88    /** The variable set associated with this define. */
     89    struct variable_set_list   *pVariables;
     90    /** The saved current variable set, for restoring in kBuild-endef. */
     91    struct variable_set_list   *pVariablesSaved;
    8392
    8493    /** The parent name, NULL if none. */
     
    8695    /** The inheritance method. */
    8796    enum kBuildExtendBy         enmExtendBy;
     97    /** Pointer to the parent. Resolved lazily, so it can be NULL even if we have
     98     *  a parent. */
     99    struct kbuild_eval_data    *pParent;
    88100
    89101    /** The template, NULL if none. Only applicable to targets. */
    90102    char                       *pszTemplate;
    91 
    92     /** The variable prefix*/
     103    /** Pointer to the template. Resolved lazily, so it can be NULL even if we have
     104     *  a parent. */
     105    struct kbuild_eval_data    *pTemplate;
     106
     107    /** The variable prefix.  */
    93108    char                       *pszVarPrefix;
    94109    /** The length of the variable prefix. */
    95110    size_t                      cchVarPrefix;
    96111};
     112
     113
     114/*******************************************************************************
     115*   Header Files                                                               *
     116*******************************************************************************/
     117/** Linked list (LIFO) of kBuild defines.
     118 * @todo use a hash! */
     119struct kbuild_eval_data *g_pHeadKbDefs = NULL;
     120/** Stack of kBuild defines. */
     121struct kbuild_eval_data *g_pTopKbDef = NULL;
     122
     123
     124struct variable_set *
     125get_top_kbuild_variable_set(void)
     126{
     127    struct kbuild_eval_data *pTop = g_pTopKbDef;
     128    assert(pTop != NULL);
     129    return pTop->pVariables->set;
     130}
     131
     132
     133char *
     134kbuild_prefix_variable(const char *pszName, unsigned int *pcchName)
     135{
     136    struct kbuild_eval_data *pTop = g_pTopKbDef;
     137    char        *pszPrefixed;
     138    unsigned int cchPrefixed;
     139
     140    assert(pTop != NULL);
     141
     142    cchPrefixed = pTop->cchVarPrefix + *pcchName;
     143    pszPrefixed = xmalloc(cchPrefixed + 1);
     144    memcpy(pszPrefixed, pTop->pszVarPrefix, pTop->cchVarPrefix);
     145    memcpy(&pszPrefixed[pTop->cchVarPrefix], pszName, *pcchName);
     146    pszPrefixed[cchPrefixed] = '\0';
     147    *pcchName = cchPrefixed;
     148    return pszPrefixed;
     149}
    97150
    98151
     
    112165}
    113166
     167static char *
     168allocate_expanded_next_token(const char **ppszCursor, const char *pszEos, unsigned int *pcchToken, int fStrip)
     169{
     170    unsigned int cchToken;
     171    char *pszToken = find_next_token_eos(ppszCursor, pszEos, &cchToken);
     172    if (pszToken)
     173    {
     174        pszToken = allocated_variable_expand_2(pszToken, cchToken, &cchToken);
     175        if (pszToken)
     176        {
     177            if (fStrip)
     178            {
     179                unsigned int off = 0;
     180                while (MY_IS_BLANK(pszToken[off]))
     181                    off++;
     182                if (off)
     183                {
     184                    cchToken -= off;
     185                    memmove(pszToken, &pszToken[off], cchToken + 1);
     186                }
     187
     188                while (cchToken > 0 && MY_IS_BLANK(pszToken[cchToken - 1]))
     189                    pszToken[--cchToken] = '\0';
     190            }
     191
     192            assert(cchToken == strlen(pszToken));
     193            if (pcchToken)
     194                *pcchToken = cchToken;
     195        }
     196    }
     197    return pszToken;
     198}
     199
     200static struct kbuild_eval_data *
     201eval_kbuild_resolve_parent(struct kbuild_eval_data *pData)
     202{
     203    if (   !pData->pParent
     204        && pData->pszParent)
     205    {
     206        struct kbuild_eval_data *pCur = g_pHeadKbDefs;
     207        while (pCur)
     208        {
     209            if (   pCur->enmKind == pData->enmKind
     210                && !strcmp(pCur->pszName, pData->pszParent))
     211            {
     212                if (    pCur->pszParent
     213                    &&  (   pCur->pParent == pData
     214                         || !strcmp(pCur->pszParent, pData->pszName)) )
     215                    fatal(&pData->FileLoc, _("'%s' and '%s' are both trying to be each other children..."),
     216                          pData->pszName, pCur->pszName);
     217
     218                pData->pParent = pCur;
     219                pData->pVariables->next = pData->pVariables;
     220                break;
     221            }
     222            pCur = pCur->pGlobalNext;
     223        }
     224    }
     225    return pData->pParent;
     226}
    114227
    115228static int
     
    117230                        const char *pszLine, const char *pszEos, int fIgnoring, enum kBuildDef enmKind)
    118231{
    119     unsigned int             cch;
    120     char                    *psz;
     232    unsigned int            cch;
     233    unsigned int            cchName;
     234    char                    ch;
     235    char                   *psz;
     236    const char             *pszPrefix;
    121237    struct kbuild_eval_data *pData;
    122238
    123     /*
    124      * Create a new kBuild eval data item unless we're in ignore-mode.
    125      */
    126239    if (fIgnoring)
    127240        return 0;
    128241
     242    /*
     243     * Create a new kBuild eval data item.
     244     */
    129245    pData = xmalloc(sizeof(*pData));
    130     pData->enmKind      = enmKind;
    131     pData->pszName      = NULL;
    132     pData->pszParent    = NULL;
    133     pData->enmExtendBy  = kBuildExtendBy_NoParent;
    134     pData->pszTemplate  = NULL;
    135     pData->pszVarPrefix = NULL;
    136     pData->cchVarPrefix = 0;
    137     pData->pDown        = *ppData;
    138     *ppData             = pData;
     246    pData->enmKind          = enmKind;
     247    pData->pszName          = NULL;
     248    pData->FileLoc          = *pFileLoc;
     249
     250    pData->pGlobalNext      = g_pHeadKbDefs;
     251    g_pHeadKbDefs           = pData;
     252
     253    pData->pStackDown       = *ppData;
     254    *ppData = g_pTopKbDef   = pData;
     255    pData->pVariables       = create_new_variable_set();
     256    pData->pVariablesSaved  = NULL;
     257
     258    pData->pszParent        = NULL;
     259    pData->enmExtendBy      = kBuildExtendBy_NoParent;
     260    pData->pParent          = NULL;
     261
     262    pData->pszTemplate      = NULL;
     263    pData->pTemplate        = NULL;
     264
     265    pData->pszVarPrefix     = NULL;
     266    pData->cchVarPrefix     = 0;
    139267
    140268    /*
    141269     * The first word is the name.
    142270     */
    143     pData->pszName = find_next_token_eos(&pszLine, pszEos, &cch);
    144     if (!pData->pszName)
    145     {
    146         error(pFileLoc, _("The kBuild define requires a name"));
    147         return 0;
    148     }
    149     pData->pszName = allocated_variable_expand_2(pData->pszName, cch, &cch);
     271    pData->pszName = allocate_expanded_next_token(&pszLine, pszEos, &cchName, 1 /*strip*/);
     272    if (!pData->pszName || !*pData->pszName)
     273        fatal(pFileLoc, _("The kBuild define requires a name"));
     274
     275    psz = pData->pszName;
     276    while ((ch = *psz++) != '\0')
     277        if (!isgraph(ch))
     278        {
     279            error(pFileLoc, _("The 'kBuild-define-%s' name '%s' contains one or more invalid characters"),
     280                  eval_kbuild_kind_to_string(enmKind), pData->pszName);
     281            break;
     282        }
    150283
    151284    /*
     
    160293            if (pData->pszParent != NULL)
    161294                fatal(pFileLoc, _("'extending' can only occure once"));
    162             pData->pszParent = find_next_token_eos(&pszLine, pszEos, &cch);
    163             if (pData->pszParent)
    164                 pData->pszParent = allocated_variable_expand_2(pData->pszParent, cch, &cch);
     295            pData->pszParent = allocate_expanded_next_token(&pszLine, pszEos, &cch, 1 /*strip*/);
    165296            if (!pData->pszParent || !*pData->pszParent)
    166297                fatal(pFileLoc, _("'extending' requires a parent name"));
     
    187318            }
    188319        }
    189         else if (   WORD_IS(psz, cch, "using")
    190                  && enmKind == kBuildDef_Tool)
     320        else if (WORD_IS(psz, cch, "using"))
    191321        {
    192322            /* Template directive. */
    193             if (pData->pszTemplate != NULL )
     323            if (enmKind != kBuildDef_Tool)
     324                fatal(pFileLoc, _("'using <template>' can only be used with 'kBuild-define-target'"));
     325            if (pData->pszTemplate != NULL)
    194326                fatal(pFileLoc, _("'using' can only occure once"));
    195             pData->pszTemplate = find_next_token_eos(&pszLine, pszEos, &cch);
    196             if (pData->pszTemplate)
    197                 pData->pszTemplate = allocated_variable_expand_2(pData->pszTemplate, cch, &cch);
     327
     328            pData->pszTemplate = allocate_expanded_next_token(&pszLine, pszEos, &cch, 1 /*fStrip*/);
    198329            if (!pData->pszTemplate || !*pData->pszTemplate)
    199330                fatal(pFileLoc, _("'using' requires a template name"));
     
    209340     * Calc the variable prefix.
    210341     */
    211 
    212     /** @todo continue here...  */
    213 
     342    switch (enmKind)
     343    {
     344        case kBuildDef_Target:      pszPrefix = ""; break;
     345        case kBuildDef_Template:    pszPrefix = "TEMPLATE_"; break;
     346        case kBuildDef_Tool:        pszPrefix = "TOOL_"; break;
     347        case kBuildDef_Sdk:         pszPrefix = "SDK_"; break;
     348        case kBuildDef_Unit:        pszPrefix = "UNIT_"; break;
     349        default:
     350            fatal(pFileLoc, _("enmKind=%d"), enmKind);
     351            return -1;
     352    }
     353    cch = strlen(pszPrefix);
     354    pData->cchVarPrefix = cch + cchName;
     355    pData->pszVarPrefix = xmalloc(pData->cchVarPrefix + 1);
     356    memcpy(pData->pszVarPrefix, pszPrefix, cch);
     357    memcpy(&pData->pszVarPrefix[cch], pData->pszName, cchName);
     358
     359    /*
     360     * Try resolve the parent and change the current variable set.
     361     */
     362    eval_kbuild_resolve_parent(pData);
     363    pData->pVariablesSaved = current_variable_set_list;
     364    current_variable_set_list = pData->pVariables;
    214365
    215366    return 0;
     
    242393     */
    243394    if (pData->enmKind != enmKind)
    244     {
    245395        error(pFileLoc, _("'kBuild-endef-%s' does not match 'kBuild-define-%s %s'"),
    246396              eval_kbuild_kind_to_string(enmKind), eval_kbuild_kind_to_string(pData->enmKind), pData->pszName);
    247         return 0;
    248     }
    249397
    250398    /*
     
    252400     * It should match the name given to the kBuild-define.
    253401     */
    254     pszName = find_next_token_eos(&pszLine, pszEos, &cchName);
     402    pszName = allocate_expanded_next_token(&pszLine, pszEos, &cchName, 1 /*fStrip*/);
    255403    if (pszName)
    256404    {
    257         pszName = allocated_variable_expand_2(pszName, cchName, &cchName);
    258405        if (strcmp(pszName, pData->pszName))
    259406            error(pFileLoc, _("'kBuild-endef-%s %s' does not match 'kBuild-define-%s %s'"),
     
    266413     * Pop a define off the stack.
    267414     */
    268     *ppData = pData->pDown;
    269     free(pData->pszName);
    270     free(pData->pszParent);
    271     free(pData->pszTemplate);
    272     free(pData->pszVarPrefix);
    273     free(pData);
     415    assert(pData == g_pTopKbDef);
     416    *ppData = g_pTopKbDef  = pData->pStackDown;
     417    pData->pStackDown      = NULL;
     418    current_variable_set_list = pData->pVariablesSaved;
     419    pData->pVariablesSaved = NULL;
    274420
    275421    return 0;
     
    326472}
    327473
     474void print_kbuild_data_base(void)
     475{
     476    struct kbuild_eval_data *pCur;
     477
     478    puts(_("\n# kBuild defines"));
     479
     480    for (pCur = g_pHeadKbDefs; pCur; pCur = pCur->pGlobalNext)
     481    {
     482        printf("\nkBuild-define-%s %s",
     483               eval_kbuild_kind_to_string(pCur->enmKind), pCur->pszName);
     484        if (pCur->pszParent)
     485        {
     486            printf(" extending %s", pCur->pszParent);
     487            switch (pCur->enmExtendBy)
     488            {
     489                case kBuildExtendBy_Overriding: break;
     490                case kBuildExtendBy_Appending:  printf(" by appending"); break;
     491                case kBuildExtendBy_Prepending: printf(" by prepending"); break;
     492                default:                        printf(" by ?!?");
     493            }
     494        }
     495        if (pCur->pszTemplate)
     496            printf(" using %s", pCur->pszTemplate);
     497        putchar('\n');
     498
     499        print_variable_set(pCur->pVariables->set, "");
     500
     501        printf("kBuild-endef-%s  %s\n",
     502               eval_kbuild_kind_to_string(pCur->enmKind), pCur->pszName);
     503    }
     504    /** @todo hash stats. */
     505}
     506
     507void print_kbuild_define_stats(void)
     508{
     509    /* later when hashing stuff */
     510}
     511
  • trunk/src/kmk/kbuild.h

    r2548 r2549  
    4040
    4141struct kbuild_eval_data;
     42extern struct kbuild_eval_data *g_pTopKbDef;
     43struct variable_set *get_top_kbuild_variable_set(void);
     44char *kbuild_prefix_variable(const char *pszName, unsigned int *pcchName);
    4245
    4346int eval_kbuild_define(struct kbuild_eval_data **kdata, const struct floc *flocp,
     
    4649                      const char *word, unsigned int wlen, const char *line, const char *eos, int ignoring);
    4750
     51void print_kbuild_data_base(void);
     52void print_kbuild_define_stats(void);
     53
    4854#endif
    4955
  • trunk/src/kmk/main.c

    r2546 r2549  
    37263726  print_file_data_base ();
    37273727  print_vpath_data_base ();
     3728#ifdef KMK
     3729  print_kbuild_data_base ();
     3730#endif
    37283731#ifndef CONFIG_WITH_STRCACHE2
    37293732  strcache_print_stats ("#");
     
    37503753  print_variable_stats ();
    37513754  print_file_stats ();
     3755# ifdef KMK
     3756  print_kbuild_define_stats ();
     3757# endif
    37523758# ifndef CONFIG_WITH_STRCACHE2
    37533759  strcache_print_stats ("#");
  • trunk/src/kmk/testcase-kBuild-define.kmk

    r2548 r2549  
    2929kBuild-define-target MyTarget
    3030
    31 TEMPLATE = MyTemplate
    32 SOURCES = MySourceFile.c
     31_TEMPLATE = MyTemplate
     32_SOURCES = MySourceFile.c
    3333
    3434kBuild-endef-target  MyTarget
     35$(if "$(MyTarget_TEMPLATE)" == "MyTemplate",,$(error MyTarget's _TEMPLATE wasn't set correctly in the global space))
     36$(if "$(MyTarget_SOURCES)" == "MySourceFile.c",,$(error MyTarget's _TEMPLATE wasn't set correctly in the global space))
    3537
    3638
     
    3840kBuild-define-target $(call INDIRECT_NAME, 2)
    3941
    40 TEMPLATE = MyTemplate2
    41 SOURCES = MySourceFile2.c
     42local _TEMPLATE = MyTemplate2
     43_SOURCES = MySourceFile2.c
    4244
    4345kBuild-endef-target  $(call INDIRECT_NAME, 2)
     46$(if "$(_TEMPLATE)" == "",,$(error _TEMPLATE has leaked out into the global space))
    4447
    4548
     
    4750
    4851all_recursive:
    49         $(ECHO) "kBuild-define-xxxx works fine"
     52        #$(ECHO) "kBuild-define-xxxx works fine"
    5053
    5154
  • trunk/src/kmk/variable.c

    r2548 r2549  
    215215  struct variable var_key;
    216216
     217#ifndef KMK
    217218  if (set == NULL)
    218219    set = &global_variable_set;
     220#else
     221  if (set == NULL)
     222    {
     223      /* underscore prefixed variables are automatically local in
     224         kBuild-define-* scopes.  They also get a global definition with
     225         the current scope prefix. */
     226      if (g_pTopKbDef && length > 0 && name[0] == '_')
     227        {
     228          char         *prefixed_nm;
     229          unsigned int  prefixed_nm_len;
     230
     231          set = get_top_kbuild_variable_set();
     232          v = define_variable_in_set(name, length, value, value_len,
     233                                     1 /* duplicate_value */,
     234                                     origin, recursive, set, flocp);
     235
     236          prefixed_nm_len = length;
     237          prefixed_nm = kbuild_prefix_variable(name, &prefixed_nm_len);
     238          define_variable_in_set(prefixed_nm, prefixed_nm_len,
     239                                 value, value_len, duplicate_value,
     240                                 origin, recursive, &global_variable_set,
     241                                 flocp);
     242          free(prefixed_nm);
     243          return v;
     244        }
     245      set = &global_variable_set;
     246    }
     247#endif
    219248
    220249#ifndef CONFIG_WITH_STRCACHE2
Note: See TracChangeset for help on using the changeset viewer.

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