Ignore:
Timestamp:
Mar 30, 2008, 6:13:55 AM (17 years ago)
Author:
bird
Message:

Added comp-cmds-ex, commands, commands-sc and commands-usr. Added a '%' command prefix that make the commands functions skip the line. Added a -c flag to append that'll make it call commands on each argument (similar to -v). Fixed a little bug in comp-cmds/vars.

File:
1 edited

Legend:

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

    r1439 r1440  
    23552355   writing rules. */
    23562356static char *
    2357 func_xargs (char *o, char **argv, const char *funcname)
     2357func_xargs (char *o, char **argv, const char *funcname UNUSED)
    23582358{
    23592359  int argc;
     
    25172517        if (!isblank (ch)
    25182518         && ch != '@'
     2519#ifdef CONFIG_WITH_COMMANDS_FUNC
     2520         && ch != '%'
     2521#endif
    25192522         && ch != '+'
    25202523         && ch != '-')
     
    25322535              char *ne_retval, const char *funcname)
    25332536{
    2534     /* give up at once if not comp-cmds. */
    2535     if (strcmp (funcname, "comp-cmds") != 0)
     2537    /* give up at once if not comp-cmds or comp-cmds-ex. */
     2538    if (strcmp (funcname, "comp-cmds") != 0
     2539     && strcmp (funcname, "comp-cmds-ex") != 0)
    25362540      o = variable_buffer_output (o, ne_retval, strlen (ne_retval));
    25372541    else
     
    26402644
    26412645  comp-cmds will compare command by command, ignoring not only leading
    2642   and trailing spaces on each line but also leading one leading '@' and '-'.
     2646  and trailing spaces on each line but also leading one leading '@',
     2647  '-', '+' and '%'
    26432648*/
    26442649static char *
     
    26662671    /* ignore trailing and leading blanks */
    26672672    s1 = var1->value;
     2673    e1 = s1 + var1->value_length;
    26682674    while (isblank ((unsigned char) *s1))
    26692675      s1++;
    2670     e1 = s1 + var1->value_length;
    26712676    while (e1 > s1 && isblank ((unsigned char) e1[-1]))
    26722677      e1--;
    26732678
    26742679    s2 = var2->value;
     2680    e2 = s2 + var2->value_length;
    26752681    while (isblank ((unsigned char) *s2))
    26762682      s2++;
    2677     e2 = s2 + var2->value_length;
    26782683    while (e2 > s2 && isblank ((unsigned char) e2[-1]))
    26792684      e2--;
     
    27622767  return o;
    27632768}
     2769
     2770/*
     2771  $(comp-cmds-ex cmds1,cmds2,not-equal-return)
     2772
     2773  Compares the two strings and return the string in the third argument
     2774  if not equal. If equal, nothing is returned.
     2775
     2776  The comparision will be performed command by command, ignoring not
     2777  only leading and trailing spaces on each line but also leading one
     2778  leading '@', '-', '+' and '%'.
     2779*/
     2780static char *
     2781func_comp_cmds_ex (char *o, char **argv, const char *funcname)
     2782{
     2783  const char *s1, *e1, *x1, *s2, *e2, *x2;
     2784  char *a1 = NULL, *a2 = NULL;
     2785  size_t l, l1, l2;
     2786
     2787  /* the simple cases */
     2788  s1 = argv[0];
     2789  s2 = argv[1];
     2790  if (s1 == s2)
     2791    return variable_buffer_output (o, "", 0);       /* eq */
     2792  l1 = strlen (argv[0]);
     2793  l2 = strlen (argv[1]);
     2794
     2795  if (    l1 == l2
     2796      &&  !memcmp (s1, s2, l1))
     2797    return variable_buffer_output (o, "", 0);       /* eq */
     2798
     2799  /* ignore trailing and leading blanks */
     2800  e1 = s1 + l1;
     2801  while (isblank ((unsigned char) *s1))
     2802    s1++;
     2803  while (e1 > s1 && isblank ((unsigned char) e1[-1]))
     2804    e1--;
     2805
     2806  e2 = s2 + l1;
     2807  while (isblank ((unsigned char) *s2))
     2808    s2++;
     2809  while (e2 > s2 && isblank ((unsigned char) e2[-1]))
     2810    e2--;
     2811
     2812  if (e1 - s1 != e2 - s2)
     2813    return comp_vars_ne (o, s1, e1, s2, e2, argv[2], funcname);
     2814  if (!memcmp (s1, s2, e1 - s1))
     2815    return variable_buffer_output (o, "", 0);       /* eq */
     2816  return comp_vars_ne (o, s1, e1, s2, e2, argv[2], funcname);
     2817}
    27642818#endif
    27652819
     
    28512905   fails. */
    28522906static char *
    2853 func_file_size (char *o, char **argv, const char *funcname)
     2907func_file_size (char *o, char **argv, const char *funcname UNUSED)
    28542908{
    28552909  struct stat st;
     
    29242978   their full location if found. Prints nothing if not found. */
    29252979static char *
    2926 func_which (char *o, char **argv, const char *funcname)
     2980func_which (char *o, char **argv, const char *funcname UNUSED)
    29272981{
    29282982  const char *path;
     
    30063060/* Push an item (string without spaces). */
    30073061static char *
    3008 func_stack_push (char *o, char **argv, const char *funcname)
     3062func_stack_push (char *o, char **argv, const char *funcname UNUSED)
    30093063{
    30103064  do_variable_definition(NILF, argv[0], argv[1], o_file, f_append, 0 /* !target_var */);
     
    31793233/* Add two or more integer numbers. */
    31803234static char *
    3181 func_int_add (char *o, char **argv, const char *funcname)
     3235func_int_add (char *o, char **argv, const char *funcname UNUSED)
    31823236{
    31833237  math_int num;
     
    31933247/* Subtract two or more integer numbers. */
    31943248static char *
    3195 func_int_sub (char *o, char **argv, const char *funcname)
     3249func_int_sub (char *o, char **argv, const char *funcname UNUSED)
    31963250{
    31973251  math_int num;
     
    32073261/* Multiply two or more integer numbers. */
    32083262static char *
    3209 func_int_mul (char *o, char **argv, const char *funcname)
     3263func_int_mul (char *o, char **argv, const char *funcname UNUSED)
    32103264{
    32113265  math_int num;
     
    32213275/* Divide an integer number by one or more divisors. */
    32223276static char *
    3223 func_int_div (char *o, char **argv, const char *funcname)
     3277func_int_div (char *o, char **argv, const char *funcname UNUSED)
    32243278{
    32253279  math_int num;
     
    32453299/* Divide and return the remainder. */
    32463300static char *
    3247 func_int_mod (char *o, char **argv, const char *funcname)
     3301func_int_mod (char *o, char **argv, const char *funcname UNUSED)
    32483302{
    32493303  math_int num;
     
    32643318/* 2-complement. */
    32653319static char *
    3266 func_int_not (char *o, char **argv, const char *funcname)
     3320func_int_not (char *o, char **argv, const char *funcname UNUSED)
    32673321{
    32683322  math_int num;
     
    32763330/* Bitwise AND (two or more numbers). */
    32773331static char *
    3278 func_int_and (char *o, char **argv, const char *funcname)
     3332func_int_and (char *o, char **argv, const char *funcname UNUSED)
    32793333{
    32803334  math_int num;
     
    32903344/* Bitwise OR (two or more numbers). */
    32913345static char *
    3292 func_int_or (char *o, char **argv, const char *funcname)
     3346func_int_or (char *o, char **argv, const char *funcname UNUSED)
    32933347{
    32943348  math_int num;
     
    33043358/* Bitwise XOR (two or more numbers). */
    33053359static char *
    3306 func_int_xor (char *o, char **argv, const char *funcname)
     3360func_int_xor (char *o, char **argv, const char *funcname UNUSED)
    33073361{
    33083362  math_int num;
     
    34163470   the variable. */
    34173471static char *
    3418 func_os2_libpath (char *o, char **argv, const char *funcname)
     3472func_os2_libpath (char *o, char **argv, const char *funcname UNUSED)
    34193473{
    34203474  char buf[4096];
     
    35033557/* Retrieve make statistics. */
    35043558static char *
    3505 func_make_stats (char *o, char **argv, const char *funcname)
     3559func_make_stats (char *o, char **argv, const char *funcname UNUSED)
    35063560{
    35073561  char buf[512];
     
    35513605  return o;
    35523606}
    3553 #endif
     3607#endif  /* CONFIG_WITH_MAKE_STATS */
     3608
     3609#ifdef CONFIG_WITH_COMMANDS_FUNC
     3610/* Gets all the commands for a target, separated by newlines.
     3611 
     3612   This is useful when creating and checking target dependencies since
     3613   it reduces the amount of work and the memory consuption. A new prefix
     3614   character '%' has been introduced for skipping certain lines, like
     3615   for instance the one calling this function and pushing to a dep file.
     3616   Blank lines are also skipped.
     3617
     3618   The commands function takes exactly one argument, which is the name of
     3619   the target which commands should be returned.
     3620
     3621   The commands-sc is identical to commands except that it uses a ';' to
     3622   separate the commands.
     3623
     3624   The commands-usr is similar to commands except that it takes a 2nd
     3625   argument that is used to separate the commands. */
     3626char *
     3627func_commands (char *o, char **argv, const char *funcname)
     3628{
     3629  struct file *file;
     3630  static int recursive = 0;
     3631
     3632  if (recursive)
     3633    return variable_buffer_output (o, "recursive", sizeof ("recursive") - 1);
     3634  recursive = 1;
     3635
     3636  file = lookup_file (argv[0]);
     3637  if (file)
     3638    {
     3639      int i, cmd_sep_len;
     3640      struct commands *cmds = file->cmds;
     3641      const char *cmd_sep;
     3642
     3643      if (!strcmp (funcname, "commands"))
     3644        {
     3645          cmd_sep = "\n";
     3646          cmd_sep_len = 1;
     3647        }
     3648      else if (!strcmp (funcname, "commands-sc"))
     3649        {
     3650          cmd_sep = ";";
     3651          cmd_sep_len = 1;
     3652        }
     3653      else /*if (!strcmp (funcname, "commands-usr"))*/
     3654        {
     3655          cmd_sep = argv[1];
     3656          cmd_sep_len = strlen (cmd_sep);
     3657        }
     3658
     3659      initialize_file_variables (file, 1 /* reading - FIXME: we don't know? */);
     3660      set_file_variables (file);
     3661      chop_commands (cmds);
     3662
     3663      for (i = 0; i < cmds->ncommand_lines; i++)
     3664        {
     3665          char *p;
     3666          char *in, *out, *ref;
     3667
     3668          /* Skip it if it has a '%' prefix or is blank. */
     3669          if (cmds->lines_flags[i] & COMMAND_GETTER_SKIP_IT)
     3670            continue;
     3671          p = cmds->command_lines[i];
     3672          while (isblank ((unsigned char)*p))
     3673            p++;
     3674          if (*p == '\0')
     3675            continue;
     3676
     3677          /* --- copied from new_job() in job.c --- */
     3678
     3679          /* Collapse backslash-newline combinations that are inside variable
     3680             or function references.  These are left alone by the parser so
     3681             that they will appear in the echoing of commands (where they look
     3682             nice); and collapsed by construct_command_argv when it tokenizes.
     3683             But letting them survive inside function invocations loses because
     3684             we don't want the functions to see them as part of the text.  */
     3685
     3686          /* IN points to where in the line we are scanning.
     3687             OUT points to where in the line we are writing.
     3688             When we collapse a backslash-newline combination,
     3689             IN gets ahead of OUT.  */
     3690
     3691          in = out = p;
     3692          while ((ref = strchr (in, '$')) != 0)
     3693            {
     3694              ++ref;            /* Move past the $.  */
     3695
     3696              if (out != in)
     3697                /* Copy the text between the end of the last chunk
     3698                   we processed (where IN points) and the new chunk
     3699                   we are about to process (where REF points).  */
     3700                memmove (out, in, ref - in);
     3701
     3702              /* Move both pointers past the boring stuff.  */
     3703              out += ref - in;
     3704              in = ref;
     3705
     3706              if (*ref == '(' || *ref == '{')
     3707                {
     3708                  char openparen = *ref;
     3709                  char closeparen = openparen == '(' ? ')' : '}';
     3710                  int count;
     3711                  char *p;
     3712
     3713                  *out++ = *in++;       /* Copy OPENPAREN.  */
     3714                  /* IN now points past the opening paren or brace.
     3715                     Count parens or braces until it is matched.  */
     3716                  count = 0;
     3717                  while (*in != '\0')
     3718                    {
     3719                      if (*in == closeparen && --count < 0)
     3720                        break;
     3721                      else if (*in == '\\' && in[1] == '\n')
     3722                        {
     3723                          /* We have found a backslash-newline inside a
     3724                             variable or function reference.  Eat it and
     3725                             any following whitespace.  */
     3726
     3727                          int quoted = 0;
     3728                          for (p = in - 1; p > ref && *p == '\\'; --p)
     3729                            quoted = !quoted;
     3730
     3731                          if (quoted)
     3732                            /* There were two or more backslashes, so this is
     3733                               not really a continuation line.  We don't collapse
     3734                               the quoting backslashes here as is done in
     3735                               collapse_continuations, because the line will
     3736                               be collapsed again after expansion.  */
     3737                            *out++ = *in++;
     3738                          else
     3739                            {
     3740                              /* Skip the backslash, newline and
     3741                                 any following whitespace.  */
     3742                              in = next_token (in + 2);
     3743
     3744                              /* Discard any preceding whitespace that has
     3745                                 already been written to the output.  */
     3746                              while (out > ref
     3747                                     && isblank ((unsigned char)out[-1]))
     3748                                --out;
     3749
     3750                              /* Replace it all with a single space.  */
     3751                              *out++ = ' ';
     3752                            }
     3753                        }
     3754                      else
     3755                        {
     3756                          if (*in == openparen)
     3757                            ++count;
     3758
     3759                          *out++ = *in++;
     3760                        }
     3761                    }
     3762                }
     3763            }
     3764
     3765          /* There are no more references in this line to worry about.
     3766             Copy the remaining uninteresting text to the output.  */
     3767          if (out != in)
     3768            strcpy (out, in);
     3769
     3770          /* --- copied from new_job() in job.c --- */
     3771
     3772          /* Finally, expand the line.  */
     3773          if (i)
     3774            o = variable_buffer_output (o, cmd_sep, cmd_sep_len);
     3775          o = variable_expand_for_file_2 (o, cmds->command_lines[i], file);
     3776
     3777          /* blank, if so, drop it. */
     3778          p = o;
     3779          while (isblank ((unsigned char)*o))
     3780            o++;
     3781          if (o != '\0')
     3782            o = strchr (o, '\0');
     3783          else
     3784            o = p - cmd_sep_len;
     3785        }
     3786    }
     3787  /* else FIXME: bitch about it? */
     3788
     3789  recursive = 0;
     3790  return o;
     3791}
     3792#endif  /* CONFIG_WITH_COMMANDS_FUNC */
    35543793
    35553794/* Lookup table for builtin functions.
     
    36333872  { STRING_SIZE_TUPLE("comp-vars"),     3,  3,  1,  func_comp_vars},
    36343873  { STRING_SIZE_TUPLE("comp-cmds"),     3,  3,  1,  func_comp_vars},
     3874  { STRING_SIZE_TUPLE("comp-cmds-ex"),  3,  3,  1,  func_comp_cmds_ex},
    36353875#endif
    36363876#ifdef CONFIG_WITH_DATE
     
    36763916  { STRING_SIZE_TUPLE("make-stats"),    0, ~0,  0,  func_make_stats},
    36773917#endif
     3918#ifdef CONFIG_WITH_COMMANDS_FUNC
     3919  { STRING_SIZE_TUPLE("commands"),      1,  1,  1,  func_commands},
     3920  { STRING_SIZE_TUPLE("commands-sc"),   1,  1,  1,  func_commands},
     3921  { STRING_SIZE_TUPLE("commands-usr"),  2,  2,  1,  func_commands},
     3922#endif
    36783923#ifdef KMK_HELPERS
    36793924  { STRING_SIZE_TUPLE("kb-src-tool"),   1,  1,  0,  func_kbuild_source_tool},
Note: See TracChangeset for help on using the changeset viewer.