summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorespie <espie@openbsd.org>2015-11-06 18:41:02 +0000
committerespie <espie@openbsd.org>2015-11-06 18:41:02 +0000
commita04fe9e425dfc79cf77079a28a8b5af4c179fea4 (patch)
tree6a3e43cea583409c9c33b6f54922e16b1fd43bc8
parentDo not compile net/radix_mpath.c in ART-enabled kernels. (diff)
downloadwireguard-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.c54
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