/[make]/make/implicit.c
ViewVC logotype

Diff of /make/implicit.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.41 by bosk, Tue Sep 21 20:23:12 2004 UTC revision 1.42 by bosk, Sun Feb 27 21:40:24 2005 UTC
# Line 22  Boston, MA 02111-1307, USA.  */ Line 22  Boston, MA 02111-1307, USA.  */
22  #include "rule.h"  #include "rule.h"
23  #include "dep.h"  #include "dep.h"
24  #include "debug.h"  #include "debug.h"
25    #include "variable.h"
26    #include "job.h"      /* struct child, used inside commands.h */
27    #include "commands.h" /* set_file_variables */
28    
29  static int pattern_search PARAMS ((struct file *file, int archive, unsigned int depth,  static int
30                  unsigned int recursions));  pattern_search PARAMS ((struct file *file, int archive,
31                            unsigned int depth, unsigned int recursions));
32    
33  /* For a FILE which has no commands specified, try to figure out some  /* For a FILE which has no commands specified, try to figure out some
34     from the implicit pattern rules.     from the implicit pattern rules.
# Line 61  try_implicit_rule (struct file *file, un Line 65  try_implicit_rule (struct file *file, un
65  }  }
66    
67    
68    /* Struct idep captures information about implicit prerequisites
69       that come from implicit rules. */
70    struct idep
71    {
72      struct idep *next;              /* struct dep -compatible interface */
73      char *name;                     /* name of the prerequisite */
74      struct file *intermediate_file; /* intermediate file, 0 otherwise */
75      char *intermediate_pattern;     /* pattern for intermediate file */
76      unsigned char had_stem;         /* had % substituted with stem */
77      unsigned char ignore_mtime;     /* ignore_mtime flag */
78    };
79    
80    static void
81    free_idep_chain (struct idep* p)
82    {
83      register struct idep* n;
84      register struct file *f;
85    
86      for (; p != 0; p = n)
87        {
88          n = p->next;
89    
90          if (p->name)
91            {
92              free (p->name);
93    
94              f = p->intermediate_file;
95    
96              if (f != 0
97                  && (f->stem < f->name
98                      || f->stem > f->name + strlen (f->name)))
99                free (f->stem);
100            }
101    
102          free (p);
103        }
104    }
105    
106    
107    /* Scans the BUFFER for the next word with whitespace as a separator.
108       Returns the pointer to the beginning of the word. LENGTH hold the
109       length of the word.  */
110    
111    static char *
112    get_next_word (char *buffer, unsigned int *length)
113    {
114      char *p = buffer, *beg;
115      char c;
116    
117      /* Skip any leading whitespace.  */
118      while (isblank ((unsigned char)*p))
119        ++p;
120    
121      beg = p;
122      c = *(p++);
123    
124      if (c == '\0')
125        return 0;
126    
127    
128      /* We already found the first value of "c", above.  */
129      while (1)
130        {
131          char closeparen;
132          int count;
133    
134          switch (c)
135            {
136            case '\0':
137            case ' ':
138            case '\t':
139              goto done_word;
140    
141            case '$':
142              c = *(p++);
143              if (c == '$')
144                break;
145    
146              /* This is a variable reference, so read it to the matching
147                 close paren.  */
148    
149              if (c == '(')
150                closeparen = ')';
151              else if (c == '{')
152                closeparen = '}';
153              else
154                /* This is a single-letter variable reference.  */
155                break;
156    
157              for (count = 0; *p != '\0'; ++p)
158                {
159                  if (*p == c)
160                    ++count;
161                  else if (*p == closeparen && --count < 0)
162                    {
163                      ++p;
164                      break;
165                    }
166                }
167              break;
168    
169            case '|':
170              goto done;
171    
172            default:
173              break;
174            }
175    
176          c = *(p++);
177        }
178     done_word:
179      --p;
180    
181     done:
182      if (length)
183        *length = p - beg;
184    
185      return beg;
186    }
187    
188  /* Search the pattern rules for a rule with an existing dependency to make  /* Search the pattern rules for a rule with an existing dependency to make
189     FILE.  If a rule is found, the appropriate commands and deps are put in FILE     FILE.  If a rule is found, the appropriate commands and deps are put in FILE
190     and 1 is returned.  If not, 0 is returned.     and 1 is returned.  If not, 0 is returned.
# Line 93  pattern_search (struct file *file, int a Line 217  pattern_search (struct file *file, int a
217       except during a recursive call.  */       except during a recursive call.  */
218    struct file *intermediate_file = 0;    struct file *intermediate_file = 0;
219    
220    /* List of dependencies found recursively.  */    /* This linked list records all the prerequisites actually
221    struct file **intermediate_files       found for a rule along with some other useful information
222      = (struct file **) xmalloc (max_pattern_deps * sizeof (struct file *));       (see struct idep for details). */
223      struct idep* deps = 0;
224    /* List of the patterns used to find intermediate files.  */  
225    char **intermediate_patterns    /* 1 if we need to remove explicit prerequisites, 0 otherwise. */
226      = (char **) alloca (max_pattern_deps * sizeof (char *));    unsigned int remove_explicit_deps = 0;
   
   /* This buffer records all the dependencies actually found for a rule.  */  
   char **found_files = (char **) alloca (max_pattern_deps * sizeof (char *));  
   /* Remember whether the associated dep has an "ignore_mtime" flag set.  */  
   unsigned char *found_files_im = (unsigned char *) alloca (max_pattern_deps * sizeof (unsigned char));  
   /* Number of dep names now in FOUND_FILES.  */  
   unsigned int deps_found = 0;  
227    
228    /* Names of possible dependencies are constructed in this buffer.  */    /* Names of possible dependencies are constructed in this buffer.  */
229    register char *depname = (char *) alloca (namelen + max_pattern_dep_length);    register char *depname = (char *) alloca (namelen + max_pattern_dep_length);
# Line 146  pattern_search (struct file *file, int a Line 263  pattern_search (struct file *file, int a
263    
264    register unsigned int i = 0;  /* uninit checks OK */    register unsigned int i = 0;  /* uninit checks OK */
265    register struct rule *rule;    register struct rule *rule;
266    register struct dep *dep;    register struct dep *dep, *expl_d;
267    
268      char *p, *vname;
269    
270    char *p, *vp;    struct idep *d;
271      struct idep **id_ptr;
272      struct dep **d_ptr;
273    
274  #ifndef NO_ARCHIVES  #ifndef NO_ARCHIVES
275    if (archive || ar_name (filename))    if (archive || ar_name (filename))
# Line 295  pattern_search (struct file *file, int a Line 416  pattern_search (struct file *file, int a
416              tryrules[i] = 0;              tryrules[i] = 0;
417          }          }
418    
419      /* We are going to do second expansion so initialize file variables
420         for the rule. */
421      initialize_file_variables (file, 0);
422    
423    /* Try each rule once without intermediate files, then once with them.  */    /* Try each rule once without intermediate files, then once with them.  */
424    for (intermed_ok = 0; intermed_ok == !!intermed_ok; ++intermed_ok)    for (intermed_ok = 0; intermed_ok == !!intermed_ok; ++intermed_ok)
425      {      {
426        /* Try each pattern rule till we find one that applies.        /* Try each pattern rule till we find one that applies.
427           If it does, copy the names of its dependencies (as substituted)           If it does, expand its dependencies (as substituted)
428           and store them in FOUND_FILES.  DEPS_FOUND is the number of them.  */           and chain them in DEPS.  */
429    
430        for (i = 0; i < nrules; i++)        for (i = 0; i < nrules; i++)
431          {          {
432              struct file *f;
433              unsigned int failed = 0;
434            int check_lastslash;            int check_lastslash;
435    
436            rule = tryrules[i];            rule = tryrules[i];
437    
438              remove_explicit_deps = 0;
439    
440            /* RULE is nil when we discover that a rule,            /* RULE is nil when we discover that a rule,
441               already placed in TRYRULES, should not be applied.  */               already placed in TRYRULES, should not be applied.  */
442            if (rule == 0)            if (rule == 0)
# Line 337  pattern_search (struct file *file, int a Line 466  pattern_search (struct file *file, int a
466            DBS (DB_IMPLICIT, (_("Trying pattern rule with stem `%.*s'.\n"),            DBS (DB_IMPLICIT, (_("Trying pattern rule with stem `%.*s'.\n"),
467                               (int) stemlen, stem));                               (int) stemlen, stem));
468    
469              /* Temporary assign STEM to file->stem and set file variables. */
470              file->stem = stem;
471              set_file_variables (file);
472    
473            /* Try each dependency; see if it "exists".  */            /* Try each dependency; see if it "exists".  */
474    
475            deps_found = 0;            /* @@ There is always only one dep line for any given implicit
476                    rule. So the loop is not necessary. Can rule->deps be 0?
477    
478                    Watch out for conversion of suffix rules to implicit rules.
479              */
480    
481            for (dep = rule->deps; dep != 0; dep = dep->next)            for (dep = rule->deps; dep != 0; dep = dep->next)
482              {              {
483                struct file *f;                unsigned int len;
484                  char *p2;
485                  unsigned int order_only = 0; /* Set if '|' was seen. */
486    
487                  /* In an ideal world we would take the dependency line,
488                     substitute the stem, re-expand the whole line and
489                     chop it into individual prerequisites. Unfortunately
490                     this won't work because of the "check_lastslash" twist.
491                     Instead, we will have to go word by word, taking $()'s
492                     into account, for each word we will substitute the stem,
493                     re-expand, chop it up, and, if check_lastslash != 0,
494                     add the directory part to each resulting prerequisite.  */
495    
496                  p = get_next_word (dep->name, &len);
497    
498                  while (1)
499                    {
500                      int add_dir = 0;
501                      int had_stem = 0;
502    
503                      if (p == 0)
504                        break; /* No more words */
505    
506                      /* If the dependency name has %, substitute the stem.  */
507    
508                      for (p2 = p; p2 < p + len && *p2 != '%'; ++p2);
509    
510                      if (p2 < p + len)
511                        {
512                          register unsigned int i = p2 - p;
513                          bcopy (p, depname, i);
514                          bcopy (stem, depname + i, stemlen);
515                          bcopy (p2 + 1, depname + i + stemlen, len - i - 1);
516                          depname[len + stemlen - 1] = '\0';
517    
518                          if (check_lastslash)
519                            add_dir = 1;
520    
521                          had_stem = 1;
522                        }
523                      else
524                        {
525                          bcopy (p, depname, len);
526                          depname[len] = '\0';
527                        }
528    
529                      p2 = variable_expand_for_file (depname, file);
530    
531                      /* Parse the dependencies. */
532    
533                      while (1)
534                        {
535                          id_ptr = &deps;
536    
537                          for (; *id_ptr; id_ptr = &(*id_ptr)->next)
538                            ;
539    
540                          *id_ptr = (struct idep *)
541                            multi_glob (
542                              parse_file_seq (&p2,
543                                              order_only ? '\0' : '|',
544                                              sizeof (struct idep),
545                                              1), sizeof (struct idep));
546    
547                          /* @@ It would be nice to teach parse_file_seq or
548                             multi_glob to add prefix. This would save us
549                             some reallocations. */
550    
551                          if (order_only || add_dir || had_stem)
552                            {
553                              unsigned long l = lastslash - filename + 1;
554    
555                              for (d = *id_ptr; d != 0; d = d->next)
556                                {
557                                  if (order_only)
558                                    d->ignore_mtime = 1;
559    
560                                  if (add_dir)
561                                    {
562                                      char *p = d->name;
563    
564                                      d->name = xmalloc (strlen (p) + l + 1);
565    
566                                      bcopy (filename, d->name, l);
567                                      bcopy (p, d->name + l, strlen (p) + 1);
568    
569                                      free (p);
570                                    }
571    
572                                  if (had_stem)
573                                    d->had_stem = 1;
574                                }
575                            }
576    
577                          if (!order_only && *p2)
578                          {
579                            ++p2;
580                            order_only = 1;
581                            continue;
582                          }
583    
584                          break;
585                        }
586    
587                      p += len;
588                      p = get_next_word (p, &len);
589                    }
590                }
591    
592              /* Reset the stem in FILE. */
593    
594                /* If the dependency name has a %, substitute the stem.  */            file->stem = 0;
595                p = strchr (dep_name (dep), '%');  
596                if (p != 0)            /* @@ This loop can be combined with the previous one. I do
597                  {               it separately for now for transparency.*/
598                    register unsigned int i;  
599                    if (check_lastslash)            for (d = deps; d != 0; d = d->next)
600                      {              {
601                        /* Copy directory name from the original FILENAME.  */                char *name = d->name;
602                        i = lastslash - filename + 1;  
603                        bcopy (filename, depname, i);                if (file_impossible_p (name))
604                      }                  {
605                    else                    /* If this dependency has already been ruled
606                      i = 0;                       "impossible", then the rule fails and don't
607                    bcopy (dep_name (dep), depname + i, p - dep_name (dep));                       bother trying it on the second pass either
608                    i += p - dep_name (dep);                       since we know that will fail too.  */
609                    bcopy (stem, depname + i, stemlen);                    DBS (DB_IMPLICIT,
610                    i += stemlen;                         (d->had_stem
                   strcpy (depname + i, p + 1);  
                   p = depname;  
                 }  
               else  
                 p = dep_name (dep);  
   
               /* P is now the actual dependency name as substituted.  */  
   
               if (file_impossible_p (p))  
                 {  
                   /* If this dependency has already been ruled  
                      "impossible", then the rule fails and don't  
                      bother trying it on the second pass either  
                      since we know that will fail too.  */  
                   DBS (DB_IMPLICIT,  
                        (p == depname  
611                          ? _("Rejecting impossible implicit prerequisite `%s'.\n")                          ? _("Rejecting impossible implicit prerequisite `%s'.\n")
612                          : _("Rejecting impossible rule prerequisite `%s'.\n"),                          : _("Rejecting impossible rule prerequisite `%s'.\n"),
613                          p));                          name));
614                    tryrules[i] = 0;                    tryrules[i] = 0;
                   break;  
                 }  
615    
616                intermediate_files[deps_found] = 0;                    failed = 1;
617                      break;
618                    }
619    
620                DBS (DB_IMPLICIT,                DBS (DB_IMPLICIT,
621                     (p == depname                     (d->had_stem
622                      ? _("Trying implicit prerequisite `%s'.\n")                      ? _("Trying implicit prerequisite `%s'.\n")
623                      : _("Trying rule prerequisite `%s'.\n"), p));                      : _("Trying rule prerequisite `%s'.\n"), name));
624    
625                /* The DEP->changed flag says that this dependency resides in a                /* If this prerequisite also happened to be explicitly
626                   nonexistent directory.  So we normally can skip looking for                   mentioned for FILE skip all the test below since it
627                   the file.  However, if CHECK_LASTSLASH is set, then the                   it has to be built anyway, no matter which implicit
628                   dependency file we are actually looking for is in a different                   rule we choose. */
629                   directory (the one gotten by prepending FILENAME's directory),  
630                   so it might actually exist.  */                for (expl_d = file->deps; expl_d != 0; expl_d = expl_d->next)
631                    if (strcmp (dep_name (expl_d), name) == 0) break;
632                if (((f = lookup_file (p)) != 0 && f->is_target)  
633                    || ((!dep->changed || check_lastslash) && file_exists_p (p)))                if (expl_d != 0)
634                  {                  continue;
                   found_files_im[deps_found] = dep->ignore_mtime;  
                   found_files[deps_found++] = xstrdup (p);  
                   continue;  
                 }  
               /* This code, given FILENAME = "lib/foo.o", dependency name  
                  "lib/foo.c", and VPATH=src, searches for "src/lib/foo.c".  */  
               vp = p;  
               if (vpath_search (&vp, (FILE_TIMESTAMP *) 0))  
                 {  
                   DBS (DB_IMPLICIT,  
                        (_("Found prerequisite `%s' as VPATH `%s'\n"), p, vp));  
                   strcpy (vp, p);  
                   found_files_im[deps_found] = dep->ignore_mtime;  
                   found_files[deps_found++] = vp;  
                   continue;  
                 }  
   
               /* We could not find the file in any place we should look.  
                  Try to make this dependency as an intermediate file,  
                  but only on the second pass.  */  
   
               if (intermed_ok)  
                 {  
                   if (intermediate_file == 0)  
                     intermediate_file  
                       = (struct file *) alloca (sizeof (struct file));  
635    
                   DBS (DB_IMPLICIT,  
                        (_("Looking for a rule with intermediate file `%s'.\n"),  
                         p));  
636    
                   bzero ((char *) intermediate_file, sizeof (struct file));  
                   intermediate_file->name = p;  
                   if (pattern_search (intermediate_file, 0, depth + 1,  
                                       recursions + 1))  
                     {  
                       p = xstrdup (p);  
                       intermediate_patterns[deps_found]  
                         = intermediate_file->name;  
                       intermediate_file->name = p;  
                       intermediate_files[deps_found] = intermediate_file;  
                       intermediate_file = 0;  
                       found_files_im[deps_found] = dep->ignore_mtime;  
                       /* Allocate an extra copy to go in FOUND_FILES,  
                          because every elt of FOUND_FILES is consumed  
                          or freed later.  */  
                       found_files[deps_found++] = xstrdup (p);  
                       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.  */  
                   file_impossible (p);  
                 }  
637    
638                /* A dependency of this rule does not exist.                /* The DEP->changed flag says that this dependency resides in a
639                   Therefore, this rule fails.  */                   nonexistent directory.  So we normally can skip looking for
640                break;                   the file.  However, if CHECK_LASTSLASH is set, then the
641              }                   dependency file we are actually looking for is in a different
642                     directory (the one gotten by prepending FILENAME's directory),
643                     so it might actually exist.  */
644    
645                  /* @@ dep->changed check is disabled. */
646                  if (((f = lookup_file (name)) != 0 && f->is_target)
647                      /*|| ((!dep->changed || check_lastslash) && */
648                      || file_exists_p (name))
649                    {
650                      continue;
651                    }
652    
653                  /* This code, given FILENAME = "lib/foo.o", dependency name
654                     "lib/foo.c", and VPATH=src, searches for "src/lib/foo.c".  */
655                  vname = name;
656                  if (vpath_search (&vname, (FILE_TIMESTAMP *) 0))
657                    {
658                      DBS (DB_IMPLICIT,
659                           (_("Found prerequisite `%s' as VPATH `%s'\n"),
660                            name,
661                            vname));
662    
663                      free (vname);
664                      continue;
665                    }
666    
667    
668                  /* We could not find the file in any place we should look.
669                     Try to make this dependency as an intermediate file,
670                     but only on the second pass.  */
671    
672                  if (intermed_ok)
673                    {
674                      if (intermediate_file == 0)
675                        intermediate_file
676                          = (struct file *) alloca (sizeof (struct file));
677    
678                      DBS (DB_IMPLICIT,
679                           (_("Looking for a rule with intermediate file `%s'.\n"),
680                            name));
681    
682            /* This rule is no longer `in use' for recursive searches.  */                    bzero ((char *) intermediate_file, sizeof (struct file));
683                      intermediate_file->name = name;
684                      if (pattern_search (intermediate_file,
685                                          0,
686                                          depth + 1,
687                                          recursions + 1))
688                        {
689                          d->intermediate_file = intermediate_file;
690                          d->intermediate_pattern = intermediate_file->name;
691    
692                          intermediate_file->name = xstrdup (name);
693                          intermediate_file = 0;
694    
695                          continue;
696                        }
697    
698                      /* If we have tried to find P as an intermediate
699                         file and failed, mark that name as impossible
700                         so we won't go through the search again later.  */
701                      file_impossible (name);
702                    }
703    
704                  /* A dependency of this rule does not exist. Therefore,
705                     this rule fails.  */
706                  failed = 1;
707                  break;
708                }
709    
710              /* This rule is no longer `in use' for recursive searches.  */
711            rule->in_use = 0;            rule->in_use = 0;
712    
713            if (dep != 0)            if (failed)
714              {              {
715                /* This pattern rule does not apply.                /* This pattern rule does not apply. If some of its
716                   If some of its dependencies succeeded,                   dependencies succeeded, free the data structure
717                   free the data structure describing them.  */                   describing them.  */
718                while (deps_found-- > 0)                free_idep_chain (deps);
719                  {                deps = 0;
720                    register struct file *f = intermediate_files[deps_found];              }
                   free (found_files[deps_found]);  
                   if (f != 0  
                       && (f->stem < f->name  
                           || f->stem > f->name + strlen (f->name)))  
                     free (f->stem);  
                 }  
             }  
721            else            else
722              /* This pattern rule does apply.  Stop looking for one.  */              /* This pattern rule does apply.  Stop looking for one.  */
723              break;              break;
# Line 511  pattern_search (struct file *file, int a Line 749  pattern_search (struct file *file, int a
749       This includes the intermediate files, if any.       This includes the intermediate files, if any.
750       Convert them into entries on the deps-chain of FILE.  */       Convert them into entries on the deps-chain of FILE.  */
751    
752    while (deps_found-- > 0)    if (remove_explicit_deps)
753        {
754          /* Remove all the dependencies that didn't come from
755             this implicit rule. */
756    
757          dep = file->deps;
758          while (dep != 0)
759            {
760              struct dep *next = dep->next;
761              free (dep->name);
762              free ((char *)dep);
763              dep = next;
764            }
765          file->deps = 0;
766      }
767    
768      expl_d = file->deps; /* We will add them at the end. */
769      d_ptr = &file->deps;
770    
771      for (d = deps; d != 0; d = d->next)
772      {      {
773        register char *s;        register char *s;
774    
775        if (intermediate_files[deps_found] != 0)        if (d->intermediate_file != 0)
776          {          {
777            /* If we need to use an intermediate file,            /* If we need to use an intermediate file,
778               make sure it is entered as a target, with the info that was               make sure it is entered as a target, with the info that was
# Line 524  pattern_search (struct file *file, int a Line 781  pattern_search (struct file *file, int a
781               a target; therefore we can assume that the deps and cmds               a target; therefore we can assume that the deps and cmds
782               of F below are null before we change them.  */               of F below are null before we change them.  */
783    
784            struct file *imf = intermediate_files[deps_found];            struct file *imf = d->intermediate_file;
785            register struct file *f = enter_file (imf->name);            register struct file *f = enter_file (imf->name);
786            f->deps = imf->deps;            f->deps = imf->deps;
787            f->cmds = imf->cmds;            f->cmds = imf->cmds;
788            f->stem = imf->stem;            f->stem = imf->stem;
789            f->also_make = imf->also_make;            f->also_make = imf->also_make;
790            imf = lookup_file (intermediate_patterns[deps_found]);            imf = lookup_file (d->intermediate_pattern);
791            if (imf != 0 && imf->precious)            if (imf != 0 && imf->precious)
792              f->precious = 1;              f->precious = 1;
793            f->intermediate = 1;            f->intermediate = 1;
# Line 547  pattern_search (struct file *file, int a Line 804  pattern_search (struct file *file, int a
804          }          }
805    
806        dep = (struct dep *) xmalloc (sizeof (struct dep));        dep = (struct dep *) xmalloc (sizeof (struct dep));
807        dep->ignore_mtime = found_files_im[deps_found];        dep->ignore_mtime = d->ignore_mtime;
808        s = found_files[deps_found];        s = d->name; /* Hijacking the name. */
809          d->name = 0;
810        if (recursions == 0)        if (recursions == 0)
811          {          {
812            dep->name = 0;            dep->name = 0;
# Line 567  pattern_search (struct file *file, int a Line 825  pattern_search (struct file *file, int a
825            dep->file = 0;            dep->file = 0;
826            dep->changed = 0;            dep->changed = 0;
827          }          }
828        if (intermediate_files[deps_found] == 0 && tryrules[foundrule]->terminal)        if (d->intermediate_file == 0 && tryrules[foundrule]->terminal)
829          {          {
830            /* If the file actually existed (was not an intermediate file),            /* If the file actually existed (was not an intermediate file),
831               and the rule that found it was a terminal one, then we want               and the rule that found it was a terminal one, then we want
# Line 579  pattern_search (struct file *file, int a Line 837  pattern_search (struct file *file, int a
837            else            else
838              dep->file->tried_implicit = 1;              dep->file->tried_implicit = 1;
839          }          }
840        dep->next = file->deps;  
841        file->deps = dep;        *d_ptr = dep;
842          d_ptr = &dep->next;
843      }      }
844    
845      *d_ptr = expl_d;
846    
847    if (!checked_lastslash[foundrule])    if (!checked_lastslash[foundrule])
848      {      {
849        /* Always allocate new storage, since STEM might be        /* Always allocate new storage, since STEM might be
# Line 629  pattern_search (struct file *file, int a Line 890  pattern_search (struct file *file, int a
890          }          }
891    
892   done:   done:
893    free (intermediate_files);    free_idep_chain (deps);
894    free (tryrules);    free (tryrules);
895    
896    return rule != 0;    return rule != 0;

Legend:
Removed from v.1.41  
changed lines
  Added in v.1.42

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26