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

kmk: Variable aliases.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • 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.  */
Note: See TracChangeset for help on using the changeset viewer.