diff --git a/src/kernel/building.c b/src/kernel/building.c index d97085345..fe28b3752 100644 --- a/src/kernel/building.c +++ b/src/kernel/building.c @@ -129,14 +129,6 @@ static void free_buildingtype(void *ptr) { free(btype); } -void free_buildingtypes(void) { - cb_clear(&cb_bldgtypes); - selist_foreach(buildingtypes, free_buildingtype); - selist_free(buildingtypes); - buildingtypes = 0; - ++bt_changes; -} - building_type *bt_get_or_create(const char *name) { assert(name && name[0]); @@ -265,17 +257,28 @@ building *findbuilding(int i) static local_names *bnames; -/* Find the building type for a given localized name (as seen by the user). Useful for parsing - * orders. The inverse of locale_string(lang, btype->_name), sort of. */ -const building_type *findbuildingtype(const char *name, - const struct locale *lang) -{ - variant type; - local_names *bn = bnames; +static void free_bnames() { + while (bnames) { + local_names *bn = bnames; + bnames = bnames->next; + freetokens(bn->names); + free(bn); + } +} +static local_names *get_bnames(const struct locale *lang) +{ + static int config; + local_names *bn; + + if (bt_changed(&config)) { + free_bnames(); + } + bn = bnames; while (bn) { - if (bn->lang == lang) + if (bn->lang == lang) { break; + } bn = bn->next; } if (!bn) { @@ -292,14 +295,26 @@ const building_type *findbuildingtype(const char *name, const char *n = LOC(lang, btype->_name); if (!n) { log_error("building type %s has no translation in %s", - btype->_name, locale_name(lang)); - } else { + btype->_name, locale_name(lang)); + } + else { + variant type; type.v = (void *)btype; addtoken((struct tnode **)&bn->names, n, type); } } bnames = bn; } + return bn; +} + +/* Find the building type for a given localized name (as seen by the user). Useful for parsing + * orders. The inverse of locale_string(lang, btype->_name), sort of. */ +const building_type *findbuildingtype(const char *name, + const struct locale *lang) +{ + variant type; + local_names *bn = get_bnames(lang); if (findtoken(bn->names, name, &type) == E_TOK_NOMATCH) return NULL; return (const building_type *)type.v; @@ -871,3 +886,12 @@ int cmp_current_owner(const building * b, const building * a) } return 0; } + +void free_buildingtypes(void) { + free_bnames(); + cb_clear(&cb_bldgtypes); + selist_foreach(buildingtypes, free_buildingtype); + selist_free(buildingtypes); + buildingtypes = 0; + ++bt_changes; +} diff --git a/src/laws.test.c b/src/laws.test.c index 774ed6ecf..bb26ed872 100644 --- a/src/laws.test.c +++ b/src/laws.test.c @@ -392,6 +392,27 @@ static void test_unit_limit(CuTest * tc) test_teardown(); } +static void test_findparam_ex(CuTest *tc) +{ + struct locale *lang; + struct building_type *btype; + test_setup(); + lang = test_create_locale(); + locale_setstring(lang, "temple", "TEMPEL"); + btype = test_create_buildingtype("temple"); + + CuAssertIntEquals(tc, P_GEBAEUDE, findparam_ex("TEMPEL", lang)); + CuAssertIntEquals(tc, P_GEBAEUDE, findparam_ex( + locale_string(lang, parameters[P_BUILDING], false), lang)); + CuAssertIntEquals(tc, P_SHIP, findparam_ex( + locale_string(lang, parameters[P_SHIP], false), lang)); + CuAssertIntEquals(tc, P_FACTION, findparam_ex( + locale_string(lang, parameters[P_FACTION], false), lang)); + CuAssertIntEquals(tc, P_UNIT, findparam_ex( + locale_string(lang, parameters[P_UNIT], false), lang)); + test_teardown(); +} + static void test_maketemp(CuTest * tc) { faction *f; @@ -1762,6 +1783,7 @@ CuSuite *get_laws_suite(void) CuSuite *suite = CuSuiteNew(); SUITE_ADD_TEST(suite, test_maketemp_default_order); SUITE_ADD_TEST(suite, test_maketemp); + SUITE_ADD_TEST(suite, test_findparam_ex); SUITE_ADD_TEST(suite, test_nmr_warnings); SUITE_ADD_TEST(suite, test_ally_cmd); SUITE_ADD_TEST(suite, test_name_cmd); diff --git a/src/tests.c b/src/tests.c index f270d9c58..cad296e57 100644 --- a/src/tests.c +++ b/src/tests.c @@ -420,7 +420,9 @@ building_type * test_create_buildingtype(const char * name) con->materials[0].rtype = get_resourcetype(R_STONE); } if (default_locale) { - locale_setstring(default_locale, name, name); + if (locale_getstring(default_locale, name) == NULL) { + locale_setstring(default_locale, name, name); + } } return btype; }