Changeset 2718 for trunk/src/kmk


Ignore:
Timestamp:
Dec 30, 2013, 10:30:47 PM (12 years ago)
Author:
bird
Message:

kmk: Variable aliases.

Location:
trunk/src/kmk
Files:
4 edited

Legend:

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

    r2717 r2718  
    284284        && g_fKbObjCompMode)
    285285    {
    286         size_t  cchPrefixed = pObj->cchVarPrefix + cchName;
    287         char   *pszPrefixed = xmalloc(cchPrefixed + 1);
     286        struct variable *pAlias;
     287        size_t           cchPrefixed = pObj->cchVarPrefix + cchName;
     288        char            *pszPrefixed = xmalloc(cchPrefixed + 1);
    288289        memcpy(pszPrefixed, pObj->pszVarPrefix, pObj->cchVarPrefix);
    289290        memcpy(&pszPrefixed[pObj->cchVarPrefix], pszName, cchName);
    290291        pszPrefixed[cchPrefixed] = '\0';
    291292
    292         /** @todo implement variable aliases or something. */
    293         define_variable_in_set(pszPrefixed, cchPrefixed,
    294                                pchValue, cchValue, 1 /*duplicate_value*/,
    295                                enmOrigin, fRecursive,
    296                                &global_variable_set,
    297                                pFileLoc);
     293        pAlias = define_variable_alias_in_set(pszPrefixed, cchPrefixed, pVar, enmOrigin,
     294                                              &global_variable_set, pFileLoc);
     295        if (!pAlias->alias)
     296            error(pFileLoc, _("Error defining alias '%s'"), pszPrefixed);
    298297    }
    299298
  • trunk/src/kmk/testcase-kBuild-define.kmk

    r2717 r2718  
    9292[target@OutsideMod]_OTHER   = outside-value
    9393$(if-expr "$([target@OutsideMod]_SOURCES)" == "file2.c file3.c file4.c",,$(error [target@OutsideMod]_SOURCES is '$([target@OutsideMod]_SOURCES)' not 'file2.c file3.c file4.c'))
    94 $(if-expr "OutsideMod_SOURCES"             == "file2.c file3.c file4.c",,$(error OutsideMod_SOURCES is '$(OutsideMod_SOURCES)' not 'file2.c file3.c file4.c'))
     94$(if-expr "$(OutsideMod_SOURCES)"          == "file2.c file3.c file4.c",,$(error OutsideMod_SOURCES is '$(OutsideMod_SOURCES)' not 'file2.c file3.c file4.c'))
    9595
    9696$(if-expr "$([target@OutsideMod]_OTHER)" == "outside-value",,$(error [target@OutsideMod]_OTHER is '$([target@OutsideMod]_OTHER)' not 'outside-value'))
  • trunk/src/kmk/variable.c

    r2717 r2718  
    4242# include <stddef.h>
    4343#endif
     44
     45#ifdef KMK
     46/** Gets the real variable if alias.  For use when looking up variables. */
     47# define RESOLVE_ALIAS_VARIABLE(v) \
     48  do { \
     49    if ((v) != NULL && (v)->alias) \
     50      { \
     51        (v) = (struct variable *)(v)->value; \
     52        assert ((v)->aliased); \
     53        assert (!(v)->alias); \
     54      } \
     55  } while (0)
     56#endif
     57
    4458
    4559/* Chain of all pattern-specific variables.  */
     
    308322  if (! HASH_VACANT (v))
    309323    {
     324#ifdef KMK
     325      RESOLVE_ALIAS_VARIABLE(v);
     326#endif
    310327      if (env_overrides && v->origin == o_env)
    311328        /* V came from in the environment.  Since it was defined
     
    423440  v->append = 0;
    424441  v->private_var = 0;
     442#ifdef KMK
     443  v->alias = 0;
     444  v->aliased = 0;
     445#endif
    425446  v->export = v_default;
    426447  MAKE_STATS_2(v->changes = 0);
     
    489510  if (! HASH_VACANT (v))
    490511    {
     512#ifdef KMK
     513      if (v->aliased || v->alias)
     514        {
     515           if (v->aliased)
     516             error (NULL, _("Cannot undefine the aliased variable '%s'"), v->name);
     517           else
     518             error (NULL, _("Cannot undefine the variable alias '%s'"), v->name);
     519          return;
     520        }
     521#endif
     522
    491523      if (env_overrides && v->origin == o_env)
    492524        /* V came from in the environment.  Since it was defined
     
    507539    }
    508540}
     541
     542#ifdef KMK
     543/* Define variable named NAME as an alias of the variable TARGET.
     544   SET defaults to the global set if NULL. FLOCP is just for completeness. */
     545
     546struct variable *
     547define_variable_alias_in_set (const char *name, unsigned int length,
     548                              struct variable *target, enum variable_origin origin,
     549                              struct variable_set *set, const struct floc *flocp)
     550{
     551  struct variable     *v;
     552  struct variable     **var_slot;
     553
     554  /* Look it up the hash table slot for it. */
     555  name = strcache2_add (&variable_strcache, name, length);
     556  if (   set != &global_variable_set
     557      || !(v = strcache2_get_user_val (&variable_strcache, name)))
     558    {
     559      struct variable var_key;
     560
     561      var_key.name = name;
     562      var_key.length = length;
     563      var_slot = (struct variable **) hash_find_slot_strcached (&set->table, &var_key);
     564      v = *var_slot;
     565    }
     566  else
     567    {
     568      assert (!v || (v->name == name && !HASH_VACANT (v)));
     569      var_slot = 0;
     570    }
     571  if (! HASH_VACANT (v))
     572    {
     573      /* A variable of this name is already defined.
     574         If the old definition is from a stronger source
     575         than this one, don't redefine it.  */
     576
     577      if (env_overrides && v->origin == o_env)
     578        /* V came from in the environment.  Since it was defined
     579           before the switches were parsed, it wasn't affected by -e.  */
     580        v->origin = o_env_override;
     581
     582      if ((int) origin < (int) v->origin)
     583        return v;
     584
     585      if (v->value != 0 && !v->rdonly_val)
     586          free (v->value);
     587      MAKE_STATS_2(v->changes++);
     588    }
     589  else
     590    {
     591      /* Create a new variable definition and add it to the hash table.  */
     592      v = alloccache_alloc (&variable_cache);
     593      v->name = name; /* already cached. */
     594      v->length = length;
     595      hash_insert_at (&set->table, v, var_slot);
     596      v->special = 0;
     597      v->expanding = 0;
     598      v->exp_count = 0;
     599      v->per_target = 0;
     600      v->append = 0;
     601      v->private_var = 0;
     602      v->aliased = 0;
     603      v->export = v_default;
     604      MAKE_STATS_2(v->changes = 0);
     605      MAKE_STATS_2(v->reallocs = 0);
     606      v->exportable = 1;
     607      if (*name != '_' && (*name < 'A' || *name > 'Z')
     608          && (*name < 'a' || *name > 'z'))
     609        v->exportable = 0;
     610      else
     611        {
     612          for (++name; *name != '\0'; ++name)
     613            if (*name != '_' && (*name < 'a' || *name > 'z')
     614                && (*name < 'A' || *name > 'Z') && !ISDIGIT(*name))
     615              break;
     616
     617          if (*name != '\0')
     618            v->exportable = 0;
     619        }
     620
     621     /* If it's the global set, remember the variable. */
     622     if (set == &global_variable_set)
     623       strcache2_set_user_val (&variable_strcache, v->name, v);
     624    }
     625
     626  /* Common variable setup. */
     627  v->alias = 1;
     628  v->rdonly_val = 1;
     629  v->value = (char *)target;
     630  v->value_length = sizeof(*target); /* Non-zero to provoke trouble. */
     631  v->value_alloc_len = sizeof(*target);
     632  if (flocp != 0)
     633    v->fileinfo = *flocp;
     634  else
     635    v->fileinfo.filenm = 0;
     636  v->origin = origin;
     637  v->recursive = 0;
     638
     639  /* Mark the target as aliased. */
     640  target->aliased = 1;
     641
     642  return v;
     643}
     644#endif /* KMK */
    509645
    510646/* If the variable passed in is "special", handle its special nature.
     
    785921# endif /* CONFIG_WITH_STRCACHE2 */
    786922      if (v && (!is_parent || !v->private_var))
    787         return v->special ? lookup_special_var (v) : v;
     923        {
     924# ifdef KMK
     925          RESOLVE_ALIAS_VARIABLE(v);
     926# endif
     927          return v->special ? lookup_special_var (v) : v;
     928        }
    788929
    789930      is_parent |= setlist->next_is_parent;
     
    8691010{
    8701011  struct variable var_key;
     1012#ifdef KMK
     1013  struct variable *v;
     1014#endif
    8711015#ifndef CONFIG_WITH_STRCACHE2
    8721016  var_key.name = (char *) name;
     
    8831027      struct variable *v = lookup_kbuild_object_variable_accessor(name, length);
    8841028      if (v != VAR_NOT_KBUILD_ACCESSOR)
    885         return v;
     1029        {
     1030          RESOLVE_ALIAS_VARIABLE(v);
     1031          return v;
     1032        }
    8861033    }
    8871034# endif
     
    8951042  if (set == &global_variable_set)
    8961043    {
    897       struct variable *v;
    8981044      v = strcache2_get_user_val (&variable_strcache, cached_name);
    8991045      assert (!v || v->name == cached_name);
    900       return v;
    901     }
    902 
    903   var_key.name = cached_name;
    904   var_key.length = length;
    905 
    906   return (struct variable *) hash_find_item_strcached (
    907     (struct hash_table *) &set->table, &var_key);
     1046    }
     1047  else
     1048    {
     1049      var_key.name = cached_name;
     1050      var_key.length = length;
     1051
     1052      v = (struct variable *) hash_find_item_strcached (
     1053        (struct hash_table *) &set->table, &var_key);
     1054    }
     1055# ifdef KMK
     1056  RESOLVE_ALIAS_VARIABLE(v);
     1057# endif
     1058  return v;
    9081059#endif /* CONFIG_WITH_STRCACHE2 */
    9091060}
     
    11961347          {
    11971348            /* GKM FIXME: delete in from_set->table */
    1198             free (from_var->value);
     1349#ifdef KMK
     1350            if (from_var->aliased)
     1351              fatal(NULL, ("Attempting to delete aliased variable '%s'"), from_var->name);
     1352            if (from_var->alias)
     1353              fatal(NULL, ("Attempting to delete variable aliased '%s'"), from_var->name);
     1354#endif
     1355#ifdef CONFIG_WITH_RDONLY_VARIABLE_VALUE
     1356            if (!from_var->rdonly_val)
     1357#endif
     1358              free (from_var->value);
    11991359            free (from_var);
    12001360          }
     
    18912051  unsigned int new_value_len = value_len + (v->value_length != 0 ? 1 + v->value_length : 0);
    18922052  int done_1st_prepend_copy = 0;
     2053#ifdef KMK
     2054  assert (!v->alias);
     2055#endif
    18932056
    18942057  /* Drop empty strings. Use $(NO_SUCH_VARIABLE) if a space is wanted. */
     
    26072770  const char *prefix = arg;
    26082771  const char *origin;
     2772#ifdef KMK
     2773  const struct variable *alias = v;
     2774  RESOLVE_ALIAS_VARIABLE(v);
     2775#endif
    26092776
    26102777  switch (v->origin)
     
    26442811  if (v->private_var)
    26452812    fputs (" private", stdout);
     2813#ifndef KMK
    26462814  if (v->fileinfo.filenm)
    26472815    printf (_(" (from `%s', line %lu)"),
    26482816            v->fileinfo.filenm, v->fileinfo.lineno);
     2817#else  /* KMK */
     2818  if (alias->fileinfo.filenm)
     2819    printf (_(" (from '%s', line %lu)"),
     2820            alias->fileinfo.filenm, alias->fileinfo.lineno);
     2821  if (alias->aliased)
     2822    fputs (" aliased", stdout);
     2823  if (alias->alias)
     2824    printf (_(", alias for '%s'"), v->name);
     2825#endif /* KMK */
     2826
    26492827#ifdef CONFIG_WITH_MAKE_STATS
    26502828  if (v->changes != 0)
     
    26692847  /* Is this a `define'?  */
    26702848  if (v->recursive && strchr (v->value, '\n') != 0)
     2849#ifndef KMK /** @todo language feature for aliases */
    26712850    printf ("define %s\n%s\nendef\n", v->name, v->value);
     2851#else
     2852    printf ("define %s\n%s\nendef\n", alias->name, v->value);
     2853#endif
    26722854  else
    26732855    {
    26742856      char *p;
    26752857
     2858#ifndef KMK /** @todo language feature for aliases */
    26762859      printf ("%s %s= ", v->name, v->recursive ? v->append ? "+" : "" : ":");
     2860#else
     2861      printf ("%s %s= ", alias->name, v->recursive ? v->append ? "+" : "" : ":");
     2862#endif
    26772863
    26782864      /* Check if the value is just whitespace.  */
  • trunk/src/kmk/variable.h

    r2717 r2718  
    8989#ifdef CONFIG_WITH_RDONLY_VARIABLE_VALUE
    9090    unsigned int rdonly_val:1;  /* VALUE is read only (strcache/const). */
     91#endif
     92#ifdef KMK
     93    unsigned int alias:1;       /* Nonzero if alias. VALUE points to the real variable. */
     94    unsigned int aliased:1;     /* Nonzero if aliased. Cannot be undefined. */
    9195#endif
    9296    enum variable_flavor
     
    450454          undefine_variable_in_set((n),(l),(o),NULL)
    451455
     456#ifdef KMK
     457struct variable *
     458define_variable_alias_in_set (const char *name, unsigned int length,
     459                              struct variable *target, enum variable_origin origin,
     460                              struct variable_set *set, const struct floc *flocp);
     461#endif
     462
    452463/* Warn that NAME is an undefined variable.  */
    453464
Note: See TracChangeset for help on using the changeset viewer.