/* Implicit rule searching for GNU Make.
Copyright (C) 1988-2025 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 "commands.h" /* set_file_variables */
#include "debug.h"
#include "dep.h"
#include "filedef.h"
#include "job.h"      /* struct child, used inside commands.h */
#include "rule.h"
#include "shuffle.h"
#include "variable.h"

static int pattern_search (struct file *file, int archive,
                           unsigned int depth, unsigned int recursions,
                           int allow_compat_rules);

/* For a FILE which has no commands specified, try to figure out some
   from the implicit pattern rules.
   Returns 1 if a suitable implicit rule was found,
   after modifying FILE to contain the appropriate commands and deps,
   or returns 0 if no implicit rule was found.  */

int
try_implicit_rule (struct file *file, unsigned int depth)
{
  DBF (DB_IMPLICIT, _("Looking for an implicit rule for '%s'.\n"));

  /* The order of these searches was previously reversed.  My logic now is
     that since the non-archive search uses more information in the target
     (the archive search omits the archive name), it is more specific and
     should come first.  */

  if (pattern_search (file, 0, depth, 0, 0))
    return 1;

#ifndef NO_ARCHIVES
  /* If this is an archive member reference, use just the
     archive member name to search for implicit rules.  */
  if (ar_name (file->name))
    {
      DBF (DB_IMPLICIT,
           _("Looking for archive-member implicit rule for '%s'.\n"));
      if (pattern_search (file, 1, depth, 0, 0))
        return 1;
      DBS (DB_IMPLICIT,
           (_("No archive-member implicit rule found for '%s'.\n"),
            file->name));
    }
#endif

  return 0;
}


/* Scans the BUFFER for the next word with whitespace as a separator.
   Returns the pointer to the beginning of the word. LENGTH hold the
   length of the word.  */

static const char *
get_next_word (const char *buffer, size_t *length)
{
  const char *p = buffer, *beg;
  char c;

  /* Skip any leading whitespace.  */
  NEXT_TOKEN (p);

  beg = p;
  c = *(p++);

  if (c == '\0')
    return 0;


  while (1)
    {
      /* Each time through the loop, "c" has the current char
         and "p" points to the next char.  */
      switch (c)
        {
        case '\0':
        case ' ':
        case '\t':
          goto done_word;

        case '$':
          /* This is a variable reference, so skip it.  */
          p = skip_reference (p);
          break;

        case '|':
          goto done;

        default:
          break;
        }

      c = *(p++);
    }
 done_word:
  --p;

 done:
  if (length)
    *length = p - beg;

  return beg;
}

/* This structure stores information about the expanded prerequisites for a
   pattern rule.  NAME is always set to the strcache'd name of the prereq.
   FILE and PATTERN will be set for intermediate files only.  IGNORE_MTIME is
   copied from the prerequisite we expanded.
 */
struct patdeps
  {
    const char *name;
    const char *pattern;
    struct file *file;
    unsigned int ignore_mtime : 1;
    unsigned int ignore_automatic_vars : 1;
    unsigned int is_explicit : 1;
    unsigned int wait_here : 1;
  };

/* This structure stores information about pattern rules that we need
   to try.
*/
struct tryrule
  {
    struct rule *rule;

    /* Stem length for this match. */
    size_t stemlen;

    /* Index of the target in this rule that matched the file. */
    unsigned int matches;

    /* Definition order of this rule. Used to implement stable sort.*/
    unsigned int order;

    /* Nonzero if the LASTSLASH logic was used in matching this rule. */
    char checked_lastslash;
  };

int
stemlen_compare (const void *v1, const void *v2)
{
  const struct tryrule *r1 = v1;
  const struct tryrule *r2 = v2;
  int r = (int) (r1->stemlen - r2->stemlen);
  return r != 0 ? r : (int) (r1->order - r2->order);
}

/* Search the pattern rules for a rule with an existing dependency to make
   FILE.  If a rule is found, the appropriate commands and deps are put in FILE
   and 1 is returned.  If not, 0 is returned.

   If ARCHIVE is nonzero, FILE->name is of the form "LIB(MEMBER)".  A rule for
   "(MEMBER)" will be searched for, and "(MEMBER)" will not be chopped up into
   directory and filename parts.

   If an intermediate file is found by pattern search, the intermediate file
   is set up as a target by the recursive call and is also made a dependency
   of FILE.

   DEPTH is used for debugging messages.  */

static int
pattern_search (struct file *file, int archive,
                unsigned int depth, unsigned int recursions,
                int allow_compat_rules)
{
  /* Filename we are searching for a rule for.  */
  const char *filename = archive ? strchr (file->name, '(') : file->name;

  /* Length of FILENAME.  */
  size_t namelen = strlen (filename);

  /* The last slash in FILENAME (or nil if there is none).  */
  const char *lastslash;

  /* This is a file-object used as an argument in
     recursive calls.  It never contains any data
     except during a recursive call.  */
  struct file *int_file = 0;

  /* List of dependencies found recursively.  */
  unsigned int max_deps = max_pattern_deps;
  struct patdeps *deplist = xmalloc (max_deps * sizeof (struct patdeps));
  struct patdeps *pat = deplist;

  /* Names of possible dependencies are constructed in this buffer.
     We may replace % by $(*F) for second expansion, increasing the length.  */
  size_t deplen = namelen + max_pattern_dep_length + 4;
  char *depname = alloca (deplen);
#ifndef NDEBUG
  char *dend = depname + deplen;
#endif

  /* The start and length of the stem of FILENAME for the current rule.  */
  const char *stem = 0;
  size_t stemlen = 0;
  size_t fullstemlen = 0;

  /* Buffer in which we store all the rules that are possibly applicable.  */
  struct tryrule *tryrules = xmalloc (num_pattern_rules * max_pattern_targets
                                      * sizeof (struct tryrule));

  /* Number of valid elements in TRYRULES.  */
  unsigned int nrules;

  /* The index in TRYRULES of the rule we found.  */
  unsigned int foundrule;

  /* Nonzero if should consider intermediate files as dependencies.  */
  int intermed_ok;

  /* Nonzero if we have initialized file variables for this target.  */
  int file_vars_initialized = 0;

  /* Nonzero if we have matched a pattern-rule target
     that is not just '%'.  */
  int specific_rule_matched = 0;

  unsigned int ri;  /* uninit checks OK */
  int found_compat_rule = 0;
  struct rule *rule;

  char *pathdir = NULL;
  size_t pathlen;

  PATH_VAR (stem_str); /* @@ Need to get rid of stem, stemlen, etc. */

  ++depth;

#ifndef NO_ARCHIVES
  if (archive || ar_name (filename))
    lastslash = 0;
  else
#endif
    {
      /* Set LASTSLASH to point at the last slash in FILENAME
         but not counting any slash at the end.  (foo/bar/ counts as
         bar/ in directory foo/, not empty in directory foo/bar/.)  */
      lastslash = memrchr (filename, '/', namelen - 1);
#if MK_OS_VMS
      if (lastslash == NULL)
        lastslash = strrchr (filename, ']');
      if (lastslash == NULL)
        lastslash = strrchr (filename, '>');
      if (lastslash == NULL)
        lastslash = strrchr (filename, ':');
#endif
#ifdef HAVE_DOS_PATHS
      /* Handle backslashes (possibly mixed with forward slashes)
         and the case of "d:file".  */
      {
        char *bslash = memrchr (filename, '\\', namelen - 1);
        if (lastslash == 0 || bslash > lastslash)
          lastslash = bslash;
        if (lastslash == 0 && filename[0] && filename[1] == ':')
          lastslash = filename + 1;
      }
#endif
    }

  pathlen = lastslash ? lastslash - filename + 1 : 0;

  /* First see which pattern rules match this target and may be considered.
     Put them in TRYRULES.  */

  nrules = 0;
  for (rule = pattern_rules; rule != 0; rule = rule->next)
    {
      unsigned int ti;

      /* If the pattern rule has deps but no commands, ignore it.
         Users cancel built-in rules by redefining them without commands.  */
      if (rule->deps != 0 && rule->cmds == 0)
        continue;

      /* If this rule is in use by a parent pattern_search,
         don't use it here.  */
      if (rule->in_use)
        {
          DBS (DB_IMPLICIT,
               (_("Avoiding implicit rule recursion for rule '%s'.\n"),
                get_rule_defn (rule)));
          continue;
        }

      for (ti = 0; ti < rule->num; ++ti)
        {
          const char *target = rule->targets[ti];
          const char *suffix = rule->suffixes[ti];
          char check_lastslash;

          /* Rules that can match any filename and are not terminal
             are ignored if we're recursing, so that they cannot be
             intermediate files.  */
          if (recursions > 0 && target[1] == '\0' && !rule->terminal)
            continue;

          if (rule->lens[ti] > namelen)
            /* It can't possibly match.  */
            continue;

          /* From the lengths of the filename and the pattern parts,
             find the stem: the part of the filename that matches the %.  */
          stem = filename + (suffix - target - 1);
          stemlen = namelen - rule->lens[ti] + 1;

          /* Set CHECK_LASTSLASH if FILENAME contains a directory
             prefix and the target pattern does not contain a slash.  */

          check_lastslash = 0;
          if (lastslash)
            {
#if MK_OS_VMS
              check_lastslash = strpbrk (target, "/]>:") == NULL;
#else
              check_lastslash = strchr (target, '/') == 0;
#endif
#ifdef HAVE_DOS_PATHS
              /* Didn't find it yet: check for DOS-type directories.  */
              if (check_lastslash)
                {
                  char *b = strchr (target, '\\');
                  check_lastslash = !(b || (target[0] && target[1] == ':'));
                }
#endif
            }
          if (check_lastslash)
            {
              /* If so, don't include the directory prefix in STEM here.  */
              if (pathlen > stemlen)
                continue;
              stemlen -= pathlen;
              stem += pathlen;
            }

          /* Check that the rule pattern matches the text before the stem.  */
          if (check_lastslash)
            {
              if (stem > (lastslash + 1)
                  && !strneq (target, lastslash + 1, stem - lastslash - 1))
                continue;
            }
          else if (stem > filename
                   && !strneq (target, filename, stem - filename))
            continue;

          /* Check that the rule pattern matches the text after the stem.
             We could test simply use streq, but this way we compare the
             first two characters immediately.  This saves time in the very
             common case where the first character matches because it is a
             period.  */
          if (*suffix != stem[stemlen]
              || (*suffix != '\0' && !streq (&suffix[1], &stem[stemlen + 1])))
            continue;

          /* Record if we match a rule that not all filenames will match.  */
          if (target[1] != '\0')
            specific_rule_matched = 1;

          /* A rule with no dependencies and no commands exists solely to set
             specific_rule_matched when it matches.  Don't try to use it.  */
          if (rule->deps == 0 && rule->cmds == 0)
            continue;

          /* Record this rule in TRYRULES and the index of the matching
             target in MATCHES.  If several targets of the same rule match,
             that rule will be in TRYRULES more than once.  */
          tryrules[nrules].rule = rule;
          tryrules[nrules].matches = ti;
          tryrules[nrules].stemlen = stemlen + (check_lastslash ? pathlen : 0);
          tryrules[nrules].order = nrules;
          tryrules[nrules].checked_lastslash = check_lastslash;
          ++nrules;
        }
    }

  /* Bail out early if we haven't found any rules. */
  if (nrules == 0)
    goto done;

  /* Sort the rules to place matches with the shortest stem first. This
     way the most specific rules will be tried first. */
  if (nrules > 1)
    qsort (tryrules, nrules, sizeof (struct tryrule), stemlen_compare);

  /* If we have found a matching rule that won't match all filenames,
     retroactively reject any non-"terminal" rules that do always match.  */
  if (specific_rule_matched)
    for (ri = 0; ri < nrules; ++ri)
      if (!tryrules[ri].rule->terminal)
        {
          unsigned int j;
          for (j = 0; j < tryrules[ri].rule->num; ++j)
            if (tryrules[ri].rule->targets[j][1] == '\0')
              {
                tryrules[ri].rule = 0;
                break;
              }
        }

  /* Try each rule once without intermediate files, then once with them.  */
  for (intermed_ok = 0; intermed_ok < 2; ++intermed_ok)
    {
      pat = deplist;
      if (intermed_ok)
        DBS (DB_IMPLICIT, (_("Trying harder.\n")));

      /* Try each pattern rule till we find one that applies.  If it does,
         expand its dependencies (as substituted) and chain them in DEPS.  */
      for (ri = 0; ri < nrules; ri++)
        {
          struct dep *dep;
          char check_lastslash;
          unsigned int failed = 0;
          int file_variables_set = 0;
          unsigned int deps_found = 0;
          /* NPTR points to the part of the prereq we haven't processed.  */
          const char *nptr = 0;
          int order_only = 0;
          unsigned int matches;

          rule = tryrules[ri].rule;

          /* RULE is nil when we discover that a rule, already placed in
             TRYRULES, should not be applied.  */
          if (rule == 0)
            continue;

          /* Reject any terminal rules if we're looking to make intermediate
             files.  */
          if (intermed_ok && rule->terminal)
            continue;

          /* From the lengths of the filename and the matching pattern parts,
             find the stem: the part of the filename that matches the %.  */
          matches = tryrules[ri].matches;
          stem = filename + (rule->suffixes[matches]
                             - rule->targets[matches]) - 1;
          stemlen = (namelen - rule->lens[matches]) + 1;
          check_lastslash = tryrules[ri].checked_lastslash;
          if (check_lastslash)
            {
              stem += pathlen;
              stemlen -= pathlen;

              /* We need to add the directory prefix, so set it up.  */
              if (! pathdir)
                {
                  pathdir = alloca (pathlen + 1);
                  memcpy (pathdir, filename, pathlen);
                  pathdir[pathlen] = '\0';
                }
            }

          DBS (DB_IMPLICIT,
               (_("Trying pattern rule '%s' with stem '%.*s'.\n"),
                get_rule_defn (rule), (int) stemlen, stem));

          if (stemlen + (check_lastslash ? pathlen : 0) > GET_PATH_MAX)
            {
              DBS (DB_IMPLICIT, (_("Stem too long: '%s%.*s'.\n"),
                                 check_lastslash ? pathdir : "",
                                 (int) stemlen, stem));
              continue;
            }

          if (!check_lastslash)
            {
              memcpy (stem_str, stem, stemlen);
              stem_str[stemlen] = '\0';
            }
          else
            {
              /* We want to prepend the directory from
                 the original FILENAME onto the stem.  */
              memcpy (stem_str, filename, pathlen);
              memcpy (stem_str + pathlen, stem, stemlen);
              stem_str[pathlen + stemlen] = '\0';
            }

          /* If there are no prerequisites, then this rule matches.  */
          if (rule->deps == 0)
            break;

          /* Mark this rule as in use so a recursive pattern_search won't try
             to use it.  */
          rule->in_use = 1;

          /* Try each prerequisite; see if it exists or can be created.  We'll
             build a list of prereq info in DEPLIST.  Due to 2nd expansion we
             may have to process multiple prereqs for a single dep entry.  */

          pat = deplist;
          dep = rule->deps;
          nptr = dep_name (dep);
          while (1)
            {
              struct dep *dl, *d;

              /* If we're out of name to parse, start the next prereq.  */
              if (! nptr)
                {
                  dep = dep->next;
                  if (dep == 0)
                    break;
                  nptr = dep_name (dep);
                }

              /* If we don't need a second expansion, just replace the %.  */
              if (! dep->need_2nd_expansion)
                {
                  char *p;
                  int is_explicit = 1;
                  const char *cp = strchr (nptr, '%');
                  if (cp == 0)
                    strcpy (depname, nptr);
                  else
                    {
                      char *o = depname;
                      if (check_lastslash)
                        o = mempcpy (o, filename, pathlen);
                      o = mempcpy (o, nptr, cp - nptr);
                      o = mempcpy (o, stem, stemlen);
                      strcpy (o, cp + 1);
                      is_explicit = 0;
                    }

                  /* Parse the expanded string.  It might have wildcards.  */
                  p = depname;
                  dl = PARSE_FILE_SEQ (&p, struct dep, MAP_NUL, NULL,
                                       PARSEFS_ONEWORD|PARSEFS_WAIT);
                  for (d = dl; d != NULL; d = d->next)
                    {
                      ++deps_found;
                      d->ignore_mtime = dep->ignore_mtime;
                      d->ignore_automatic_vars = dep->ignore_automatic_vars;
                      d->wait_here |= dep->wait_here;
                      d->is_explicit = is_explicit;
                    }

                  /* We've used up this dep, so next time get a new one.  */
                  nptr = 0;
                }

              /* We have to perform second expansion on this prereq.  In an
                 ideal world we would take the dependency line, substitute the
                 stem, re-expand the whole line and chop it into individual
                 prerequisites.  Unfortunately this won't work because of the
                 "check_lastslash" twist.  Instead, we will have to go word by
                 word, taking $()'s into account.  For each word we will
                 substitute the stem, re-expand, chop it up, and, if
                 check_lastslash != 0, add the directory part to each
                 resulting prerequisite.  */
              else
                {
                  int add_dir = 0;
                  size_t len;
                  const char *end;
                  struct dep **dptr;
                  int is_explicit;
                  const char *cp;
                  char *p;

                  nptr = get_next_word (nptr, &len);
                  if (nptr == 0)
                    continue;
                  end = nptr + len;

                  /* See if this is a transition to order-only prereqs.  */
                  if (! order_only && len == 1 && nptr[0] == '|')
                    {
                      order_only = 1;
                      nptr = end;
                      continue;
                    }

                  /* If the dependency name has %, substitute the stem.  If we
                     just replace % with the stem value then later, when we do
                     the 2nd expansion, we will re-expand this stem value
                     again.  This is not good if you have certain characters
                     in your stem (like $).

                     Instead, we will replace % with $* or $(*F) and allow the
                     second expansion to take care of it for us.  This way
                     (since $* and $(*F) are simple variables) there won't be
                     additional re-expansion of the stem.  */

                  cp = lindex (nptr, end, '%');
                  if (cp == 0)
                    {
                      memcpy (depname, nptr, len);
                      depname[len] = '\0';
                      is_explicit = 1;
                    }
                  else
                    {
                      /* Go through all % between NPTR and END.
                         Copy contents of [NPTR, END) to depname, with the
                         first % after NPTR and then each first % after white
                         space replaced with $* or $(*F).  depname has enough
                         room to substitute each % with $(*F).  */
                      char *o = depname;

                      is_explicit = 0;
                      for (;;)
                        {
                          size_t i = cp - nptr;
                          assert (o + i < dend);
                          o = mempcpy (o, nptr, i);
                          if (check_lastslash)
                            {
                              add_dir = 1;
                              assert (o + 5 < dend);
                              o = mempcpy (o, "$(*F)", 5);
                            }
                          else
                            {
                              assert (o + 2 < dend);
                              o = mempcpy (o, "$*", 2);
                            }
                          assert (o < dend);
                          ++cp;
                          assert (cp <= end);
                          nptr = cp;
                          if (nptr == end)
                            break;

                          /* Skip the rest of this word then find the next %.
                             No need to worry about order-only, or nested
                             functions: NPTR went though get_next_word.  */
                          while (cp < end && ! END_OF_TOKEN (*cp))
                            ++cp;
                          cp = lindex (cp, end, '%');
                          if (cp == 0)
                            break;
                        }
                        len = end - nptr;
                        memcpy (o, nptr, len);
                        o[len] = '\0';
                    }

                  /* Set up for the next word.  */
                  nptr = end;

                  /* Initialize and set file variables if we haven't already
                     done so. */
                  if (!file_vars_initialized)
                    {
                      initialize_file_variables (file, 0);
                      set_file_variables (file, stem_str);
                      file_vars_initialized = 1;
                    }
                  /* Update the stem value in $* for this rule.  */
                  else if (!file_variables_set)
                    {
                      define_variable_for_file (
                        "*", 1, stem_str, o_automatic, 0, file);
                      file_variables_set = 1;
                    }

                  /* Perform the 2nd expansion.  */
                  p = expand_string_for_file (depname, file);
                  dptr = &dl;

                  /* Parse the results into a deps list.  */
                  do
                    {
                      /* Parse the expanded string. */
                      struct dep *dp = PARSE_FILE_SEQ (&p, struct dep,
                                                       order_only ? MAP_NUL : MAP_PIPE,
                                                       add_dir ? pathdir : NULL,
                                                       PARSEFS_WAIT);
                      *dptr = dp;

                      for (d = dp; d != NULL; d = d->next)
                        {
                          ++deps_found;
                          if (order_only)
                            d->ignore_mtime = 1;
                          d->is_explicit = is_explicit;
                          dptr = &d->next;
                        }

                      /* If we stopped due to an order-only token, note it.  */
                      if (*p == '|')
                        {
                          order_only = 1;
                          ++p;
                        }
                    }
                  while (*p != '\0');
                }

              /* If there are more than max_pattern_deps prerequisites (due to
                 2nd expansion), reset it and realloc the arrays.  */

              if (deps_found > max_deps)
                {
                  size_t l = pat - deplist;
                  /* This might have changed due to recursion.  */
                  max_pattern_deps = MAX(max_pattern_deps, deps_found);
                  max_deps = max_pattern_deps;
                  deplist = xrealloc (deplist,
                                      max_deps * sizeof (struct patdeps));
                  pat = deplist + l;
                }

              /* Go through the nameseq and handle each as a prereq name.  */
              for (d = dl; d != 0; d = d->next)
                {
                  struct file *df;
                  int is_rule = d->name == dep_name (dep);
                  int explicit = 0;
                  struct dep *dp = 0;

                  if (file_impossible_p (d->name))
                    {
                      /* If this prereq has already been ruled "impossible",
                         then the rule fails.  Don't bother trying it on the
                         second pass either since we know that will fail.  */
                      DBS (DB_IMPLICIT,
                           (is_rule
                            ? _("Rejecting rule '%s' due to impossible rule"
                                " prerequisite '%s'.\n")
                            : _("Rejecting rule '%s' due to impossible implicit"
                                " prerequisite '%s'.\n"),
                            get_rule_defn (rule), d->name));
                      tryrules[ri].rule = 0;

                      failed = 1;
                      break;
                    }

                  memset (pat, '\0', sizeof (struct patdeps));
                  pat->ignore_mtime = d->ignore_mtime;
                  pat->ignore_automatic_vars = d->ignore_automatic_vars;
                  pat->wait_here = d->wait_here;
                  pat->is_explicit = d->is_explicit;

                  DBS (DB_IMPLICIT,
                       (is_rule
                        ? _("Trying rule prerequisite '%s'.\n")
                        : _("Trying implicit prerequisite '%s'.\n"), d->name));

                  df = lookup_file (d->name);

                  if (df && df->is_explicit)
                    pat->is_explicit = 1;

                  /* If we found a file for the dep, set its intermediate flag.
                     df->is_explicit is set when the dep file is mentioned
                     explicitly on some other rule.  d->is_explicit is set when
                     the dep file is mentioned explicitly on this rule.  E.g.:
                       %.x : %.y ; ...
                     then:
                       one.x:
                       one.y:        # df->is_explicit
                     vs.
                       one.x: one.y  # d->is_explicit
                  */
                  if (df && !df->is_explicit && !d->is_explicit)
                    df->intermediate = 1;

                  /* If the pattern prereq is also explicitly mentioned for
                     FILE, skip all tests below since it must be built no
                     matter which implicit rule we choose. */
                  if (df && df->is_target)
                    /* This prerequisite is mentioned explicitly as a target of
                       some rule.  */
                    explicit = 1;
                  else
                    for (dp = file->deps; dp != 0; dp = dp->next)
                      if (streq (d->name, dep_name (dp)))
                        break;

                  /* If dp is set, this prerequisite is mentioned explicitly as
                     a prerequisite of the current target.  */

                  if (explicit || dp)
                    {
                      (pat++)->name = d->name;
                      DBS (DB_IMPLICIT, (_("'%s' ought to exist.\n"), d->name));
                      continue;
                    }

                  if (file_exists_p (d->name))
                    {
                      (pat++)->name = d->name;
                      DBS (DB_IMPLICIT, (_("Found '%s'.\n"), d->name));
                      continue;
                    }

                  if (df && allow_compat_rules)
                    {
                      (pat++)->name = d->name;
                      DBS (DB_IMPLICIT,
                           (_("Using compatibility rule '%s' due to '%s'.\n"),
                            get_rule_defn (rule), d->name));
                      continue;
                    }

                  if (df)
                    {
                      /* This prerequisite is mentioned explicitly as a
                         prerequisite on some rule, but it is not a
                         prerequisite of the current target. Therefore, this
                         prerequisite does not qualify as ought-to-exist. Keep
                         note of this rule and continue the search.  If a more
                         suitable rule is not found, then use this rule.  */
                      DBS (DB_IMPLICIT,
                           (_("Prerequisite '%s' of rule '%s' does not qualify"
                              " as ought to exist.\n"),
                            d->name, get_rule_defn (rule)));
                      found_compat_rule = 1;
                    }

                  /* This code, given FILENAME = "lib/foo.o", dependency name
                     "lib/foo.c", and VPATH=src, searches for
                     "src/lib/foo.c".  */
                  {
                    const char *vname = vpath_search (d->name, 0, NULL, NULL);
                    if (vname)
                      {
                        DBS (DB_IMPLICIT,
                             (_("Found prerequisite '%s' as VPATH '%s'.\n"),
                              d->name, vname));
                        (pat++)->name = d->name;
                        continue;
                      }
                  }

                  /* We could not find the file in any place we should look.
                     Look for an implicit rule to make this dependency, but
                     only on the second pass.  */

                  if (intermed_ok)
                    {
                      DBS (DB_IMPLICIT,
                           (d->is_explicit || (df && df->is_explicit)
                            ? _("Looking for a rule with explicit file '%s'.\n")
                            : _("Looking for a rule with intermediate file '%s'.\n"),
                            d->name));

                      if (int_file == 0)
                        int_file = alloca (sizeof (struct file));
                      memset (int_file, '\0', sizeof (struct file));
                      int_file->name = d->name;

                      if (pattern_search (int_file,
                                          0,
                                          depth,
                                          recursions + 1,
                                          allow_compat_rules))
                        {
                          pat->pattern = int_file->name;
                          int_file->name = d->name;
                          pat->file = int_file;
                          int_file = 0;
                          (pat++)->name = d->name;
                          continue;
                        }

                      /* If we have tried to find P as an intermediate file
                         and failed, mark that name as impossible so we won't
                         go through the search again later.  */
                      if (int_file->variables)
                        free_variable_set (int_file->variables);
                      if (int_file->pat_variables)
                        free_variable_set (int_file->pat_variables);

                      /* Keep prerequisites explicitly mentioned on unrelated
                         rules as "possible" to let compatibility search find
                         such prerequisites.  */
                      if (df == 0)
                        file_impossible (d->name);
                    }

                  /* A dependency of this rule does not exist. Therefore, this
                     rule fails.  */
                  if (intermed_ok)
                    DBS (DB_IMPLICIT,
                         (_("Rejecting rule '%s' "
                            "due to impossible prerequisite '%s'.\n"),
                          get_rule_defn (rule), d->name));
                  else
                    DBS (DB_IMPLICIT, (_("Not found '%s'.\n"), d->name));

                  failed = 1;
                  break;
                }

              /* Free the ns chain.  */
              free_dep_chain (dl);

              if (failed)
                break;
            }

          /* This rule is no longer 'in use' for recursive searches.  */
          rule->in_use = 0;

          if (! failed)
            /* This pattern rule does apply.  Stop looking for one.  */
            break;

          /* This pattern rule does not apply.  Keep looking.  */
        }

      /* If we found an applicable rule without intermediate files, don't try
         with them.  */
      if (ri < nrules)
        break;

      rule = 0;
    }

  /* RULE is nil if the loop went through the list but everything failed.  */
  if (rule == 0)
    goto done;

  foundrule = ri;

  /* If we are recursing, store the pattern that matched FILENAME in
     FILE->name for use in upper levels.  */

  if (recursions > 0)
    /* Kludge-o-matic */
    file->name = rule->targets[tryrules[foundrule].matches];

  /* DEPLIST lists the prerequisites for the rule we found.  This includes the
     intermediate files, if any.  Convert them into entries on the deps-chain
     of FILE.  */

  while (pat-- > deplist)
    {
      struct dep *dep;
      const char *s;

      if (pat->file != 0)
        {
          /* If we need to use an intermediate file, make sure it is entered
             as a target, with the info that was found for it in the recursive
             pattern_search call.  We know that the intermediate file did not
             already exist as a target; therefore we can assume that the deps
             and cmds of F below are null before we change them.  */

          struct file *imf = pat->file;
          struct file *f = lookup_file (imf->name);

          if (!f)
            f = enter_file (imf->name);

          f->deps = imf->deps;
          f->cmds = imf->cmds;
          f->stem = imf->stem;
          /* Setting target specific variables for a file causes the file to be
             entered to the database as a prerequisite. Implicit search then
             treats this file as explicitly mentioned. Preserve target specific
             variables of this file.  */
          merge_variable_set_lists(&f->variables, imf->variables);
          f->pat_variables = imf->pat_variables;
          f->pat_searched = imf->pat_searched;
          f->also_make = imf->also_make;
          f->is_target = 1;
          f->is_explicit |= imf->is_explicit || pat->is_explicit;
          f->notintermediate |= imf->notintermediate || no_intermediates;
          f->intermediate |= !f->is_explicit && !f->notintermediate;
          f->tried_implicit = 1;

          imf = lookup_file (pat->pattern);
          if (imf != 0 && imf->precious)
            f->precious = 1;

          for (dep = f->deps; dep != 0; dep = dep->next)
            {
              dep->file = enter_file (dep->name);
              dep->name = 0;
              dep->file->tried_implicit |= dep->changed;
            }
        }

      dep = alloc_dep ();
      dep->ignore_mtime = pat->ignore_mtime;
      dep->is_explicit = pat->is_explicit;
      dep->ignore_automatic_vars = pat->ignore_automatic_vars;
      dep->wait_here = pat->wait_here;
      s = strcache_add (pat->name);
      if (recursions)
        dep->name = s;
      else
        {
          dep->file = lookup_file (s);
          if (dep->file == 0)
            dep->file = enter_file (s);
        }

      if (pat->file == 0 && tryrules[foundrule].rule->terminal)
        {
          /* If the file actually existed (was not an intermediate file), and
             the rule that found it was a terminal one, then we want to mark
             the found file so that it will not have implicit rule search done
             for it.  If we are not entering a 'struct file' for it now, we
             indicate this with the 'changed' flag.  */
          if (dep->file == 0)
            dep->changed = 1;
          else
            dep->file->tried_implicit = 1;
        }

      dep->next = file->deps;
      file->deps = dep;

      /* The file changed its dependencies; schedule the shuffle.  */
      file->was_shuffled = 0;
    }

  if (!file->was_shuffled)
    shuffle_deps_recursive (file->deps);

  if (!tryrules[foundrule].checked_lastslash)
    {
      /* Always allocate new storage, since STEM might be on the stack for an
         intermediate file.  */
      file->stem = strcache_add_len (stem, stemlen);
      fullstemlen = stemlen;
    }
  else
    {
      /* We want to prepend the directory from
         the original FILENAME onto the stem.  */
      fullstemlen = pathlen + stemlen;
      memcpy (stem_str, filename, pathlen);
      memcpy (stem_str + pathlen, stem, stemlen);
      stem_str[fullstemlen] = '\0';
      file->stem = strcache_add (stem_str);
    }

  file->cmds = rule->cmds;
  file->is_target = 1;

  /* Set precious and notintermediate flags. */
  {
    struct file *f = lookup_file (rule->targets[tryrules[foundrule].matches]);
    if (f)
      {
        if (f->precious)
          file->precious = 1;
        if (f->notintermediate || no_intermediates)
          file->notintermediate = 1;
      }
  }

  /* If this rule builds other targets, too, put the others into FILE's
     'also_make' member.  */

  if (rule->num > 1)
    for (ri = 0; ri < rule->num; ++ri)
      if (ri != tryrules[foundrule].matches)
        {
          char *nm = alloca (rule->lens[ri] + fullstemlen + 1);
          char *p = nm;
          struct file *f;
          struct dep *new = alloc_dep ();

          /* GKM FIMXE: handle '|' here too */
          p = mempcpy (p, rule->targets[ri],
                       rule->suffixes[ri] - rule->targets[ri] - 1);
          p = mempcpy (p, file->stem, fullstemlen);
          memcpy (p, rule->suffixes[ri],
                  rule->lens[ri] - (rule->suffixes[ri] - rule->targets[ri])+1);
          new->name = strcache_add (nm);
          new->file = enter_file (new->name);
          new->next = file->also_make;

          /* Set precious flag. */
          f = lookup_file (rule->targets[ri]);
          if (f)
            {
              if (f->precious)
                new->file->precious = 1;
              if (f->notintermediate || no_intermediates)
                new->file->notintermediate = 1;
            }

          /* Set the is_target flag so that this file is not treated as
             intermediate by the pattern rule search algorithm and
             file_exists_p cannot pick it up yet.  */
          new->file->is_target = 1;

          file->also_make = new;
        }

 done:
  free (tryrules);
  free (deplist);

  --depth;

  if (rule)
    {
      DBS (DB_IMPLICIT, (_("Found implicit rule '%s' for '%s'.\n"),
                         get_rule_defn (rule), filename));
      return 1;
    }

  if (found_compat_rule)
    {
      DBS (DB_IMPLICIT, (_("Searching for a compatibility rule for '%s'.\n"),
                         filename));
      assert (allow_compat_rules == 0);
      return pattern_search (file, archive, depth, recursions, 1);
    }

  DBS (DB_IMPLICIT, (_("No implicit rule found for '%s'.\n"), filename));
  return 0;
}
