diff options
author | Marc Espie <espie@cvs.openbsd.org> | 2015-11-29 09:17:13 +0000 |
---|---|---|
committer | Marc Espie <espie@cvs.openbsd.org> | 2015-11-29 09:17:13 +0000 |
commit | cb08ba35f709852eceaf6c02c45d0e5dfaa01486 (patch) | |
tree | b338dfbd8933a3ee382ad5d2564fb2c09c8575f3 /usr.bin/make | |
parent | 0636f90435f354080dc94a12b315a28172a17dc7 (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.c | 3 | ||||
-rw-r--r-- | usr.bin/make/parse.c | 93 | ||||
-rw-r--r-- | usr.bin/make/parse.h | 3 |
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(>argets, ParseDoOp, op); + dedup_targets(>argets); 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(>argets); commands_seen = false; - Array_Reset(>argets); 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; |