=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/make/parse.c,v retrieving revision 1.113 retrieving revision 1.114 diff -c -r1.113 -r1.114 *** src/usr.bin/make/parse.c 2015/11/06 18:41:02 1.113 --- src/usr.bin/make/parse.c 2015/11/29 09:17:12 1.114 *************** *** 1,4 **** ! /* $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 $ */ /* --- 1,4 ---- ! /* $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,105 **** --- 100,107 ---- * 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,171 **** --- 168,176 ---- 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,817 **** * a list of .PATH targets */ unsigned int tOp; /* operator from special target */ - waiting = 0; Lst_Init(&paths); --- 816,821 ---- *************** *** 826,831 **** --- 830,836 ---- return; Array_FindP(>argets, ParseDoOp, op); + dedup_targets(>argets); line = cp; *************** *** 1381,1392 **** return false; } ! /*** ! *** handle a group of commands ! ***/ ! ! static void ! register_for_groupling(GNode *gn, struct ohash *temp) { unsigned int slot; uint32_t hv; --- 1386,1394 ---- return false; } ! /* 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,1409 **** 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) { LstNode ln; bool seen_target = false; --- 1397,1414 ---- hv = ohash_interval(gn->name, &ename); ! slot = ohash_lookup_interval(t, gn->name, ename, hv); ! gn2 = ohash_find(t, slot); ! if (gn2 == NULL) { ! ohash_insert(t, slot, gn); ! return true; ! } else ! return false; } static void ! build_target_group(struct growableArray *targets, struct ohash *t) { LstNode ln; bool seen_target = false; *************** *** 1412,1420 **** --- 1417,1428 ---- /* 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,1472 **** 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++) { 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 finish_commands(struct growableArray *targets) { ! build_target_group(targets); Array_Every(targets, ParseHasCommands); } --- 1442,1512 ---- if (seen_target) return; ! GNode *gn, *gn2; ! /* 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]; for (gn2 = gn->groupling; gn2 != gn; gn2 = gn2->groupling) { if (!gn2) break; ! register_target(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; + } ! 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; + + 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, &htargets); Array_Every(targets, ParseHasCommands); } *************** *** 1596,1602 **** if (commands_seen) finish_commands(>argets); commands_seen = false; - Array_Reset(>argets); if (Parse_As_Var_Assignment(stripped)) expectingCommands = false; else { --- 1636,1641 ----