From 61f76e6722c809de2ead96bb027cd4f77df0ac04 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Tue, 4 Oct 2016 10:34:18 +0200 Subject: [PATCH 1/2] make old_race a little bit less awful. --- src/kernel/config.c | 10 ---------- src/kernel/race.c | 44 ++++++++++++++++++++++++++++++++++++++++++ src/kernel/race.test.c | 16 +++++++++++++++ 3 files changed, 60 insertions(+), 10 deletions(-) diff --git a/src/kernel/config.c b/src/kernel/config.c index f7eb0e303..ba69f142e 100644 --- a/src/kernel/config.c +++ b/src/kernel/config.c @@ -137,16 +137,6 @@ int NMRTimeout(void) return config_get_int("nmr.timeout", 0); } -race_t old_race(const struct race * rc) -{ - race_t i; - // TODO: this sucks so bad! - for (i = 0; i != MAXRACES; ++i) { - if (get_race(i) == rc) return i; - } - return NORACE; -} - helpmode helpmodes[] = { { "all", HELP_ALL } , diff --git a/src/kernel/race.c b/src/kernel/race.c index 57ebe972a..ce13d1ef7 100644 --- a/src/kernel/race.c +++ b/src/kernel/race.c @@ -86,6 +86,50 @@ const struct race *get_race(race_t rt) { return rc_find(name); } +typedef struct xref { + race_t id; + const race *rc; +} rc_xref; + +int cmp_xref(const void *a, const void *b) +{ + const rc_xref *l = (const rc_xref *)a; + const rc_xref *r = (const rc_xref *)b; + if (l->rcrc) return -1; + if (l->rc>r->rc) return 1; + return 0; +} + +race_t old_race(const struct race * rc) +{ + static int cache; + static rc_xref *xrefs; + int i, l, r; + + if (rc_changed(&cache)) { + if (!xrefs) { + xrefs = malloc(sizeof(rc_xref) * MAXRACES); + } + for (i = 0; i != MAXRACES; ++i) { + xrefs[i].rc = get_race(i); + xrefs[i].id = (race_t)i; + } + qsort(xrefs, MAXRACES, sizeof(rc_xref), cmp_xref); + } + l=0; r=MAXRACES-1; + while (l<=r) { + int m = (l+r)/2; + if (rcxrefs[m].rc) { + l = m+1; + } else { + return (race_t)xrefs[m].id; + } + } + return NORACE; +} + race_list *get_familiarraces(void) { static int init = 0; diff --git a/src/kernel/race.test.c b/src/kernel/race.test.c index 7bccdbba8..663a538ee 100644 --- a/src/kernel/race.test.c +++ b/src/kernel/race.test.c @@ -66,10 +66,26 @@ static void test_race_get(CuTest *tc) { test_cleanup(); } +static void test_old_race(CuTest *tc) +{ + race * rc1, *rc2; + test_setup(); + test_create_race("dwarf"); + rc1 = test_create_race("elf"); + rc2 = test_create_race("onkel"); + CuAssertIntEquals(tc, RC_ELF, old_race(rc1)); + CuAssertIntEquals(tc, NORACE, old_race(rc2)); + rc2 = test_create_race("human"); + CuAssertIntEquals(tc, RC_ELF, old_race(rc1)); + CuAssertIntEquals(tc, RC_HUMAN, old_race(rc2)); + test_cleanup(); +} + CuSuite *get_race_suite(void) { CuSuite *suite = CuSuiteNew(); SUITE_ADD_TEST(suite, test_race_get); + SUITE_ADD_TEST(suite, test_old_race); SUITE_ADD_TEST(suite, test_rc_name); SUITE_ADD_TEST(suite, test_rc_defaults); SUITE_ADD_TEST(suite, test_rc_find); From e79b36bc366c235dd42f75cb4eef0bb85daa598d Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Tue, 4 Oct 2016 10:51:37 +0200 Subject: [PATCH 2/2] introduced a memory leak i last commit --- src/kernel/race.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/kernel/race.c b/src/kernel/race.c index ce13d1ef7..5b991eca6 100644 --- a/src/kernel/race.c +++ b/src/kernel/race.c @@ -100,10 +100,10 @@ int cmp_xref(const void *a, const void *b) return 0; } +static rc_xref *xrefs; race_t old_race(const struct race * rc) { static int cache; - static rc_xref *xrefs; int i, l, r; if (rc_changed(&cache)) { @@ -170,6 +170,8 @@ void free_races(void) { while (races) { race * rc = races->next; free_params(&races->parameters); + free(xrefs); + xrefs = 0; free(races->_name); free(races->def_damage); free(races);