summaryrefslogtreecommitdiff
path: root/usr.bin/make
diff options
context:
space:
mode:
authorMarc Espie <espie@cvs.openbsd.org>2015-11-29 09:17:13 +0000
committerMarc Espie <espie@cvs.openbsd.org>2015-11-29 09:17:13 +0000
commitcb08ba35f709852eceaf6c02c45d0e5dfaa01486 (patch)
treeb338dfbd8933a3ee382ad5d2564fb2c09c8575f3 /usr.bin/make
parent0636f90435f354080dc94a12b315a28172a17dc7 (diff)
fix duplicate targets in target list for good: split previous groupling fix
in two. Catch 22: we have to dedup targets very early so that commands get attached correctly, but we can't figure out the grouplings heuristics until we have all commands... ok millert@
Diffstat (limited to 'usr.bin/make')
-rw-r--r--usr.bin/make/main.c3
-rw-r--r--usr.bin/make/parse.c93
-rw-r--r--usr.bin/make/parse.h3
3 files changed, 70 insertions, 29 deletions
diff --git a/usr.bin/make/main.c b/usr.bin/make/main.c
index 3c721248ab2..6c005df5db0 100644
--- a/usr.bin/make/main.c
+++ b/usr.bin/make/main.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: main.c,v 1.116 2015/11/15 06:19:22 daniel Exp $ */
+/* $OpenBSD: main.c,v 1.117 2015/11/29 09:17:12 espie Exp $ */
/* $NetBSD: main.c,v 1.34 1997/03/24 20:56:36 gwr Exp $ */
/*
@@ -626,6 +626,7 @@ read_all_make_rules(bool noBuiltins, bool read_depend,
if (read_depend)
(void)ReadMakefile(".depend", d);
+ Parse_End();
}
diff --git a/usr.bin/make/parse.c b/usr.bin/make/parse.c
index f967f8ac4aa..11d02df162a 100644
--- a/usr.bin/make/parse.c
+++ b/usr.bin/make/parse.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: parse.c,v 1.113 2015/11/06 18:41:02 espie Exp $ */
+/* $OpenBSD: parse.c,v 1.114 2015/11/29 09:17:12 espie Exp $ */
/* $NetBSD: parse.c,v 1.29 1997/03/10 21:20:04 christos Exp $ */
/*
@@ -100,6 +100,8 @@
* set as persistent arrays for performance reasons.
*/
static struct growableArray gsources, gtargets;
+static struct ohash htargets;
+static bool htargets_setup = false;
#define SOURCES_SIZE 128
#define TARGETS_SIZE 32
@@ -166,6 +168,9 @@ static void create_special_nodes(void);
static bool found_delimiter(const char *);
static unsigned int handle_special_targets(Lst);
static void dump_targets(void);
+static void dedup_targets(struct growableArray *);
+static void build_target_group(struct growableArray *, struct ohash *t);
+static void reset_target_hash(void);
#define P(k) k, sizeof(k), K_##k
@@ -811,7 +816,6 @@ ParseDoDependency(const char *line) /* the line to parse */
* a list of .PATH targets */
unsigned int tOp; /* operator from special target */
-
waiting = 0;
Lst_Init(&paths);
@@ -826,6 +830,7 @@ ParseDoDependency(const char *line) /* the line to parse */
return;
Array_FindP(&gtargets, ParseDoOp, op);
+ dedup_targets(&gtargets);
line = cp;
@@ -1381,12 +1386,9 @@ handle_bsd_command(Buffer linebuf, Buffer copy, const char *line)
return false;
}
-/***
- *** handle a group of commands
- ***/
-
-static void
-register_for_groupling(GNode *gn, struct ohash *temp)
+/* postprocess group of targets prior to linking stuff with them */
+bool
+register_target(GNode *gn, struct ohash *t)
{
unsigned int slot;
uint32_t hv;
@@ -1395,15 +1397,18 @@ register_for_groupling(GNode *gn, struct ohash *temp)
hv = ohash_interval(gn->name, &ename);
- slot = ohash_lookup_interval(temp, gn->name, ename, hv);
- gn2 = ohash_find(temp, slot);
+ slot = ohash_lookup_interval(t, gn->name, ename, hv);
+ gn2 = ohash_find(t, slot);
- if (gn2 == NULL)
- ohash_insert(temp, slot, gn);
+ if (gn2 == NULL) {
+ ohash_insert(t, slot, gn);
+ return true;
+ } else
+ return false;
}
static void
-build_target_group(struct growableArray *targets)
+build_target_group(struct growableArray *targets, struct ohash *t)
{
LstNode ln;
bool seen_target = false;
@@ -1412,9 +1417,12 @@ build_target_group(struct growableArray *targets)
/* may be 0 if wildcard expansion resulted in zero match */
if (targets->n <= 1)
return;
+
+ /* Perform checks to see if we must tie targets together */
/* XXX */
if (targets->a[0]->type & OP_TRANSFORM)
return;
+
for (ln = Lst_First(&targets->a[0]->commands); ln != NULL;
ln = Lst_Adv(ln)) {
struct command *cmd = Lst_Datum(ln);
@@ -1434,39 +1442,71 @@ build_target_group(struct growableArray *targets)
if (seen_target)
return;
- /* target list MAY hold duplicates AND targets may already participate
- * in groupling lists, so rebuild the circular list "from scratch"
- */
-
- struct ohash t;
GNode *gn, *gn2;
-
- ohash_init(&t, 5, &gnode_info);
+ /* targets may already participate in groupling lists,
+ * so rebuild the circular list "from scratch"
+ */
for (i = 0; i < targets->n; i++) {
gn = targets->a[i];
- register_for_groupling(gn, &t);
for (gn2 = gn->groupling; gn2 != gn; gn2 = gn2->groupling) {
if (!gn2)
break;
- register_for_groupling(gn2, &t);
+ register_target(gn2, t);
}
}
- for (gn = ohash_first(&t, &i); gn != NULL; gn = ohash_next(&t, &i)) {
+ for (gn = ohash_first(t, &i); gn != NULL; gn = ohash_next(t, &i)) {
gn->groupling = gn2;
gn2 = gn;
}
- gn = ohash_first(&t, &i);
+ gn = ohash_first(t, &i);
gn->groupling = gn2;
+}
+
+static void
+reset_target_hash()
+{
+ if (htargets_setup)
+ ohash_delete(&htargets);
+ ohash_init(&htargets, 5, &gnode_info);
+ htargets_setup = true;
+}
+
+void
+Parse_End()
+{
+ if (htargets_setup)
+ ohash_delete(&htargets);
+}
+
+static void
+dedup_targets(struct growableArray *targets)
+{
+ unsigned int i, j;
- ohash_delete(&t);
+ if (targets->n <= 1)
+ return;
+
+ reset_target_hash();
+ /* first let's de-dup the list */
+ for (i = 0, j = 0; i < targets->n; i++) {
+ GNode *gn = targets->a[i];
+ if (register_target(gn, &htargets))
+ targets->a[j++] = targets->a[i];
+ }
+ targets->n = j;
}
+
+/***
+ *** handle a group of commands
+ ***/
+
static void
finish_commands(struct growableArray *targets)
{
- build_target_group(targets);
+ build_target_group(targets, &htargets);
Array_Every(targets, ParseHasCommands);
}
@@ -1596,7 +1636,6 @@ Parse_File(const char *filename, FILE *stream)
if (commands_seen)
finish_commands(&gtargets);
commands_seen = false;
- Array_Reset(&gtargets);
if (Parse_As_Var_Assignment(stripped))
expectingCommands = false;
else {
diff --git a/usr.bin/make/parse.h b/usr.bin/make/parse.h
index d4235f40a06..edeceb2353f 100644
--- a/usr.bin/make/parse.h
+++ b/usr.bin/make/parse.h
@@ -1,6 +1,6 @@
#ifndef PARSE_H
#define PARSE_H
-/* $OpenBSD: parse.h,v 1.6 2012/10/02 10:29:31 espie Exp $ */
+/* $OpenBSD: parse.h,v 1.7 2015/11/29 09:17:12 espie Exp $ */
/*
* Copyright (c) 2001 Marc Espie.
*
@@ -31,6 +31,7 @@
*/
extern void Parse_Init(void);
+extern void Parse_End(void);
extern Lst systemIncludePath;
extern Lst userIncludePath;