/* Pattern and suffix rule internals for GNU Make.
Copyright (C) 1988-2024 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 <https://www.gnu.org/licenses/>.  */

#include "makeint.h"

#include <assert.h>

#include "filedef.h"
#include "dep.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.  */

size_t max_pattern_dep_length;

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

struct file *suffix_file;

/* Return the rule definition: space separated rule targets, followed by
   either a colon or two colons in the case of a terminal rule, followed by
   space separated rule prerequisites, followed by a pipe, followed by
   order-only prerequisites, if present.  */

const char *
get_rule_defn (struct rule *r)
{
  if (r->_defn == NULL)
    {
      size_t len = 8; /* Reserve for ":: ", " | ", and nul.  */
      unsigned int k;
      char *p;
      const char *sep = "";
      const struct dep *dep, *ood = 0;

      for (k = 0; k < r->num; ++k)
        len += r->lens[k] + 1;

      for (dep = r->deps; dep; dep = dep->next)
        len += strlen (dep_name (dep)) + (dep->wait_here ? CSTRLEN (" .WAIT") : 0) + 1;

      p = r->_defn = xmalloc (len);
      for (k = 0; k < r->num; ++k, sep = " ")
        p = mempcpy (mempcpy (p, sep, strlen (sep)), r->targets[k], r->lens[k]);
      *p++ = ':';
      if (r->terminal)
        *p++ = ':';

      /* Copy all normal dependencies; note any order-only deps.  */
      for (dep = r->deps; dep; dep = dep->next)
        if (dep->ignore_mtime == 0)
          {
            if (dep->wait_here)
              p = mempcpy (p, " .WAIT", CSTRLEN (" .WAIT"));
            p = mempcpy (mempcpy (p, " ", 1), dep_name (dep),
                         strlen (dep_name (dep)));
          }
        else if (ood == 0)
          ood = dep;

      /* Copy order-only deps, if we have any.  */
      for (sep = " | "; ood; ood = ood->next, sep = " ")
        if (ood->ignore_mtime)
          {
            p = mempcpy (p, sep, strlen (sep));
            if (ood->wait_here)
              p = mempcpy (p, ".WAIT ", CSTRLEN (".WAIT "));
            p = mempcpy (p, dep_name (ood), strlen (dep_name (ood)));
          }
      *p = '\0';
    }

  return r->_defn;
}


/* 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.

   Add any global EXTRA_PREREQS here as well.  */

void
snap_implicit_rules (void)
{
  char *name = NULL;
  size_t namelen = 0;
  struct rule *rule;
  struct dep *dep;
  struct dep *prereqs = expand_extra_prereqs (lookup_variable (STRING_SIZE_TUPLE(".EXTRA_PREREQS")));
  unsigned int pre_deps = 0;

  max_pattern_dep_length = 0;

  for (dep = prereqs; dep; dep = dep->next)
    {
      const char *d = dep_name (dep);
      size_t l = strlen (d);

      if (second_expansion)
        {
          if (!dep->name)
            dep->name = xstrdup (dep->file->name);
          dep->need_2nd_expansion = 1;
        }
      if (dep->need_2nd_expansion)
        /* When pattern_search allocates a buffer, allow 5 bytes per each % to
           substitute each % with $(*F) while avoiding realloc.  */
        while ((d = strchr (d, '%')) != 0)
          {
            l += 4;
            ++d;
          }

      if (l > max_pattern_dep_length)
        max_pattern_dep_length = l;
      ++pre_deps;
    }

  num_pattern_rules = max_pattern_targets = max_pattern_deps = 0;

  for (rule = pattern_rules; rule; rule = rule->next)
    {
      unsigned int ndeps = pre_deps;
      struct dep *lastdep = NULL;

      ++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);
          size_t len = strlen (dname);

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

          if (len > max_pattern_dep_length)
            max_pattern_dep_length = len;

          if (!dep->next)
            lastdep = dep;

          if (p2)
            {
              /* There is a slash before the % in the dep name.
                 Extract the directory name.  */
              if (p == dname)
                ++p;
              if ((size_t) (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 (prereqs)
        {
          if (lastdep)
            lastdep->next = copy_dep_chain (prereqs);
          else
            rule->deps = copy_dep_chain (prereqs);
        }

      if (ndeps > max_pattern_deps)
        max_pattern_deps = ndeps;
    }

  free (name);
  free_dep_chain (prereqs);
}

/* 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)'.  */
#if MK_OS_VMS
      *names = strcache_add_len ("(%.obj)", 7);
#else
      *names = strcache_add_len ("(%.o)", 5);
#endif
      *percents = *names + 1;
    }
  else
    {
      /* Construct the target name.  */
      size_t 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.  */
      size_t 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.  */

  size_t maxsuffix = 0;
  for (d = suffix_file->deps; d != 0; d = d->next)
    {
      size_t 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)
    {
      struct file *f;
      size_t 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);

      slen = strlen (dep_name (d));
      memcpy (rulename, dep_name (d), slen + 1);

      f = lookup_file (rulename);
      if (f && f->cmds)
        {
          if (!f->deps)
            f->suffix = 1;
          else if (!posix_pedantic)
            {
              O (error, &f->cmds->fileinfo,
                 _("warning: ignoring prerequisites on suffix rule definition"));
              f->suffix = 1;
            }
        }

      /* Add every other suffix to this one and see if it exists as a
         two-suffix rule.  */
      for (d2 = suffix_file->deps; d2 != 0; d2 = d2->next)
        {
          size_t 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);

          /* No target, or no commands: it can't be a suffix rule.  */
          if (f == 0 || f->cmds == 0)
            continue;

          /* POSIX says that suffix rules can't have prerequisites.
             In POSIX mode, don't make this a suffix rule.  Previous versions
             of GNU Make did treat this as a suffix rule and ignored the
             prerequisites, which is bad.  In the future we'll do the same as
             POSIX, but for now preserve the old behavior and warn about it.  */
          if (f->deps != 0)
            {
              if (posix_pedantic)
                continue;
              O (error, &f->cmds->fileinfo,
                 _("warning: ignoring prerequisites on suffix rule definition"));
            }

          f->suffix = 1;

          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;
  const 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->_defn = NULL;

  r->lens[0] = (unsigned int) 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 ((char **)&ptr, struct dep);

  if (new_pattern_rule (r, 0))
    {
      r->terminal = terminal ? 1 : 0;
      r->cmds = xmalloc (sizeof (struct commands));
      r->cmds->fileinfo.filenm = 0;
      r->cmds->fileinfo.lineno = 0;
      r->cmds->fileinfo.offset = 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);
  free ((void *) rule->_defn);

  /* 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 short 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));
  r->_defn = NULL;

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

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

static void                     /* Useful to call from gdb.  */
print_rule (struct rule *r)
{
  fputs (get_rule_defn (r), stdout);
  putchar ('\n');

  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 (%.1f%%) terminal."),
              rules, terminal, (double) terminal / (double) rules * 100.0);
    }

  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)
        ONN (fatal, NILF, "INTERNAL: num_pattern_rules is wrong!  %u != %u",
             num_pattern_rules, rules);
    }
}
