/* Pattern and suffix rule internals for GNU Make.
Copyright (C) 1988-2013 Free Software Foundation, Inc.
This file is part of GNU Make.

GNU Make is free software; you can redistribute it and/or modify it under the
terms of the GNU General Public License as published by the Free Software
Foundation; either version 3 of the License, or (at your option) any later
version.

GNU Make is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.  See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with
this program.  If not, see <http://www.gnu.org/licenses/>.  */

#include "makeint.h"

#include <assert.h>

#include "dep.h"
#include "filedef.h"
#include "job.h"
#include "commands.h"
#include "variable.h"
#include "rule.h"

static void freerule (struct rule *rule, struct rule *lastrule);

/* Chain of all pattern rules.  */

struct rule *pattern_rules;

/* Pointer to last rule in the chain, so we can add onto the end.  */

struct rule *last_pattern_rule;

/* Number of rules in the chain.  */

unsigned int num_pattern_rules;

/* Maximum number of target patterns of any pattern rule.  */

unsigned int max_pattern_targets;

/* Maximum number of dependencies of any pattern rule.  */

unsigned int max_pattern_deps;

/* Maximum length of the name of a dependencies of any pattern rule.  */

unsigned int max_pattern_dep_length;

/* Pointer to structure for the file .SUFFIXES
   whose dependencies are the suffixes to be searched.  */

struct file *suffix_file;

/* Maximum length of a suffix.  */

unsigned int maxsuffix;

/* Compute the maximum dependency length and maximum number of
   dependencies of all implicit rules.  Also sets the subdir
   flag for a rule when appropriate, possibly removing the rule
   completely when appropriate.  */

void
count_implicit_rule_limits (void)
{
  char *name;
  int namelen;
  struct rule *rule;

  num_pattern_rules = max_pattern_targets = max_pattern_deps = 0;
  max_pattern_dep_length = 0;

  name = 0;
  namelen = 0;
  rule = pattern_rules;
  while (rule != 0)
    {
      unsigned int ndeps = 0;
      struct dep *dep;
      struct rule *next = rule->next;

      ++num_pattern_rules;

      if (rule->num > max_pattern_targets)
        max_pattern_targets = rule->num;

      for (dep = rule->deps; dep != 0; dep = dep->next)
        {
          const char *dname = dep_name (dep);
          unsigned int len = strlen (dname);

#ifdef VMS
          const char *p = strrchr (dname, ']');
          const char *p2;
          if (p == 0)
            p = strrchr (dname, ':');
          p2 = p != 0 ? strchr (dname, '%') : 0;
#else
          const char *p = strrchr (dname, '/');
          const char *p2 = p != 0 ? strchr (dname, '%') : 0;
#endif
          ndeps++;

          if (len > max_pattern_dep_length)
            max_pattern_dep_length = len;

          if (p != 0 && p2 > p)
            {
              /* There is a slash before the % in the dep name.
                 Extract the directory name.  */
              if (p == dname)
                ++p;
              if (p - dname > namelen)
                {
                  namelen = p - dname;
                  name = xrealloc (name, namelen + 1);
                }
              memcpy (name, dname, p - dname);
              name[p - dname] = '\0';

              /* In the deps of an implicit rule the 'changed' flag
                 actually indicates that the dependency is in a
                 nonexistent subdirectory.  */

              dep->changed = !dir_file_exists_p (name, "");
            }
          else
            /* This dependency does not reside in a subdirectory.  */
            dep->changed = 0;
        }

      if (ndeps > max_pattern_deps)
        max_pattern_deps = ndeps;

      rule = next;
    }

  if (name != 0)
    free (name);
}

/* Create a pattern rule from a suffix rule.
   TARGET is the target suffix; SOURCE is the source suffix.
   CMDS are the commands.
   If TARGET is nil, it means the target pattern should be '(%.o)'.
   If SOURCE is nil, it means there should be no deps.  */

static void
convert_suffix_rule (const char *target, const char *source,
                     struct commands *cmds)
{
  const char **names, **percents;
  struct dep *deps;

  names = xmalloc (sizeof (const char *));
  percents = xmalloc (sizeof (const char *));

  if (target == 0)
    {
      /* Special case: TARGET being nil means we are defining a '.X.a' suffix
         rule; the target pattern is always '(%.o)'.  */
#ifdef VMS
      *names = strcache_add_len ("(%.obj)", 7);
#else
      *names = strcache_add_len ("(%.o)", 5);
#endif
      *percents = *names + 1;
    }
  else
    {
      /* Construct the target name.  */
      unsigned int len = strlen (target);
      char *p = alloca (1 + len + 1);
      p[0] = '%';
      memcpy (p + 1, target, len + 1);
      *names = strcache_add_len (p, len + 1);
      *percents = *names;
    }

  if (source == 0)
    deps = 0;
  else
    {
      /* Construct the dependency name.  */
      unsigned int len = strlen (source);
      char *p = alloca (1 + len + 1);
      p[0] = '%';
      memcpy (p + 1, source, len + 1);
      deps = alloc_dep ();
      deps->name = strcache_add_len (p, len + 1);
    }

  create_pattern_rule (names, percents, 1, 0, deps, cmds, 0);
}

/* Convert old-style suffix rules to pattern rules.
   All rules for the suffixes on the .SUFFIXES list are converted and added to
   the chain of pattern rules.  */

void
convert_to_pattern (void)
{
  struct dep *d, *d2;
  char *rulename;

  /* We will compute every potential suffix rule (.x.y) from the list of
     suffixes in the .SUFFIXES target's dependencies and see if it exists.
     First find the longest of the suffixes.  */

  maxsuffix = 0;
  for (d = suffix_file->deps; d != 0; d = d->next)
    {
      unsigned int l = strlen (dep_name (d));
      if (l > maxsuffix)
        maxsuffix = l;
    }

  /* Space to construct the suffix rule target name.  */
  rulename = alloca ((maxsuffix * 2) + 1);

  for (d = suffix_file->deps; d != 0; d = d->next)
    {
      unsigned int slen;

      /* Make a rule that is just the suffix, with no deps or commands.
         This rule exists solely to disqualify match-anything rules.  */
      convert_suffix_rule (dep_name (d), 0, 0);

      if (d->file->cmds != 0)
        /* Record a pattern for this suffix's null-suffix rule.  */
        convert_suffix_rule ("", dep_name (d), d->file->cmds);

      /* Add every other suffix to this one and see if it exists as a
         two-suffix rule.  */
      slen = strlen (dep_name (d));
      memcpy (rulename, dep_name (d), slen);

      for (d2 = suffix_file->deps; d2 != 0; d2 = d2->next)
        {
          struct file *f;
          unsigned int s2len;

          s2len = strlen (dep_name (d2));

          /* Can't build something from itself.  */
          if (slen == s2len && streq (dep_name (d), dep_name (d2)))
            continue;

          memcpy (rulename + slen, dep_name (d2), s2len + 1);
          f = lookup_file (rulename);
          if (f == 0 || f->cmds == 0)
            continue;

          if (s2len == 2 && rulename[slen] == '.' && rulename[slen + 1] == 'a')
            /* A suffix rule '.X.a:' generates the pattern rule '(%.o): %.X'.
               It also generates a normal '%.a: %.X' rule below.  */
            convert_suffix_rule (NULL, /* Indicates '(%.o)'.  */
                                 dep_name (d),
                                 f->cmds);

          /* The suffix rule '.X.Y:' is converted
             to the pattern rule '%.Y: %.X'.  */
          convert_suffix_rule (dep_name (d2), dep_name (d), f->cmds);
        }
    }
}


/* Install the pattern rule RULE (whose fields have been filled in) at the end
   of the list (so that any rules previously defined will take precedence).
   If this rule duplicates a previous one (identical target and dependencies),
   the old one is replaced if OVERRIDE is nonzero, otherwise this new one is
   thrown out.  When an old rule is replaced, the new one is put at the end of
   the list.  Return nonzero if RULE is used; zero if not.  */

static int
new_pattern_rule (struct rule *rule, int override)
{
  struct rule *r, *lastrule;
  unsigned int i, j;

  rule->in_use = 0;
  rule->terminal = 0;

  rule->next = 0;

  /* Search for an identical rule.  */
  lastrule = 0;
  for (r = pattern_rules; r != 0; lastrule = r, r = r->next)
    for (i = 0; i < rule->num; ++i)
      {
        for (j = 0; j < r->num; ++j)
          if (!streq (rule->targets[i], r->targets[j]))
            break;
        /* If all the targets matched...  */
        if (j == r->num)
          {
            struct dep *d, *d2;
            for (d = rule->deps, d2 = r->deps;
                 d != 0 && d2 != 0; d = d->next, d2 = d2->next)
              if (!streq (dep_name (d), dep_name (d2)))
                break;
            if (d == 0 && d2 == 0)
              {
                /* All the dependencies matched.  */
                if (override)
                  {
                    /* Remove the old rule.  */
                    freerule (r, lastrule);
                    /* Install the new one.  */
                    if (pattern_rules == 0)
                      pattern_rules = rule;
                    else
                      last_pattern_rule->next = rule;
                    last_pattern_rule = rule;

                    /* We got one.  Stop looking.  */
                    goto matched;
                  }
                else
                  {
                    /* The old rule stays intact.  Destroy the new one.  */
                    freerule (rule, (struct rule *) 0);
                    return 0;
                  }
              }
          }
      }

 matched:;

  if (r == 0)
    {
      /* There was no rule to replace.  */
      if (pattern_rules == 0)
        pattern_rules = rule;
      else
        last_pattern_rule->next = rule;
      last_pattern_rule = rule;
    }

  return 1;
}


/* Install an implicit pattern rule based on the three text strings
   in the structure P points to.  These strings come from one of
   the arrays of default implicit pattern rules.
   TERMINAL specifies what the 'terminal' field of the rule should be.  */

void
install_pattern_rule (struct pspec *p, int terminal)
{
  struct rule *r;
  char *ptr;

  r = xmalloc (sizeof (struct rule));

  r->num = 1;
  r->targets = xmalloc (sizeof (const char *));
  r->suffixes = xmalloc (sizeof (const char *));
  r->lens = xmalloc (sizeof (unsigned int));

  r->lens[0] = strlen (p->target);
  r->targets[0] = p->target;
  r->suffixes[0] = find_percent_cached (&r->targets[0]);
  assert (r->suffixes[0] != NULL);
  ++r->suffixes[0];

  ptr = p->dep;
  r->deps = PARSE_SIMPLE_SEQ (&ptr, struct dep);

  if (new_pattern_rule (r, 0))
    {
      r->terminal = terminal;
      r->cmds = xmalloc (sizeof (struct commands));
      r->cmds->fileinfo.filenm = 0;
      r->cmds->fileinfo.lineno = 0;
      /* These will all be string literals, but we malloc space for them
         anyway because somebody might want to free them later.  */
      r->cmds->commands = xstrdup (p->commands);
      r->cmds->command_lines = 0;
      r->cmds->recipe_prefix = RECIPEPREFIX_DEFAULT;
    }
}


/* Free all the storage used in RULE and take it out of the
   pattern_rules chain.  LASTRULE is the rule whose next pointer
   points to RULE.  */

static void
freerule (struct rule *rule, struct rule *lastrule)
{
  struct rule *next = rule->next;

  free_dep_chain (rule->deps);

  /* MSVC erroneously warns without a cast here.  */
  free ((void *)rule->targets);
  free ((void *)rule->suffixes);
  free (rule->lens);

  /* We can't free the storage for the commands because there
     are ways that they could be in more than one place:
       * If the commands came from a suffix rule, they could also be in
       the 'struct file's for other suffix rules or plain targets given
       on the same makefile line.
       * If two suffixes that together make a two-suffix rule were each
       given twice in the .SUFFIXES list, and in the proper order, two
       identical pattern rules would be created and the second one would
       be discarded here, but both would contain the same 'struct commands'
       pointer from the 'struct file' for the suffix rule.  */

  free (rule);

  if (pattern_rules == rule)
    if (lastrule != 0)
      abort ();
    else
      pattern_rules = next;
  else if (lastrule != 0)
    lastrule->next = next;
  if (last_pattern_rule == rule)
    last_pattern_rule = lastrule;
}

/* Create a new pattern rule with the targets in the nil-terminated array
   TARGETS.  TARGET_PERCENTS is an array of pointers to the % in each element
   of TARGETS.  N is the number of items in the array (not counting the nil
   element).  The new rule has dependencies DEPS and commands from COMMANDS.
   It is a terminal rule if TERMINAL is nonzero.  This rule overrides
   identical rules with different commands if OVERRIDE is nonzero.

   The storage for TARGETS and its elements and TARGET_PERCENTS is used and
   must not be freed until the rule is destroyed.  */

void
create_pattern_rule (const char **targets, const char **target_percents,
                     unsigned int n, int terminal, struct dep *deps,
                     struct commands *commands, int override)
{
  unsigned int i;
  struct rule *r = xmalloc (sizeof (struct rule));

  r->num = n;
  r->cmds = commands;
  r->deps = deps;
  r->targets = targets;
  r->suffixes = target_percents;
  r->lens = xmalloc (n * sizeof (unsigned int));

  for (i = 0; i < n; ++i)
    {
      r->lens[i] = strlen (targets[i]);
      assert (r->suffixes[i] != NULL);
      ++r->suffixes[i];
    }

  if (new_pattern_rule (r, override))
    r->terminal = terminal;
}

/* Print the data base of rules.  */

static void                     /* Useful to call from gdb.  */
print_rule (struct rule *r)
{
  unsigned int i;

  for (i = 0; i < r->num; ++i)
    {
      fputs (r->targets[i], stdout);
      putchar ((i + 1 == r->num) ? ':' : ' ');
    }
  if (r->terminal)
    putchar (':');

  print_prereqs (r->deps);

  if (r->cmds != 0)
    print_commands (r->cmds);
}

void
print_rule_data_base (void)
{
  unsigned int rules, terminal;
  struct rule *r;

  puts (_("\n# Implicit Rules"));

  rules = terminal = 0;
  for (r = pattern_rules; r != 0; r = r->next)
    {
      ++rules;

      putchar ('\n');
      print_rule (r);

      if (r->terminal)
        ++terminal;
    }

  if (rules == 0)
    puts (_("\n# No implicit rules."));
  else
    {
      printf (_("\n# %u implicit rules, %u"), rules, terminal);
#ifndef NO_FLOAT
      printf (" (%.1f%%)", (double) terminal / (double) rules * 100.0);
#else
      {
        int f = (terminal * 1000 + 5) / rules;
        printf (" (%d.%d%%)", f/10, f%10);
      }
#endif
      puts (_(" terminal."));
    }

  if (num_pattern_rules != rules)
    {
      /* This can happen if a fatal error was detected while reading the
         makefiles and thus count_implicit_rule_limits wasn't called yet.  */
      if (num_pattern_rules != 0)
        fatal (NILF, _("BUG: num_pattern_rules is wrong!  %u != %u"),
               num_pattern_rules, rules);
    }
}
