Ignore:
Timestamp:
Jul 22, 2011, 1:12:06 PM (14 years ago)
Author:
bird
Message:

kmk: added $(firstdefined ) and $(lastdefined ).

File:
1 edited

Legend:

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

    r2462 r2489  
    10211021}
    10221022
     1023#ifdef CONFIG_WITH_DEFINED_FUNCTIONS
     1024
     1025/* Used by func_firstdefined and func_lastdefined to parse the optional last
     1026   argument.  Returns 0 if the variable name is to be returned and 1 if it's
     1027   the variable value value. */
     1028static int
     1029parse_value_name_argument (const char *arg1, const char *funcname)
     1030{
     1031  const char *end;
     1032  int rc;
     1033
     1034  if (arg1 == NULL)
     1035    return 0;
     1036
     1037  end = strchr (arg1, '\0');
     1038  strip_whitespace (&arg1, &end);
     1039
     1040  if (!strncmp (arg1, "name", end - arg1))
     1041    rc = 0;
     1042  else if (!strncmp (arg1, "value", end - arg1))
     1043    rc = 1;
     1044  else
     1045    {
     1046#if 0 /* FIXME: later */
     1047      /* check the expanded form */
     1048      char *exp = expand_argument (arg1, strchr (arg1, '\0'));
     1049      arg1 = exp;
     1050      end = strchr (arg1, '\0');
     1051      strip_whitespace (&arg1, &end);
     1052
     1053      if (!strncmp (arg1, "name", end - arg1))
     1054        rc = 0;
     1055      else if (!strncmp (arg1, "value", end - arg1))
     1056        rc = 1;
     1057      else
     1058#endif
     1059        fatal (*expanding_var,
     1060               _("second argument to `%s' function must be `name' or `value', not `%s'"),
     1061               funcname, exp);
     1062#if 0
     1063      free (exp);
     1064#endif
     1065    }
     1066
     1067  return rc;
     1068}
     1069
     1070/* Given a list of variable names (ARGV[0]), returned the first variable which
     1071   is defined (i.e. value is not empty).  ARGV[1] indicates whether to return
     1072   the variable name or its value. */
     1073static char *
     1074func_firstdefined (char *o, char **argv, const char *funcname)
     1075{
     1076  unsigned int i;
     1077  const char *words = argv[0];    /* Use a temp variable for find_next_token */
     1078  const char *p;
     1079  int ret_value = parse_value_name_argument (argv[1], funcname);
     1080
     1081  /* FIXME: Optimize by not expanding the arguments, but instead expand them
     1082     one by one here.  This will require a find_next_token variant which
     1083     takes `$(' and `)' into account. */
     1084  while ((p = find_next_token (&words, &i)) != NULL)
     1085    {
     1086      struct variable *v = lookup_variable (p, i);
     1087      if (v && v->value_length)
     1088        {
     1089          if (ret_value)
     1090            variable_expand_string_2 (o, v->value, v->value_length, &o);
     1091          else
     1092            o = variable_buffer_output (o, p, i);
     1093          break;
     1094        }
     1095    }
     1096
     1097  return o;
     1098}
     1099
     1100/* Given a list of variable names (ARGV[0]), returned the last variable which
     1101   is defined (i.e. value is not empty).  ARGV[1] indicates whether to return
     1102   the variable name or its value. */
     1103static char *
     1104func_lastdefined (char *o, char **argv, const char *funcname)
     1105{
     1106  struct variable *last_v = NULL;
     1107  unsigned int i;
     1108  const char *words = argv[0];    /* Use a temp variable for find_next_token */
     1109  const char *p;
     1110  int ret_value = parse_value_name_argument (argv[1], funcname);
     1111
     1112  /* FIXME: Optimize this.  Walk from the end on unexpanded arguments. */
     1113  while ((p = find_next_token (&words, &i)) != NULL)
     1114    {
     1115      struct variable *v = lookup_variable (p, i);
     1116      if (v && v->value_length)
     1117        {
     1118          last_v = v;
     1119          break;
     1120        }
     1121    }
     1122
     1123  if (last_v != NULL)
     1124    {
     1125      if (ret_value)
     1126        variable_expand_string_2 (o, last_v->value, last_v->value_length, &o);
     1127      else
     1128        o = variable_buffer_output (o, last_v->name, last_v->length);
     1129    }
     1130  return o;
     1131}
     1132
     1133#endif /* CONFIG_WITH_DEFINED_FUNCTIONS */
    10231134
    10241135static char *
     
    51545265  { STRING_SIZE_TUPLE("filter-out"),    2,  2,  1,  func_filter_filterout},
    51555266  { STRING_SIZE_TUPLE("findstring"),    2,  2,  1,  func_findstring},
     5267#ifdef CONFIG_WITH_DEFINED_FUNCTIONS
     5268  { STRING_SIZE_TUPLE("firstdefined"),  0,  2,  1,  func_firstdefined},
     5269#endif
    51565270  { STRING_SIZE_TUPLE("firstword"),     0,  1,  1,  func_firstword},
    51575271  { STRING_SIZE_TUPLE("flavor"),        0,  1,  1,  func_flavor},
    51585272  { STRING_SIZE_TUPLE("join"),          2,  2,  1,  func_join},
     5273#ifdef CONFIG_WITH_DEFINED_FUNCTIONS
     5274  { STRING_SIZE_TUPLE("lastdefined"),   0,  2,  1,  func_lastdefined},
     5275#endif
    51595276  { STRING_SIZE_TUPLE("lastword"),      0,  1,  1,  func_lastword},
    51605277  { STRING_SIZE_TUPLE("patsubst"),      3,  3,  1,  func_patsubst},
Note: See TracChangeset for help on using the changeset viewer.