Blame rule.c

Packit 26a39e
/* Pattern and suffix rule internals for GNU Make.
Packit 26a39e
Copyright (C) 1988-2016 Free Software Foundation, Inc.
Packit 26a39e
This file is part of GNU Make.
Packit 26a39e
Packit 26a39e
GNU Make is free software; you can redistribute it and/or modify it under the
Packit 26a39e
terms of the GNU General Public License as published by the Free Software
Packit 26a39e
Foundation; either version 3 of the License, or (at your option) any later
Packit 26a39e
version.
Packit 26a39e
Packit 26a39e
GNU Make is distributed in the hope that it will be useful, but WITHOUT ANY
Packit 26a39e
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
Packit 26a39e
A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
Packit 26a39e
Packit 26a39e
You should have received a copy of the GNU General Public License along with
Packit 26a39e
this program.  If not, see <http://www.gnu.org/licenses/>.  */
Packit 26a39e
Packit 26a39e
#include "makeint.h"
Packit 26a39e
Packit 26a39e
#include <assert.h>
Packit 26a39e
Packit 26a39e
#include "filedef.h"
Packit 26a39e
#include "dep.h"
Packit 26a39e
#include "job.h"
Packit 26a39e
#include "commands.h"
Packit 26a39e
#include "variable.h"
Packit 26a39e
#include "rule.h"
Packit 26a39e
Packit 26a39e
static void freerule (struct rule *rule, struct rule *lastrule);
Packit 26a39e

Packit 26a39e
/* Chain of all pattern rules.  */
Packit 26a39e
Packit 26a39e
struct rule *pattern_rules;
Packit 26a39e
Packit 26a39e
/* Pointer to last rule in the chain, so we can add onto the end.  */
Packit 26a39e
Packit 26a39e
struct rule *last_pattern_rule;
Packit 26a39e
Packit 26a39e
/* Number of rules in the chain.  */
Packit 26a39e
Packit 26a39e
unsigned int num_pattern_rules;
Packit 26a39e
Packit 26a39e
/* Maximum number of target patterns of any pattern rule.  */
Packit 26a39e
Packit 26a39e
unsigned int max_pattern_targets;
Packit 26a39e
Packit 26a39e
/* Maximum number of dependencies of any pattern rule.  */
Packit 26a39e
Packit 26a39e
unsigned int max_pattern_deps;
Packit 26a39e
Packit 26a39e
/* Maximum length of the name of a dependencies of any pattern rule.  */
Packit 26a39e
Packit 26a39e
unsigned int max_pattern_dep_length;
Packit 26a39e
Packit 26a39e
/* Pointer to structure for the file .SUFFIXES
Packit 26a39e
   whose dependencies are the suffixes to be searched.  */
Packit 26a39e
Packit 26a39e
struct file *suffix_file;
Packit 26a39e
Packit 26a39e
/* Maximum length of a suffix.  */
Packit 26a39e
Packit 26a39e
unsigned int maxsuffix;
Packit 26a39e

Packit 26a39e
/* Compute the maximum dependency length and maximum number of
Packit 26a39e
   dependencies of all implicit rules.  Also sets the subdir
Packit 26a39e
   flag for a rule when appropriate, possibly removing the rule
Packit 26a39e
   completely when appropriate.  */
Packit 26a39e
Packit 26a39e
void
Packit 26a39e
count_implicit_rule_limits (void)
Packit 26a39e
{
Packit 26a39e
  char *name;
Packit 26a39e
  int namelen;
Packit 26a39e
  struct rule *rule;
Packit 26a39e
Packit 26a39e
  num_pattern_rules = max_pattern_targets = max_pattern_deps = 0;
Packit 26a39e
  max_pattern_dep_length = 0;
Packit 26a39e
Packit 26a39e
  name = 0;
Packit 26a39e
  namelen = 0;
Packit 26a39e
  rule = pattern_rules;
Packit 26a39e
  while (rule != 0)
Packit 26a39e
    {
Packit 26a39e
      unsigned int ndeps = 0;
Packit 26a39e
      struct dep *dep;
Packit 26a39e
      struct rule *next = rule->next;
Packit 26a39e
Packit 26a39e
      ++num_pattern_rules;
Packit 26a39e
Packit 26a39e
      if (rule->num > max_pattern_targets)
Packit 26a39e
        max_pattern_targets = rule->num;
Packit 26a39e
Packit 26a39e
      for (dep = rule->deps; dep != 0; dep = dep->next)
Packit 26a39e
        {
Packit 26a39e
          const char *dname = dep_name (dep);
Packit 26a39e
          unsigned int len = strlen (dname);
Packit 26a39e
Packit 26a39e
#ifdef VMS
Packit 26a39e
          const char *p = strrchr (dname, ']');
Packit 26a39e
          const char *p2;
Packit 26a39e
          if (p == 0)
Packit 26a39e
            p = strrchr (dname, ':');
Packit 26a39e
          p2 = p != 0 ? strchr (dname, '%') : 0;
Packit 26a39e
#else
Packit 26a39e
          const char *p = strrchr (dname, '/');
Packit 26a39e
          const char *p2 = p != 0 ? strchr (dname, '%') : 0;
Packit 26a39e
#endif
Packit 26a39e
          ndeps++;
Packit 26a39e
Packit 26a39e
          if (len > max_pattern_dep_length)
Packit 26a39e
            max_pattern_dep_length = len;
Packit 26a39e
Packit 26a39e
          if (p != 0 && p2 > p)
Packit 26a39e
            {
Packit 26a39e
              /* There is a slash before the % in the dep name.
Packit 26a39e
                 Extract the directory name.  */
Packit 26a39e
              if (p == dname)
Packit 26a39e
                ++p;
Packit 26a39e
              if (p - dname > namelen)
Packit 26a39e
                {
Packit 26a39e
                  namelen = p - dname;
Packit 26a39e
                  name = xrealloc (name, namelen + 1);
Packit 26a39e
                }
Packit 26a39e
              memcpy (name, dname, p - dname);
Packit 26a39e
              name[p - dname] = '\0';
Packit 26a39e
Packit 26a39e
              /* In the deps of an implicit rule the 'changed' flag
Packit 26a39e
                 actually indicates that the dependency is in a
Packit 26a39e
                 nonexistent subdirectory.  */
Packit 26a39e
Packit 26a39e
              dep->changed = !dir_file_exists_p (name, "");
Packit 26a39e
            }
Packit 26a39e
          else
Packit 26a39e
            /* This dependency does not reside in a subdirectory.  */
Packit 26a39e
            dep->changed = 0;
Packit 26a39e
        }
Packit 26a39e
Packit 26a39e
      if (ndeps > max_pattern_deps)
Packit 26a39e
        max_pattern_deps = ndeps;
Packit 26a39e
Packit 26a39e
      rule = next;
Packit 26a39e
    }
Packit 26a39e
Packit 26a39e
  free (name);
Packit 26a39e
}
Packit 26a39e

Packit 26a39e
/* Create a pattern rule from a suffix rule.
Packit 26a39e
   TARGET is the target suffix; SOURCE is the source suffix.
Packit 26a39e
   CMDS are the commands.
Packit 26a39e
   If TARGET is nil, it means the target pattern should be '(%.o)'.
Packit 26a39e
   If SOURCE is nil, it means there should be no deps.  */
Packit 26a39e
Packit 26a39e
static void
Packit 26a39e
convert_suffix_rule (const char *target, const char *source,
Packit 26a39e
                     struct commands *cmds)
Packit 26a39e
{
Packit 26a39e
  const char **names, **percents;
Packit 26a39e
  struct dep *deps;
Packit 26a39e
Packit 26a39e
  names = xmalloc (sizeof (const char *));
Packit 26a39e
  percents = xmalloc (sizeof (const char *));
Packit 26a39e
Packit 26a39e
  if (target == 0)
Packit 26a39e
    {
Packit 26a39e
      /* Special case: TARGET being nil means we are defining a '.X.a' suffix
Packit 26a39e
         rule; the target pattern is always '(%.o)'.  */
Packit 26a39e
#ifdef VMS
Packit 26a39e
      *names = strcache_add_len ("(%.obj)", 7);
Packit 26a39e
#else
Packit 26a39e
      *names = strcache_add_len ("(%.o)", 5);
Packit 26a39e
#endif
Packit 26a39e
      *percents = *names + 1;
Packit 26a39e
    }
Packit 26a39e
  else
Packit 26a39e
    {
Packit 26a39e
      /* Construct the target name.  */
Packit 26a39e
      unsigned int len = strlen (target);
Packit 26a39e
      char *p = alloca (1 + len + 1);
Packit 26a39e
      p[0] = '%';
Packit 26a39e
      memcpy (p + 1, target, len + 1);
Packit 26a39e
      *names = strcache_add_len (p, len + 1);
Packit 26a39e
      *percents = *names;
Packit 26a39e
    }
Packit 26a39e
Packit 26a39e
  if (source == 0)
Packit 26a39e
    deps = 0;
Packit 26a39e
  else
Packit 26a39e
    {
Packit 26a39e
      /* Construct the dependency name.  */
Packit 26a39e
      unsigned int len = strlen (source);
Packit 26a39e
      char *p = alloca (1 + len + 1);
Packit 26a39e
      p[0] = '%';
Packit 26a39e
      memcpy (p + 1, source, len + 1);
Packit 26a39e
      deps = alloc_dep ();
Packit 26a39e
      deps->name = strcache_add_len (p, len + 1);
Packit 26a39e
    }
Packit 26a39e
Packit 26a39e
  create_pattern_rule (names, percents, 1, 0, deps, cmds, 0);
Packit 26a39e
}
Packit 26a39e
Packit 26a39e
/* Convert old-style suffix rules to pattern rules.
Packit 26a39e
   All rules for the suffixes on the .SUFFIXES list are converted and added to
Packit 26a39e
   the chain of pattern rules.  */
Packit 26a39e
Packit 26a39e
void
Packit 26a39e
convert_to_pattern (void)
Packit 26a39e
{
Packit 26a39e
  struct dep *d, *d2;
Packit 26a39e
  char *rulename;
Packit 26a39e
Packit 26a39e
  /* We will compute every potential suffix rule (.x.y) from the list of
Packit 26a39e
     suffixes in the .SUFFIXES target's dependencies and see if it exists.
Packit 26a39e
     First find the longest of the suffixes.  */
Packit 26a39e
Packit 26a39e
  maxsuffix = 0;
Packit 26a39e
  for (d = suffix_file->deps; d != 0; d = d->next)
Packit 26a39e
    {
Packit 26a39e
      unsigned int l = strlen (dep_name (d));
Packit 26a39e
      if (l > maxsuffix)
Packit 26a39e
        maxsuffix = l;
Packit 26a39e
    }
Packit 26a39e
Packit 26a39e
  /* Space to construct the suffix rule target name.  */
Packit 26a39e
  rulename = alloca ((maxsuffix * 2) + 1);
Packit 26a39e
Packit 26a39e
  for (d = suffix_file->deps; d != 0; d = d->next)
Packit 26a39e
    {
Packit 26a39e
      unsigned int slen;
Packit 26a39e
Packit 26a39e
      /* Make a rule that is just the suffix, with no deps or commands.
Packit 26a39e
         This rule exists solely to disqualify match-anything rules.  */
Packit 26a39e
      convert_suffix_rule (dep_name (d), 0, 0);
Packit 26a39e
Packit 26a39e
      if (d->file->cmds != 0)
Packit 26a39e
        /* Record a pattern for this suffix's null-suffix rule.  */
Packit 26a39e
        convert_suffix_rule ("", dep_name (d), d->file->cmds);
Packit 26a39e
Packit 26a39e
      /* Add every other suffix to this one and see if it exists as a
Packit 26a39e
         two-suffix rule.  */
Packit 26a39e
      slen = strlen (dep_name (d));
Packit 26a39e
      memcpy (rulename, dep_name (d), slen);
Packit 26a39e
Packit 26a39e
      for (d2 = suffix_file->deps; d2 != 0; d2 = d2->next)
Packit 26a39e
        {
Packit 26a39e
          struct file *f;
Packit 26a39e
          unsigned int s2len;
Packit 26a39e
Packit 26a39e
          s2len = strlen (dep_name (d2));
Packit 26a39e
Packit 26a39e
          /* Can't build something from itself.  */
Packit 26a39e
          if (slen == s2len && streq (dep_name (d), dep_name (d2)))
Packit 26a39e
            continue;
Packit 26a39e
Packit 26a39e
          memcpy (rulename + slen, dep_name (d2), s2len + 1);
Packit 26a39e
          f = lookup_file (rulename);
Packit 26a39e
          if (f == 0 || f->cmds == 0)
Packit 26a39e
            continue;
Packit 26a39e
Packit 26a39e
          if (s2len == 2 && rulename[slen] == '.' && rulename[slen + 1] == 'a')
Packit 26a39e
            /* A suffix rule '.X.a:' generates the pattern rule '(%.o): %.X'.
Packit 26a39e
               It also generates a normal '%.a: %.X' rule below.  */
Packit 26a39e
            convert_suffix_rule (NULL, /* Indicates '(%.o)'.  */
Packit 26a39e
                                 dep_name (d),
Packit 26a39e
                                 f->cmds);
Packit 26a39e
Packit 26a39e
          /* The suffix rule '.X.Y:' is converted
Packit 26a39e
             to the pattern rule '%.Y: %.X'.  */
Packit 26a39e
          convert_suffix_rule (dep_name (d2), dep_name (d), f->cmds);
Packit 26a39e
        }
Packit 26a39e
    }
Packit 26a39e
}
Packit 26a39e
Packit 26a39e
Packit 26a39e
/* Install the pattern rule RULE (whose fields have been filled in) at the end
Packit 26a39e
   of the list (so that any rules previously defined will take precedence).
Packit 26a39e
   If this rule duplicates a previous one (identical target and dependencies),
Packit 26a39e
   the old one is replaced if OVERRIDE is nonzero, otherwise this new one is
Packit 26a39e
   thrown out.  When an old rule is replaced, the new one is put at the end of
Packit 26a39e
   the list.  Return nonzero if RULE is used; zero if not.  */
Packit 26a39e
Packit 26a39e
static int
Packit 26a39e
new_pattern_rule (struct rule *rule, int override)
Packit 26a39e
{
Packit 26a39e
  struct rule *r, *lastrule;
Packit 26a39e
  unsigned int i, j;
Packit 26a39e
Packit 26a39e
  rule->in_use = 0;
Packit 26a39e
  rule->terminal = 0;
Packit 26a39e
Packit 26a39e
  rule->next = 0;
Packit 26a39e
Packit 26a39e
  /* Search for an identical rule.  */
Packit 26a39e
  lastrule = 0;
Packit 26a39e
  for (r = pattern_rules; r != 0; lastrule = r, r = r->next)
Packit 26a39e
    for (i = 0; i < rule->num; ++i)
Packit 26a39e
      {
Packit 26a39e
        for (j = 0; j < r->num; ++j)
Packit 26a39e
          if (!streq (rule->targets[i], r->targets[j]))
Packit 26a39e
            break;
Packit 26a39e
        /* If all the targets matched...  */
Packit 26a39e
        if (j == r->num)
Packit 26a39e
          {
Packit 26a39e
            struct dep *d, *d2;
Packit 26a39e
            for (d = rule->deps, d2 = r->deps;
Packit 26a39e
                 d != 0 && d2 != 0; d = d->next, d2 = d2->next)
Packit 26a39e
              if (!streq (dep_name (d), dep_name (d2)))
Packit 26a39e
                break;
Packit 26a39e
            if (d == 0 && d2 == 0)
Packit 26a39e
              {
Packit 26a39e
                /* All the dependencies matched.  */
Packit 26a39e
                if (override)
Packit 26a39e
                  {
Packit 26a39e
                    /* Remove the old rule.  */
Packit 26a39e
                    freerule (r, lastrule);
Packit 26a39e
                    /* Install the new one.  */
Packit 26a39e
                    if (pattern_rules == 0)
Packit 26a39e
                      pattern_rules = rule;
Packit 26a39e
                    else
Packit 26a39e
                      last_pattern_rule->next = rule;
Packit 26a39e
                    last_pattern_rule = rule;
Packit 26a39e
Packit 26a39e
                    /* We got one.  Stop looking.  */
Packit 26a39e
                    goto matched;
Packit 26a39e
                  }
Packit 26a39e
                else
Packit 26a39e
                  {
Packit 26a39e
                    /* The old rule stays intact.  Destroy the new one.  */
Packit 26a39e
                    freerule (rule, (struct rule *) 0);
Packit 26a39e
                    return 0;
Packit 26a39e
                  }
Packit 26a39e
              }
Packit 26a39e
          }
Packit 26a39e
      }
Packit 26a39e
Packit 26a39e
 matched:;
Packit 26a39e
Packit 26a39e
  if (r == 0)
Packit 26a39e
    {
Packit 26a39e
      /* There was no rule to replace.  */
Packit 26a39e
      if (pattern_rules == 0)
Packit 26a39e
        pattern_rules = rule;
Packit 26a39e
      else
Packit 26a39e
        last_pattern_rule->next = rule;
Packit 26a39e
      last_pattern_rule = rule;
Packit 26a39e
    }
Packit 26a39e
Packit 26a39e
  return 1;
Packit 26a39e
}
Packit 26a39e
Packit 26a39e
Packit 26a39e
/* Install an implicit pattern rule based on the three text strings
Packit 26a39e
   in the structure P points to.  These strings come from one of
Packit 26a39e
   the arrays of default implicit pattern rules.
Packit 26a39e
   TERMINAL specifies what the 'terminal' field of the rule should be.  */
Packit 26a39e
Packit 26a39e
void
Packit 26a39e
install_pattern_rule (struct pspec *p, int terminal)
Packit 26a39e
{
Packit 26a39e
  struct rule *r;
Packit 26a39e
  const char *ptr;
Packit 26a39e
Packit 26a39e
  r = xmalloc (sizeof (struct rule));
Packit 26a39e
Packit 26a39e
  r->num = 1;
Packit 26a39e
  r->targets = xmalloc (sizeof (const char *));
Packit 26a39e
  r->suffixes = xmalloc (sizeof (const char *));
Packit 26a39e
  r->lens = xmalloc (sizeof (unsigned int));
Packit 26a39e
Packit 26a39e
  r->lens[0] = strlen (p->target);
Packit 26a39e
  r->targets[0] = p->target;
Packit 26a39e
  r->suffixes[0] = find_percent_cached (&r->targets[0]);
Packit 26a39e
  assert (r->suffixes[0] != NULL);
Packit 26a39e
  ++r->suffixes[0];
Packit 26a39e
Packit 26a39e
  ptr = p->dep;
Packit 26a39e
  r->deps = PARSE_SIMPLE_SEQ ((char **)&ptr, struct dep);
Packit 26a39e
Packit 26a39e
  if (new_pattern_rule (r, 0))
Packit 26a39e
    {
Packit 26a39e
      r->terminal = terminal;
Packit 26a39e
      r->cmds = xmalloc (sizeof (struct commands));
Packit 26a39e
      r->cmds->fileinfo.filenm = 0;
Packit 26a39e
      r->cmds->fileinfo.lineno = 0;
Packit 26a39e
      r->cmds->fileinfo.offset = 0;
Packit 26a39e
      /* These will all be string literals, but we malloc space for them
Packit 26a39e
         anyway because somebody might want to free them later.  */
Packit 26a39e
      r->cmds->commands = xstrdup (p->commands);
Packit 26a39e
      r->cmds->command_lines = 0;
Packit 26a39e
      r->cmds->recipe_prefix = RECIPEPREFIX_DEFAULT;
Packit 26a39e
    }
Packit 26a39e
}
Packit 26a39e
Packit 26a39e
Packit 26a39e
/* Free all the storage used in RULE and take it out of the
Packit 26a39e
   pattern_rules chain.  LASTRULE is the rule whose next pointer
Packit 26a39e
   points to RULE.  */
Packit 26a39e
Packit 26a39e
static void
Packit 26a39e
freerule (struct rule *rule, struct rule *lastrule)
Packit 26a39e
{
Packit 26a39e
  struct rule *next = rule->next;
Packit 26a39e
Packit 26a39e
  free_dep_chain (rule->deps);
Packit 26a39e
Packit 26a39e
  /* MSVC erroneously warns without a cast here.  */
Packit 26a39e
  free ((void *)rule->targets);
Packit 26a39e
  free ((void *)rule->suffixes);
Packit 26a39e
  free (rule->lens);
Packit 26a39e
Packit 26a39e
  /* We can't free the storage for the commands because there
Packit 26a39e
     are ways that they could be in more than one place:
Packit 26a39e
       * If the commands came from a suffix rule, they could also be in
Packit 26a39e
       the 'struct file's for other suffix rules or plain targets given
Packit 26a39e
       on the same makefile line.
Packit 26a39e
       * If two suffixes that together make a two-suffix rule were each
Packit 26a39e
       given twice in the .SUFFIXES list, and in the proper order, two
Packit 26a39e
       identical pattern rules would be created and the second one would
Packit 26a39e
       be discarded here, but both would contain the same 'struct commands'
Packit 26a39e
       pointer from the 'struct file' for the suffix rule.  */
Packit 26a39e
Packit 26a39e
  free (rule);
Packit 26a39e
Packit 26a39e
  if (pattern_rules == rule)
Packit 26a39e
    if (lastrule != 0)
Packit 26a39e
      abort ();
Packit 26a39e
    else
Packit 26a39e
      pattern_rules = next;
Packit 26a39e
  else if (lastrule != 0)
Packit 26a39e
    lastrule->next = next;
Packit 26a39e
  if (last_pattern_rule == rule)
Packit 26a39e
    last_pattern_rule = lastrule;
Packit 26a39e
}
Packit 26a39e

Packit 26a39e
/* Create a new pattern rule with the targets in the nil-terminated array
Packit 26a39e
   TARGETS.  TARGET_PERCENTS is an array of pointers to the % in each element
Packit 26a39e
   of TARGETS.  N is the number of items in the array (not counting the nil
Packit 26a39e
   element).  The new rule has dependencies DEPS and commands from COMMANDS.
Packit 26a39e
   It is a terminal rule if TERMINAL is nonzero.  This rule overrides
Packit 26a39e
   identical rules with different commands if OVERRIDE is nonzero.
Packit 26a39e
Packit 26a39e
   The storage for TARGETS and its elements and TARGET_PERCENTS is used and
Packit 26a39e
   must not be freed until the rule is destroyed.  */
Packit 26a39e
Packit 26a39e
void
Packit 26a39e
create_pattern_rule (const char **targets, const char **target_percents,
Packit 26a39e
                     unsigned int n, int terminal, struct dep *deps,
Packit 26a39e
                     struct commands *commands, int override)
Packit 26a39e
{
Packit 26a39e
  unsigned int i;
Packit 26a39e
  struct rule *r = xmalloc (sizeof (struct rule));
Packit 26a39e
Packit 26a39e
  r->num = n;
Packit 26a39e
  r->cmds = commands;
Packit 26a39e
  r->deps = deps;
Packit 26a39e
  r->targets = targets;
Packit 26a39e
  r->suffixes = target_percents;
Packit 26a39e
  r->lens = xmalloc (n * sizeof (unsigned int));
Packit 26a39e
Packit 26a39e
  for (i = 0; i < n; ++i)
Packit 26a39e
    {
Packit 26a39e
      r->lens[i] = strlen (targets[i]);
Packit 26a39e
      assert (r->suffixes[i] != NULL);
Packit 26a39e
      ++r->suffixes[i];
Packit 26a39e
    }
Packit 26a39e
Packit 26a39e
  if (new_pattern_rule (r, override))
Packit 26a39e
    r->terminal = terminal;
Packit 26a39e
}
Packit 26a39e

Packit 26a39e
/* Print the data base of rules.  */
Packit 26a39e
Packit 26a39e
static void                     /* Useful to call from gdb.  */
Packit 26a39e
print_rule (struct rule *r)
Packit 26a39e
{
Packit 26a39e
  unsigned int i;
Packit 26a39e
Packit 26a39e
  for (i = 0; i < r->num; ++i)
Packit 26a39e
    {
Packit 26a39e
      fputs (r->targets[i], stdout);
Packit 26a39e
      putchar ((i + 1 == r->num) ? ':' : ' ');
Packit 26a39e
    }
Packit 26a39e
  if (r->terminal)
Packit 26a39e
    putchar (':');
Packit 26a39e
Packit 26a39e
  print_prereqs (r->deps);
Packit 26a39e
Packit 26a39e
  if (r->cmds != 0)
Packit 26a39e
    print_commands (r->cmds);
Packit 26a39e
}
Packit 26a39e
Packit 26a39e
void
Packit 26a39e
print_rule_data_base (void)
Packit 26a39e
{
Packit 26a39e
  unsigned int rules, terminal;
Packit 26a39e
  struct rule *r;
Packit 26a39e
Packit 26a39e
  puts (_("\n# Implicit Rules"));
Packit 26a39e
Packit 26a39e
  rules = terminal = 0;
Packit 26a39e
  for (r = pattern_rules; r != 0; r = r->next)
Packit 26a39e
    {
Packit 26a39e
      ++rules;
Packit 26a39e
Packit 26a39e
      putchar ('\n');
Packit 26a39e
      print_rule (r);
Packit 26a39e
Packit 26a39e
      if (r->terminal)
Packit 26a39e
        ++terminal;
Packit 26a39e
    }
Packit 26a39e
Packit 26a39e
  if (rules == 0)
Packit 26a39e
    puts (_("\n# No implicit rules."));
Packit 26a39e
  else
Packit 26a39e
    {
Packit 26a39e
      printf (_("\n# %u implicit rules, %u"), rules, terminal);
Packit 26a39e
#ifndef NO_FLOAT
Packit 26a39e
      printf (" (%.1f%%)", (double) terminal / (double) rules * 100.0);
Packit 26a39e
#else
Packit 26a39e
      {
Packit 26a39e
        int f = (terminal * 1000 + 5) / rules;
Packit 26a39e
        printf (" (%d.%d%%)", f/10, f%10);
Packit 26a39e
      }
Packit 26a39e
#endif
Packit 26a39e
      puts (_(" terminal."));
Packit 26a39e
    }
Packit 26a39e
Packit 26a39e
  if (num_pattern_rules != rules)
Packit 26a39e
    {
Packit 26a39e
      /* This can happen if a fatal error was detected while reading the
Packit 26a39e
         makefiles and thus count_implicit_rule_limits wasn't called yet.  */
Packit 26a39e
      if (num_pattern_rules != 0)
Packit 26a39e
        ONN (fatal, NILF, _("BUG: num_pattern_rules is wrong!  %u != %u"),
Packit 26a39e
             num_pattern_rules, rules);
Packit 26a39e
    }
Packit 26a39e
}