diff --git a/src/seen.c b/src/seen.c index 2bbc529b0..1b147fb19 100644 --- a/src/seen.c +++ b/src/seen.c @@ -96,30 +96,45 @@ seen_region *find_seen(struct seen_region *seehash[], const region * r) return NULL; } -void get_seen_interval(struct seen_region *seen[], struct region **firstp, struct region **lastp) -{ - /* this is required to find the neighbour regions of the ones we are in, - * which may well be outside of [firstregion, lastregion) */ +void seenhash_map(struct seen_region *seen[], void(*cb)(seen_region *, void *), void *cbdata) { int i; - region *first, *last; - - assert(seen && firstp && lastp); - first = *firstp; - last = *lastp; for (i = 0; i != MAXSEEHASH; ++i) { seen_region *sr = seen[i]; while (sr != NULL) { - if (first == NULL || sr->r->index < first->index) { - first = sr->r; - } - if (last != NULL && sr->r->index >= last->index) { - last = sr->r->next; - } + cb(sr, cbdata); sr = sr->nextHash; } } - *firstp = first; - *lastp = last; +} + +typedef struct cb_interval { + region *first; + region *last; +} cb_interval; + +static void cb_get_interval(seen_region *sr, void *cbdata) { + cb_interval *iv = (cb_interval *)cbdata; + region *r = sr->r; + if (iv->first == NULL || r->index < iv->first->index) { + iv->first = r; + } + if (iv->last != NULL && r->index >= iv->last->index) { + iv->last = r->next; + } +} + +/* this function adds the neighbour regions of the ones we have seen + * to the interval, which may be outside of [faction.first, faction.last) + */ +void get_seen_interval(struct seen_region *seen[], struct region **firstp, struct region **lastp) +{ + cb_interval interval; + + interval.first = *firstp; + interval.last = *lastp; + seenhash_map(seen, cb_get_interval, &interval); + *firstp = interval.first; + *lastp = interval.last; } bool add_seen(struct seen_region *seehash[], struct region *r, unsigned char mode, bool dis) diff --git a/src/seen.h b/src/seen.h index 9e6312d78..2a393adf2 100644 --- a/src/seen.h +++ b/src/seen.h @@ -53,6 +53,7 @@ struct seen_region *find_seen(struct seen_region *seehash[], const struct region void get_seen_interval(struct seen_region *seen[], struct region **firstp, struct region **lastp); bool add_seen(struct seen_region *seehash[], struct region *r, unsigned char mode, bool dis); void link_seen(struct seen_region *seehash[], const struct region *first, const struct region *last); +void seenhash_map(struct seen_region *seen[], void(*cb)(struct seen_region *, void *), void *cbdata); #ifdef __cplusplus } #endif diff --git a/src/seen.test.c b/src/seen.test.c index be2189c14..a181a690d 100644 --- a/src/seen.test.c +++ b/src/seen.test.c @@ -121,6 +121,28 @@ static void test_seen_interval_forward(CuTest *tc) { test_cleanup(); } +static void cb_testmap(seen_region *sr, void *cbdata) { + int *ip = (int *)cbdata; + *ip += sr->r->y; +} + +static void test_seenhash_map(CuTest *tc) { + region *r; + seen_region **seen; + int i = 0; + + test_cleanup(); + seen = seen_init(); + r = test_create_region(1, 1, 0); + add_seen(seen, r, see_unit, false); + r = test_create_region(2, 2, 0); + add_seen(seen, r, see_unit, false); + seenhash_map(seen, cb_testmap, &i); + CuAssertIntEquals(tc, 3, i); + seen_done(seen); + test_cleanup(); +} + CuSuite *get_seen_suite(void) { CuSuite *suite = CuSuiteNew(); @@ -129,5 +151,6 @@ CuSuite *get_seen_suite(void) SUITE_ADD_TEST(suite, test_seen_region); SUITE_ADD_TEST(suite, test_seen_interval_backward); SUITE_ADD_TEST(suite, test_seen_interval_forward); + SUITE_ADD_TEST(suite, test_seenhash_map); return suite; }