mirror of
https://git.savannah.gnu.org/git/make.git
synced 2024-12-27 23:06:53 +00:00
Fix savannah bug 25780. Optimize things a bit.
This commit is contained in:
parent
4254e88cfa
commit
bd2d124f27
7 changed files with 101 additions and 101 deletions
14
ChangeLog
14
ChangeLog
|
@ -1,3 +1,17 @@
|
||||||
|
2009-10-06 Boris Kolpackov <boris@codesynthesis.com>
|
||||||
|
|
||||||
|
* dep.h (uniquize_deps): Remove.
|
||||||
|
|
||||||
|
* read.c (uniquize_deps): Merge into set_file_variables in
|
||||||
|
commands.c.
|
||||||
|
(dep_hash_1, dep_hash_2, dep_hash_cmp): Move to commands.c.
|
||||||
|
|
||||||
|
* commands.c (set_file_variables): Avoid modifying the dep
|
||||||
|
chain to achieve uniqueness. Fixes savannah bug 25780.
|
||||||
|
|
||||||
|
* implicit.c (pattern_search): Instead of re-setting all automatic
|
||||||
|
variables for each rule we try, just update $*.
|
||||||
|
|
||||||
2009-10-06 Boris Kolpackov <boris@codesynthesis.com>
|
2009-10-06 Boris Kolpackov <boris@codesynthesis.com>
|
||||||
|
|
||||||
* variable.h (undefine_variable_in_set): New function declaration.
|
* variable.h (undefine_variable_in_set): New function declaration.
|
||||||
|
|
92
commands.c
92
commands.c
|
@ -39,6 +39,36 @@ int remote_kill (int id, int sig);
|
||||||
int getpid ();
|
int getpid ();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
static unsigned long
|
||||||
|
dep_hash_1 (const void *key)
|
||||||
|
{
|
||||||
|
return_STRING_HASH_1 (dep_name ((struct dep const *) key));
|
||||||
|
}
|
||||||
|
|
||||||
|
static unsigned long
|
||||||
|
dep_hash_2 (const void *key)
|
||||||
|
{
|
||||||
|
return_STRING_HASH_2 (dep_name ((struct dep const *) key));
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
dep_hash_cmp (const void *x, const void *y)
|
||||||
|
{
|
||||||
|
struct dep *dx = (struct dep *) x;
|
||||||
|
struct dep *dy = (struct dep *) y;
|
||||||
|
int cmp = strcmp (dep_name (dx), dep_name (dy));
|
||||||
|
|
||||||
|
/* If the names are the same but ignore_mtimes are not equal, one of these
|
||||||
|
is an order-only prerequisite and one isn't. That means that we should
|
||||||
|
remove the one that isn't and keep the one that is. */
|
||||||
|
|
||||||
|
if (!cmp && dx->ignore_mtime != dy->ignore_mtime)
|
||||||
|
dx->ignore_mtime = dy->ignore_mtime = 0;
|
||||||
|
|
||||||
|
return cmp;
|
||||||
|
}
|
||||||
|
|
||||||
/* Set FILE's automatic variables up. */
|
/* Set FILE's automatic variables up. */
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -149,18 +179,34 @@ set_file_variables (struct file *file)
|
||||||
char *bp;
|
char *bp;
|
||||||
unsigned int len;
|
unsigned int len;
|
||||||
|
|
||||||
|
struct hash_table dep_hash;
|
||||||
|
void **slot;
|
||||||
|
|
||||||
/* Compute first the value for $+, which is supposed to contain
|
/* Compute first the value for $+, which is supposed to contain
|
||||||
duplicate dependencies as they were listed in the makefile. */
|
duplicate dependencies as they were listed in the makefile. */
|
||||||
|
|
||||||
plus_len = 0;
|
plus_len = 0;
|
||||||
|
bar_len = 0;
|
||||||
for (d = file->deps; d != 0; d = d->next)
|
for (d = file->deps; d != 0; d = d->next)
|
||||||
if (! d->ignore_mtime && ! d->need_2nd_expansion)
|
{
|
||||||
plus_len += strlen (dep_name (d)) + 1;
|
if (!d->need_2nd_expansion)
|
||||||
|
{
|
||||||
|
if (d->ignore_mtime)
|
||||||
|
bar_len += strlen (dep_name (d)) + 1;
|
||||||
|
else
|
||||||
|
plus_len += strlen (dep_name (d)) + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bar_len == 0)
|
||||||
|
bar_len++;
|
||||||
|
|
||||||
if (plus_len == 0)
|
if (plus_len == 0)
|
||||||
plus_len++;
|
plus_len++;
|
||||||
|
|
||||||
if (plus_len > plus_max)
|
if (plus_len > plus_max)
|
||||||
plus_value = xrealloc (plus_value, plus_max = plus_len);
|
plus_value = xrealloc (plus_value, plus_max = plus_len);
|
||||||
|
|
||||||
cp = plus_value;
|
cp = plus_value;
|
||||||
|
|
||||||
qmark_len = plus_len + 1; /* Will be this or less. */
|
qmark_len = plus_len + 1; /* Will be this or less. */
|
||||||
|
@ -191,19 +237,6 @@ set_file_variables (struct file *file)
|
||||||
cp[cp > plus_value ? -1 : 0] = '\0';
|
cp[cp > plus_value ? -1 : 0] = '\0';
|
||||||
DEFINE_VARIABLE ("+", 1, plus_value);
|
DEFINE_VARIABLE ("+", 1, plus_value);
|
||||||
|
|
||||||
/* Make sure that no dependencies are repeated. This does not
|
|
||||||
really matter for the purpose of updating targets, but it
|
|
||||||
might make some names be listed twice for $^ and $?. */
|
|
||||||
|
|
||||||
uniquize_deps (file->deps);
|
|
||||||
|
|
||||||
bar_len = 0;
|
|
||||||
for (d = file->deps; d != 0; d = d->next)
|
|
||||||
if (d->ignore_mtime && ! d->need_2nd_expansion)
|
|
||||||
bar_len += strlen (dep_name (d)) + 1;
|
|
||||||
if (bar_len == 0)
|
|
||||||
bar_len++;
|
|
||||||
|
|
||||||
/* Compute the values for $^, $?, and $|. */
|
/* Compute the values for $^, $?, and $|. */
|
||||||
|
|
||||||
cp = caret_value = plus_value; /* Reuse the buffer; it's big enough. */
|
cp = caret_value = plus_value; /* Reuse the buffer; it's big enough. */
|
||||||
|
@ -216,16 +249,33 @@ set_file_variables (struct file *file)
|
||||||
bar_value = xrealloc (bar_value, bar_max = bar_len);
|
bar_value = xrealloc (bar_value, bar_max = bar_len);
|
||||||
bp = bar_value;
|
bp = bar_value;
|
||||||
|
|
||||||
|
/* Make sure that no dependencies are repeated in $^, $?, and $|. It
|
||||||
|
would be natural to combine the next two loops but we can't do it
|
||||||
|
because of a situation where we have two dep entries, the first
|
||||||
|
is order-only and the second is normal (see dep_hash_cmp). */
|
||||||
|
|
||||||
|
hash_init (&dep_hash, 500, dep_hash_1, dep_hash_2, dep_hash_cmp);
|
||||||
|
|
||||||
for (d = file->deps; d != 0; d = d->next)
|
for (d = file->deps; d != 0; d = d->next)
|
||||||
{
|
{
|
||||||
const char *c;
|
|
||||||
|
|
||||||
if (d->need_2nd_expansion)
|
if (d->need_2nd_expansion)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
slot = hash_find_slot (&dep_hash, d);
|
||||||
|
if (HASH_VACANT (*slot))
|
||||||
|
hash_insert_at (&dep_hash, d, slot);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (d = file->deps; d != 0; d = d->next)
|
||||||
|
{
|
||||||
|
const char *c;
|
||||||
|
|
||||||
|
if (d->need_2nd_expansion || hash_find_item (&dep_hash, d) != d)
|
||||||
|
continue;
|
||||||
|
|
||||||
c = dep_name (d);
|
c = dep_name (d);
|
||||||
#ifndef NO_ARCHIVES
|
#ifndef NO_ARCHIVES
|
||||||
if (ar_name (c))
|
if (ar_name (c))
|
||||||
{
|
{
|
||||||
c = strchr (c, '(') + 1;
|
c = strchr (c, '(') + 1;
|
||||||
len = strlen (c) - 1;
|
len = strlen (c) - 1;
|
||||||
|
@ -236,12 +286,12 @@ set_file_variables (struct file *file)
|
||||||
|
|
||||||
if (d->ignore_mtime)
|
if (d->ignore_mtime)
|
||||||
{
|
{
|
||||||
memcpy (bp, c, len);
|
memcpy (bp, c, len);
|
||||||
bp += len;
|
bp += len;
|
||||||
*bp++ = FILE_LIST_SEPARATOR;
|
*bp++ = FILE_LIST_SEPARATOR;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
memcpy (cp, c, len);
|
memcpy (cp, c, len);
|
||||||
cp += len;
|
cp += len;
|
||||||
*cp++ = FILE_LIST_SEPARATOR;
|
*cp++ = FILE_LIST_SEPARATOR;
|
||||||
|
@ -254,6 +304,8 @@ set_file_variables (struct file *file)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hash_free (&dep_hash, 0);
|
||||||
|
|
||||||
/* Kill the last spaces and define the variables. */
|
/* Kill the last spaces and define the variables. */
|
||||||
|
|
||||||
cp[cp > caret_value ? -1 : 0] = '\0';
|
cp[cp > caret_value ? -1 : 0] = '\0';
|
||||||
|
|
1
dep.h
1
dep.h
|
@ -90,4 +90,3 @@ void free_ns_chain (struct nameseq *n);
|
||||||
struct dep *read_all_makefiles (const char **makefiles);
|
struct dep *read_all_makefiles (const char **makefiles);
|
||||||
int eval_buffer (char *buffer);
|
int eval_buffer (char *buffer);
|
||||||
int update_goal_chain (struct dep *goals);
|
int update_goal_chain (struct dep *goals);
|
||||||
void uniquize_deps (struct dep *);
|
|
||||||
|
|
13
implicit.c
13
implicit.c
|
@ -612,20 +612,19 @@ pattern_search (struct file *file, int archive,
|
||||||
add_dir = 1;
|
add_dir = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Initialize file variables if we haven't already
|
/* Initialize and set file variables if we haven't already
|
||||||
done so. */
|
done so. */
|
||||||
if (!file_vars_initialized)
|
if (!file_vars_initialized)
|
||||||
{
|
{
|
||||||
initialize_file_variables (file, 0);
|
initialize_file_variables (file, 0);
|
||||||
|
set_file_variables (file);
|
||||||
file_vars_initialized = 1;
|
file_vars_initialized = 1;
|
||||||
}
|
}
|
||||||
|
/* Update the stem value in $* for this rule. */
|
||||||
/* Set file variables. Note that we cannot do it once at the
|
else if (!file_variables_set)
|
||||||
beginning of the function because the stem value changes
|
|
||||||
for each rule. */
|
|
||||||
if (!file_variables_set)
|
|
||||||
{
|
{
|
||||||
set_file_variables (file);
|
define_variable_for_file (
|
||||||
|
"*", 1, file->stem, o_automatic, 0, file);
|
||||||
file_variables_set = 1;
|
file_variables_set = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
64
read.c
64
read.c
|
@ -1723,71 +1723,7 @@ conditional_line (char *line, int len, const struct floc *flocp)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Remove duplicate dependencies in CHAIN. */
|
|
||||||
|
|
||||||
static unsigned long
|
|
||||||
dep_hash_1 (const void *key)
|
|
||||||
{
|
|
||||||
return_STRING_HASH_1 (dep_name ((struct dep const *) key));
|
|
||||||
}
|
|
||||||
|
|
||||||
static unsigned long
|
|
||||||
dep_hash_2 (const void *key)
|
|
||||||
{
|
|
||||||
return_STRING_HASH_2 (dep_name ((struct dep const *) key));
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
dep_hash_cmp (const void *x, const void *y)
|
|
||||||
{
|
|
||||||
struct dep *dx = (struct dep *) x;
|
|
||||||
struct dep *dy = (struct dep *) y;
|
|
||||||
int cmp = strcmp (dep_name (dx), dep_name (dy));
|
|
||||||
|
|
||||||
/* If the names are the same but ignore_mtimes are not equal, one of these
|
|
||||||
is an order-only prerequisite and one isn't. That means that we should
|
|
||||||
remove the one that isn't and keep the one that is. */
|
|
||||||
|
|
||||||
if (!cmp && dx->ignore_mtime != dy->ignore_mtime)
|
|
||||||
dx->ignore_mtime = dy->ignore_mtime = 0;
|
|
||||||
|
|
||||||
return cmp;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
uniquize_deps (struct dep *chain)
|
|
||||||
{
|
|
||||||
struct hash_table deps;
|
|
||||||
register struct dep **depp;
|
|
||||||
|
|
||||||
hash_init (&deps, 500, dep_hash_1, dep_hash_2, dep_hash_cmp);
|
|
||||||
|
|
||||||
/* Make sure that no dependencies are repeated. This does not
|
|
||||||
really matter for the purpose of updating targets, but it
|
|
||||||
might make some names be listed twice for $^ and $?. */
|
|
||||||
|
|
||||||
depp = &chain;
|
|
||||||
while (*depp)
|
|
||||||
{
|
|
||||||
struct dep *dep = *depp;
|
|
||||||
struct dep **dep_slot = (struct dep **) hash_find_slot (&deps, dep);
|
|
||||||
if (HASH_VACANT (*dep_slot))
|
|
||||||
{
|
|
||||||
hash_insert_at (&deps, dep, dep_slot);
|
|
||||||
depp = &dep->next;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Don't bother freeing duplicates.
|
|
||||||
It's dangerous and little benefit accrues. */
|
|
||||||
*depp = dep->next;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
hash_free (&deps, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Record target-specific variable values for files FILENAMES.
|
/* Record target-specific variable values for files FILENAMES.
|
||||||
TWO_COLON is nonzero if a double colon was used.
|
TWO_COLON is nonzero if a double colon was used.
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,8 @@
|
||||||
|
2009-10-06 Boris Kolpackov <boris@codesynthesis.com>
|
||||||
|
|
||||||
|
* scripts/features/se_explicit: Enable the test for now fixed
|
||||||
|
savannah bug 25780.
|
||||||
|
|
||||||
2009-10-06 Boris Kolpackov <boris@codesynthesis.com>
|
2009-10-06 Boris Kolpackov <boris@codesynthesis.com>
|
||||||
|
|
||||||
* scripts/variables/undefine: Tests for the new undefine feature.
|
* scripts/variables/undefine: Tests for the new undefine feature.
|
||||||
|
|
|
@ -131,9 +131,8 @@ endef
|
||||||
'', "#MAKE#: *** prerequisites cannot be defined in recipes. Stop.\n", 512);
|
'', "#MAKE#: *** prerequisites cannot be defined in recipes. Stop.\n", 512);
|
||||||
|
|
||||||
|
|
||||||
if ($all_tests) {
|
# Automatic $$+ variable expansion issue. Savannah bug #25780
|
||||||
# Automatic $$+ variable expansion issue. Savannah bug #25780
|
run_make_test(q!
|
||||||
run_make_test(q!
|
|
||||||
all : foo foo
|
all : foo foo
|
||||||
.SECONDEXPANSION:
|
.SECONDEXPANSION:
|
||||||
all : $$+ ; @echo '$+'
|
all : $$+ ; @echo '$+'
|
||||||
|
@ -141,11 +140,9 @@ foo : ;
|
||||||
!,
|
!,
|
||||||
'', "foo foo foo foo\n");
|
'', "foo foo foo foo\n");
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($all_tests) {
|
# Automatic $$+ variable expansion issue. Savannah bug #25780
|
||||||
# Automatic $$+ variable expansion issue. Savannah bug #25780
|
run_make_test(q!
|
||||||
run_make_test(q!
|
|
||||||
all : bar bar
|
all : bar bar
|
||||||
bar : ;
|
bar : ;
|
||||||
q%x : ;
|
q%x : ;
|
||||||
|
@ -154,8 +151,6 @@ a%l: q1x $$+ q2x ; @echo '$+'
|
||||||
!,
|
!,
|
||||||
'', "q1x bar bar q2x bar bar\n");
|
'', "q1x bar bar q2x bar bar\n");
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
# This tells the test driver that the perl test script executed properly.
|
# This tells the test driver that the perl test script executed properly.
|
||||||
1;
|
1;
|
||||||
|
|
Loading…
Reference in a new issue