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. |
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. |
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); |
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)) |
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) |
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; |
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 |
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; |
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; |
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 |
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 |
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; |