diff options
author | 2015-11-06 18:41:02 +0000 | |
---|---|---|
committer | 2015-11-06 18:41:02 +0000 | |
commit | a04fe9e425dfc79cf77079a28a8b5af4c179fea4 (patch) | |
tree | 6a3e43cea583409c9c33b6f54922e16b1fd43bc8 | |
parent | Do not compile net/radix_mpath.c in ART-enabled kernels. (diff) | |
download | wireguard-openbsd-a04fe9e425dfc79cf77079a28a8b5af4c179fea4.tar.xz wireguard-openbsd-a04fe9e425dfc79cf77079a28a8b5af4c179fea4.zip |
I was very optimistic in groupling creation. Turns out lists of targets
can have duplicates, or overlap, or even be empty thanks to fnmatch.
So use the big guns to build the circular list correctly, namely
actual lists of targets that are made together will be registered in a
hash first, then we recreate the full list from there.
(merging lists is not an issue, since groupling links are only used to
temporarily lock targets in parallel mode).
Issue noticed by guenther@, okay guenther@
-rw-r--r-- | usr.bin/make/parse.c | 54 |
1 files changed, 48 insertions, 6 deletions
diff --git a/usr.bin/make/parse.c b/usr.bin/make/parse.c index 5e83ff29948..f967f8ac4aa 100644 --- a/usr.bin/make/parse.c +++ b/usr.bin/make/parse.c @@ -1,4 +1,4 @@ -/* $OpenBSD: parse.c,v 1.112 2015/01/23 22:35:57 espie Exp $ */ +/* $OpenBSD: parse.c,v 1.113 2015/11/06 18:41:02 espie Exp $ */ /* $NetBSD: parse.c,v 1.29 1997/03/10 21:20:04 christos Exp $ */ /* @@ -63,9 +63,11 @@ #include <assert.h> #include <ctype.h> +#include <stddef.h> #include <stdio.h> #include <stdlib.h> #include <string.h> +#include <ohash.h> #include "config.h" #include "defines.h" #include "dir.h" @@ -1384,15 +1386,31 @@ handle_bsd_command(Buffer linebuf, Buffer copy, const char *line) ***/ static void +register_for_groupling(GNode *gn, struct ohash *temp) +{ + unsigned int slot; + uint32_t hv; + const char *ename = NULL; + GNode *gn2; + + hv = ohash_interval(gn->name, &ename); + + slot = ohash_lookup_interval(temp, gn->name, ename, hv); + gn2 = ohash_find(temp, slot); + + if (gn2 == NULL) + ohash_insert(temp, slot, gn); +} + +static void build_target_group(struct growableArray *targets) { - unsigned int i; LstNode ln; bool seen_target = false; + unsigned int i; - if (targets->n == 1) - return; - if (targets->a[0]->groupling != NULL) + /* may be 0 if wildcard expansion resulted in zero match */ + if (targets->n <= 1) return; /* XXX */ if (targets->a[0]->type & OP_TRANSFORM) @@ -1416,9 +1434,33 @@ 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); + for (i = 0; i < targets->n; i++) { - targets->a[i]->groupling = targets->a[(i+1)%targets->n]; + 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); + } } + + for (gn = ohash_first(&t, &i); gn != NULL; gn = ohash_next(&t, &i)) { + gn->groupling = gn2; + gn2 = gn; + } + gn = ohash_first(&t, &i); + gn->groupling = gn2; + + ohash_delete(&t); } static void |