134 |
static void record_files PARAMS ((struct nameseq *filenames, char *pattern, char *pattern_percent, |
static void record_files PARAMS ((struct nameseq *filenames, char *pattern, char *pattern_percent, |
135 |
struct dep *deps, unsigned int cmds_started, char *commands, |
struct dep *deps, unsigned int cmds_started, char *commands, |
136 |
unsigned int commands_idx, int two_colon, |
unsigned int commands_idx, int two_colon, |
|
int have_sysv_atvar, |
|
137 |
const struct floc *flocp, int set_default)); |
const struct floc *flocp, int set_default)); |
138 |
static void record_target_var PARAMS ((struct nameseq *filenames, char *defn, |
static void record_target_var PARAMS ((struct nameseq *filenames, char *defn, |
139 |
enum variable_origin origin, |
enum variable_origin origin, |
456 |
unsigned int cmds_started, tgts_started; |
unsigned int cmds_started, tgts_started; |
457 |
int ignoring = 0, in_ignored_define = 0; |
int ignoring = 0, in_ignored_define = 0; |
458 |
int no_targets = 0; /* Set when reading a rule without targets. */ |
int no_targets = 0; /* Set when reading a rule without targets. */ |
|
int have_sysv_atvar = 0; |
|
459 |
struct nameseq *filenames = 0; |
struct nameseq *filenames = 0; |
460 |
struct dep *deps = 0; |
struct dep *deps = 0; |
461 |
long nlines = 0; |
long nlines = 0; |
472 |
fi.lineno = tgts_started; \ |
fi.lineno = tgts_started; \ |
473 |
record_files (filenames, pattern, pattern_percent, deps, \ |
record_files (filenames, pattern, pattern_percent, deps, \ |
474 |
cmds_started, commands, commands_idx, two_colon, \ |
cmds_started, commands, commands_idx, two_colon, \ |
475 |
have_sysv_atvar, &fi, set_default); \ |
&fi, set_default); \ |
476 |
} \ |
} \ |
477 |
filenames = 0; \ |
filenames = 0; \ |
478 |
commands_idx = 0; \ |
commands_idx = 0; \ |
867 |
char *cmdleft, *semip, *lb_next; |
char *cmdleft, *semip, *lb_next; |
868 |
unsigned int len, plen = 0; |
unsigned int len, plen = 0; |
869 |
char *colonp; |
char *colonp; |
870 |
|
const char *end, *beg; /* Helpers for whitespace stripping. */ |
871 |
|
|
872 |
/* Record the previous rule. */ |
/* Record the previous rule. */ |
873 |
|
|
916 |
} |
} |
917 |
|
|
918 |
p2 = variable_expand_string(NULL, lb_next, len); |
p2 = variable_expand_string(NULL, lb_next, len); |
919 |
|
|
920 |
while (1) |
while (1) |
921 |
{ |
{ |
922 |
lb_next += len; |
lb_next += len; |
1094 |
} |
} |
1095 |
} |
} |
1096 |
|
|
|
/* Do any of the prerequisites appear to have $@ etc.? */ |
|
|
have_sysv_atvar = 0; |
|
|
if (!posix_pedantic) |
|
|
for (p = strchr (p2, '$'); p != 0; p = strchr (p+1, '$')) |
|
|
if (p[1] == '@' || ((p[1] == '(' || p[1] == '{') && p[2] == '@')) |
|
|
{ |
|
|
have_sysv_atvar = 1; |
|
|
break; |
|
|
} |
|
|
|
|
1097 |
/* Is this a static pattern rule: `target: %targ: %dep; ...'? */ |
/* Is this a static pattern rule: `target: %targ: %dep; ...'? */ |
1098 |
p = strchr (p2, ':'); |
p = strchr (p2, ':'); |
1099 |
while (p != 0 && p[-1] == '\\') |
while (p != 0 && p[-1] == '\\') |
1158 |
else |
else |
1159 |
pattern = 0; |
pattern = 0; |
1160 |
|
|
1161 |
/* Parse the dependencies. */ |
/* Strip leading and trailing whitespaces. */ |
1162 |
deps = (struct dep *) |
beg = p2; |
1163 |
multi_glob (parse_file_seq (&p2, '|', sizeof (struct dep), 1), |
end = beg + strlen (beg) - 1; |
1164 |
sizeof (struct dep)); |
strip_whitespace (&beg, &end); |
1165 |
if (*p2) |
|
1166 |
|
if (beg <= end && *beg != '\0') |
1167 |
{ |
{ |
1168 |
/* Files that follow '|' are special prerequisites that |
deps = (struct dep*) xmalloc (sizeof (struct dep)); |
1169 |
need only exist in order to satisfy the dependency. |
deps->next = 0; |
1170 |
Their modification times are irrelevant. */ |
deps->name = savestring (beg, end - beg + 1); |
1171 |
struct dep **deps_ptr = &deps; |
deps->file = 0; |
|
struct dep *d; |
|
|
for (deps_ptr = &deps; *deps_ptr; deps_ptr = &(*deps_ptr)->next) |
|
|
; |
|
|
++p2; |
|
|
*deps_ptr = (struct dep *) |
|
|
multi_glob (parse_file_seq (&p2, '\0', sizeof (struct dep), 1), |
|
|
sizeof (struct dep)); |
|
|
for (d = *deps_ptr; d != 0; d = d->next) |
|
|
d->ignore_mtime = 1; |
|
1172 |
} |
} |
1173 |
|
else |
1174 |
|
deps = 0; |
1175 |
|
|
1176 |
commands_idx = 0; |
commands_idx = 0; |
1177 |
if (cmdleft != 0) |
if (cmdleft != 0) |
1737 |
record_files (struct nameseq *filenames, char *pattern, char *pattern_percent, |
record_files (struct nameseq *filenames, char *pattern, char *pattern_percent, |
1738 |
struct dep *deps, unsigned int cmds_started, char *commands, |
struct dep *deps, unsigned int cmds_started, char *commands, |
1739 |
unsigned int commands_idx, int two_colon, |
unsigned int commands_idx, int two_colon, |
1740 |
int have_sysv_atvar, const struct floc *flocp, int set_default) |
const struct floc *flocp, int set_default) |
1741 |
{ |
{ |
1742 |
struct nameseq *nextf; |
struct nameseq *nextf; |
1743 |
int implicit = 0; |
int implicit = 0; |
1830 |
/* We use patsubst_expand to do the work of translating |
/* We use patsubst_expand to do the work of translating |
1831 |
the target pattern, the target's name and the dependencies' |
the target pattern, the target's name and the dependencies' |
1832 |
patterns into plain dependency names. */ |
patterns into plain dependency names. */ |
|
char *buffer = variable_expand (""); |
|
1833 |
|
|
1834 |
for (d = this; d != 0; d = d->next) |
if (find_percent (this->name) != 0) |
1835 |
{ |
{ |
1836 |
char *o; |
char stem[PATH_MAX]; |
1837 |
char *percent = find_percent (d->name); |
char *o; |
1838 |
if (percent == 0) |
char *buffer = variable_expand (""); |
1839 |
continue; |
|
1840 |
o = patsubst_expand (buffer, name, pattern, d->name, |
o = patsubst_expand (buffer, name, pattern, "%", |
1841 |
pattern_percent+1, percent+1); |
pattern_percent + 1, 0); |
1842 |
|
|
1843 |
|
|
1844 |
|
strncpy (stem, buffer, o - buffer); |
1845 |
|
stem[o - buffer] = '\0'; |
1846 |
|
|
1847 |
|
o = subst_expand (buffer, this->name, "%", stem, |
1848 |
|
1, strlen (stem), 0); |
1849 |
|
|
1850 |
/* If the name expanded to the empty string, that's |
/* If the name expanded to the empty string, that's |
1851 |
illegal. */ |
illegal. */ |
1852 |
if (o == buffer) |
if (o == buffer) |
1853 |
fatal (flocp, |
fatal (flocp, |
1854 |
_("target `%s' leaves prerequisite pattern empty"), |
_("target `%s' leaves prerequisite pattern empty"), |
1855 |
name); |
name); |
1856 |
free (d->name); |
free (this->name); |
1857 |
d->name = savestring (buffer, o - buffer); |
this->name = savestring (buffer, o - buffer); |
1858 |
} |
} |
1859 |
} |
} |
1860 |
} |
} |
1861 |
|
|
|
/* If at least one of the dependencies uses $$@ etc. deal with that. |
|
|
It would be very nice and very simple to just expand everything, but |
|
|
it would break a lot of backward compatibility. Maybe that's OK |
|
|
since we're just emulating a SysV function, and if we do that then |
|
|
why not emulate it completely (that's what SysV make does: it |
|
|
re-expands the entire prerequisite list, all the time, with $@ |
|
|
etc. in scope). But, it would be a pain indeed to document this |
|
|
("iff you use $$@, your prerequisite lists is expanded twice...") |
|
|
Ouch. Maybe better to make the code more complex. */ |
|
|
|
|
|
if (have_sysv_atvar) |
|
|
{ |
|
|
char *p; |
|
|
int tlen = strlen (name); |
|
|
char *fnp = strrchr (name, '/'); |
|
|
int dlen; |
|
|
int flen; |
|
|
|
|
|
if (fnp) |
|
|
{ |
|
|
dlen = fnp - name; |
|
|
++fnp; |
|
|
flen = strlen (fnp); |
|
|
} |
|
|
else |
|
|
{ |
|
|
dlen = 0; |
|
|
fnp = name; |
|
|
flen = tlen; |
|
|
} |
|
|
|
|
|
|
|
|
for (d = this; d != 0; d = d->next) |
|
|
for (p = strchr (d->name, '$'); p != 0; p = strchr (p+1, '$')) |
|
|
{ |
|
|
char *s = p; |
|
|
char *at; |
|
|
int atlen; |
|
|
|
|
|
/* If it's '$@', '$(@', or '${@', it's escaped */ |
|
|
if ((++p)[0] == '$' |
|
|
&& (p[1] == '@' |
|
|
|| ((p[1] == '(' || p[1] == '{') && p[2] == '@'))) |
|
|
{ |
|
|
bcopy (p, s, strlen (p)+1); |
|
|
continue; |
|
|
} |
|
|
|
|
|
/* Maybe found one. We like anything of any form matching @, |
|
|
[({]@[}):], or [({]@[DF][}):]. */ |
|
|
|
|
|
if (! (p[0] == '@' |
|
|
|| ((p[0] == '(' || p[0] == '{') && (++p)[0] == '@' |
|
|
&& (((++p)[0] == ')' || p[0] == '}' || p[0] == ':') |
|
|
|| ((p[1] == ')' || p[1] == '}' || p[1] == ':') |
|
|
&& (p[0] == 'D' || p[0] == 'F')))))) |
|
|
continue; |
|
|
|
|
|
/* Found one. Compute the length and string ptr. Move p |
|
|
past the variable reference. */ |
|
|
switch (p[0]) |
|
|
{ |
|
|
case 'D': |
|
|
atlen = dlen; |
|
|
at = name; |
|
|
p += 2; |
|
|
break; |
|
|
|
|
|
case 'F': |
|
|
atlen = flen; |
|
|
at = fnp; |
|
|
p += 2; |
|
|
break; |
|
|
|
|
|
default: |
|
|
atlen = tlen; |
|
|
at = name; |
|
|
++p; |
|
|
break; |
|
|
} |
|
|
|
|
|
/* Get more space. */ |
|
|
{ |
|
|
int soff = s - d->name; |
|
|
int poff = p - d->name; |
|
|
d->name = (char *) xrealloc (d->name, |
|
|
strlen (d->name) + atlen + 1); |
|
|
s = d->name + soff; |
|
|
p = d->name + poff; |
|
|
} |
|
|
|
|
|
/* Copy the string over. */ |
|
|
bcopy(p, s+atlen, strlen (p)+1); |
|
|
bcopy(at, s, atlen); |
|
|
p = s + atlen - 1; |
|
|
} |
|
|
} |
|
|
|
|
1862 |
if (!two_colon) |
if (!two_colon) |
1863 |
{ |
{ |
1864 |
/* Single-colon. Combine these dependencies |
/* Single-colon. Combine these dependencies |
1896 |
f->cmds = 0; |
f->cmds = 0; |
1897 |
if (cmds != 0) |
if (cmds != 0) |
1898 |
f->cmds = cmds; |
f->cmds = cmds; |
1899 |
|
|
1900 |
/* Defining .SUFFIXES with no dependencies |
/* Defining .SUFFIXES with no dependencies |
1901 |
clears out the list of suffixes. */ |
clears out the list of suffixes. */ |
1902 |
if (f == suffix_file && this == 0) |
if (f == suffix_file && this == 0) |
1911 |
} |
} |
1912 |
f->deps = 0; |
f->deps = 0; |
1913 |
} |
} |
1914 |
else if (f->deps != 0) |
else if (this != 0) |
1915 |
{ |
{ |
1916 |
/* Add the file's old deps and the new ones in THIS together. */ |
/* Add the file's old deps and the new ones in THIS together. */ |
1917 |
|
|
1918 |
struct dep *firstdeps, *moredeps; |
if (f->deps != 0) |
1919 |
if (cmds != 0) |
{ |
1920 |
{ |
struct dep **d_ptr = &f->deps; |
|
/* This is the rule with commands, so put its deps first. |
|
|
The rationale behind this is that $< expands to the |
|
|
first dep in the chain, and commands use $< expecting |
|
|
to get the dep that rule specifies. */ |
|
|
firstdeps = this; |
|
|
moredeps = f->deps; |
|
|
} |
|
|
else |
|
|
{ |
|
|
/* Append the new deps to the old ones. */ |
|
|
firstdeps = f->deps; |
|
|
moredeps = this; |
|
|
} |
|
1921 |
|
|
1922 |
if (firstdeps == 0) |
while ((*d_ptr)->next != 0) |
1923 |
firstdeps = moredeps; |
d_ptr = &(*d_ptr)->next; |
1924 |
else |
|
1925 |
{ |
if (cmds != 0) |
1926 |
d = firstdeps; |
{ |
1927 |
while (d->next != 0) |
/* This is the rule with commands, so put its deps |
1928 |
d = d->next; |
last. The rationale behind this is that $< expands |
1929 |
d->next = moredeps; |
to the first dep in the chain, and commands use $< |
1930 |
} |
expecting to get the dep that rule specifies. |
1931 |
|
However the second expansion algorithm reverses |
1932 |
|
the order thus we need to make it last here. */ |
1933 |
|
|
1934 |
f->deps = firstdeps; |
(*d_ptr)->next = this; |
1935 |
|
} |
1936 |
|
else |
1937 |
|
{ |
1938 |
|
/* This is the rule without commands. Put its |
1939 |
|
dependencies at the end but before dependencies |
1940 |
|
from the rule with commands (if any). This way |
1941 |
|
everyhting appears in makefile order. */ |
1942 |
|
|
1943 |
|
if (f->cmds != 0) |
1944 |
|
{ |
1945 |
|
this->next = *d_ptr; |
1946 |
|
*d_ptr = this; |
1947 |
|
} |
1948 |
|
else |
1949 |
|
(*d_ptr)->next = this; |
1950 |
|
} |
1951 |
|
} |
1952 |
|
else |
1953 |
|
f->deps = this; |
1954 |
|
|
1955 |
|
/* This is a hack. I need a way to communicate to snap_deps() |
1956 |
|
that the last dependency line in this file came with commands |
1957 |
|
(so that logic in snap_deps() can put it in front and all |
1958 |
|
this $< -logic works). I cannot's simply rely oon file->cmds |
1959 |
|
being not 0 because of the cases like the following: |
1960 |
|
|
1961 |
|
foo: bar |
1962 |
|
foo: |
1963 |
|
... |
1964 |
|
|
1965 |
|
I am going to temporarily "borrow" UPDATING member in |
1966 |
|
`struct file' for this. */ |
1967 |
|
|
1968 |
|
if (cmds != 0) |
1969 |
|
f->updating = 1; |
1970 |
} |
} |
|
else |
|
|
f->deps = this; |
|
1971 |
|
|
1972 |
/* If this is a static pattern rule, set the file's stem to |
/* If this is a static pattern rule, set the file's stem to |
1973 |
the part of its name that matched the `%' in the pattern, |
the part of its name that matched the `%' in the pattern, |
2051 |
} |
} |
2052 |
|
|
2053 |
if (!reject) |
if (!reject) |
2054 |
default_goal_file = f; |
default_goal_file = f; |
2055 |
} |
} |
2056 |
} |
} |
2057 |
|
|