diff --git a/src/bind_region.c b/src/bind_region.c index 5db39b6fc..e10b22cfd 100644 --- a/src/bind_region.c +++ b/src/bind_region.c @@ -228,7 +228,7 @@ static int tolua_region_get_luxury(lua_State * L) if (r->land) { const item_type *lux = r_luxury(r); if (lux) { - const char *name = lux->rtype->_name[0]; + const char *name = lux->rtype->_name; tolua_pushstring(L, name); return 1; } @@ -268,7 +268,7 @@ static int tolua_region_get_herb(lua_State * L) { region *r = (region *) tolua_tousertype(L, 1, 0); if (r->land && r->land->herbtype) { - const char *name = r->land->herbtype->rtype->_name[0]; + const char *name = r->land->herbtype->rtype->_name; tolua_pushstring(L, name); return 1; } diff --git a/src/bindings.c b/src/bindings.c index b5cfef0b5..140e738d3 100755 --- a/src/bindings.c +++ b/src/bindings.c @@ -151,7 +151,7 @@ int tolua_itemlist_next(lua_State * L) item **item_ptr = (item **) lua_touserdata(L, lua_upvalueindex(1)); item *itm = *item_ptr; if (itm != NULL) { - tolua_pushstring(L, itm->type->rtype->_name[0]); + tolua_pushstring(L, itm->type->rtype->_name); *item_ptr = itm->next; return 1; } @@ -820,7 +820,7 @@ static int config_get_resource(lua_State * L) lua_newtable(L); for (i = 0; itype->construction->materials[i].number; ++i) { lua_pushstring(L, - itype->construction->materials[i].rtype->_name[0]); + itype->construction->materials[i].rtype->_name); lua_pushinteger(L, itype->construction->materials[i].number); lua_settable(L, -3); } @@ -865,7 +865,7 @@ static int config_get_btype(lua_State * L) lua_newtable(L); for (i = 0; btype->maintenance[i].number; ++i) { lua_pushstring(L, - btype->maintenance[i].rtype->_name[0]); + btype->maintenance[i].rtype->_name); lua_pushinteger(L, btype->maintenance[i].number); lua_settable(L, -3); } @@ -884,7 +884,7 @@ static int config_get_btype(lua_State * L) lua_newtable(L); for (i = 0; btype->construction->materials[i].number; ++i) { lua_pushstring(L, - btype->construction->materials[i].rtype->_name[0]); + btype->construction->materials[i].rtype->_name); lua_pushinteger(L, btype->construction->materials[i].number); lua_settable(L, -3); } @@ -950,7 +950,7 @@ static int config_get_stype(lua_State * L) lua_newtable(L); for (i = 0; stype->construction->materials[i].number; ++i) { lua_pushstring(L, - stype->construction->materials[i].rtype->_name[0]); + stype->construction->materials[i].rtype->_name); lua_pushinteger(L, stype->construction->materials[i].number); lua_settable(L, -3); } diff --git a/src/helpers.c b/src/helpers.c index ffe1af9e2..8ec55e7de 100644 --- a/src/helpers.c +++ b/src/helpers.c @@ -46,7 +46,7 @@ lua_giveitem(unit * s, unit * d, const item_type * itype, int n, struct order *o lua_State *L = (lua_State *) global.vm_state; char fname[64]; int result = -1; - const char *iname = itype->rtype->_name[0]; + const char *iname = itype->rtype->_name; assert(s != NULL); strlcpy(fname, iname, sizeof(fname)); @@ -81,7 +81,7 @@ static int limit_resource(const region * r, const resource_type * rtype) int result = -1; lua_State *L = (lua_State *) global.vm_state; - strlcpy(fname, rtype->_name[0], sizeof(fname)); + strlcpy(fname, rtype->_name, sizeof(fname)); strlcat(fname, "_limit", sizeof(fname)); lua_getglobal(L, fname); @@ -110,7 +110,7 @@ produce_resource(region * r, const resource_type * rtype, int norders) lua_State *L = (lua_State *) global.vm_state; char fname[64]; - strlcpy(fname, rtype->_name[0], sizeof(fname)); + strlcpy(fname, rtype->_name, sizeof(fname)); strlcat(fname, "_produce", sizeof(fname)); lua_getglobal(L, fname); @@ -250,7 +250,7 @@ lua_changeresource(unit * u, const struct resource_type *rtype, int delta) int result = -1; char fname[64]; - strlcpy(fname, rtype->_name[0], sizeof(fname)); + strlcpy(fname, rtype->_name, sizeof(fname)); strlcat(fname, "_changeresource", sizeof(fname)); lua_getglobal(L, fname); @@ -280,7 +280,7 @@ static int lua_getresource(unit * u, const struct resource_type *rtype) int result = -1; char fname[64]; - strlcpy(fname, rtype->_name[0], sizeof(fname)); + strlcpy(fname, rtype->_name, sizeof(fname)); strlcat(fname, "_getresource", sizeof(fname)); lua_getglobal(L, fname); @@ -315,7 +315,7 @@ static bool lua_canuse_item(const unit * u, const struct item_type *itype) lua_getglobal(L, fname); if (lua_isfunction(L, -1)) { tolua_pushusertype(L, (void *)u, TOLUA_CAST "unit"); - tolua_pushstring(L, itype->rtype->_name[0]); + tolua_pushstring(L, itype->rtype->_name); if (lua_pcall(L, 2, 1, 0) != 0) { const char *error = lua_tostring(L, -1); @@ -503,7 +503,7 @@ lua_useitem(struct unit *u, const struct item_type *itype, int amount, char fname[64]; strlcpy(fname, "use_", sizeof(fname)); - strlcat(fname, itype->rtype->_name[0], sizeof(fname)); + strlcat(fname, itype->rtype->_name, sizeof(fname)); lua_getglobal(L, fname); if (lua_isfunction(L, -1)) { diff --git a/src/kernel/item.c b/src/kernel/item.c index faa6f1611..94b3b8b48 100644 --- a/src/kernel/item.c +++ b/src/kernel/item.c @@ -139,18 +139,25 @@ static int res_changeitem(unit * u, const resource_type * rtype, int delta) const char *resourcename(const resource_type * rtype, int flags) { - int i = 0; - + if (!rtype) + assert(rtype); if (rtype) { if (rtype->name) return rtype->name(rtype, flags); - if (flags & NMF_PLURAL) - i = 1; - if (flags & NMF_APPEARANCE && rtype->itype && rtype->itype->_appearance[i]) { - return rtype->itype->_appearance[i]; + if (flags & NMF_APPEARANCE && rtype->itype) { + int i = (flags & NMF_PLURAL) ? 1 : 0; + const char * result = rtype->itype->_appearance[i]; + if (result) { + return result; + } } - return rtype->_name[i]; + if (flags & NMF_PLURAL) { + static char name[64]; // FIXME: static return value + _snprintf(name, sizeof(name), "%s_p", rtype->_name); + return name; + } + return rtype->_name; } return "none"; } @@ -160,7 +167,7 @@ static int num_resources; static void rt_register(resource_type * rtype) { char buffer[64]; - const char * name = rtype->_name[0]; + const char * name = rtype->_name; size_t len = strlen(name); assert(len < sizeof(buffer) - sizeof(rtype)); @@ -173,9 +180,7 @@ resource_type *rt_get_or_create(const char *name) { resource_type *rtype = rt_find(name); if (!rtype) { rtype = (resource_type *)calloc(sizeof(resource_type), 1); - rtype->_name[0] = _strdup(name); - rtype->_name[1] = (char *)malloc(strlen(name) + 3); - sprintf(rtype->_name[1], "%s_p", name); + rtype->_name = _strdup(name); rt_register(rtype); } return rtype; @@ -184,7 +189,7 @@ resource_type *rt_get_or_create(const char *name) { void it_register(item_type * itype) { char buffer[64]; - const char * name = itype->rtype->_name[0]; + const char * name = itype->rtype->_name; size_t len = strlen(name); assert(len < sizeof(buffer) - sizeof(itype)); @@ -225,7 +230,7 @@ item_type *it_find(const char *zname) item_type *it_get_or_create(resource_type *rtype) { item_type * itype; assert(rtype); - itype = it_find(rtype->_name[0]); + itype = it_find(rtype->_name); assert(!itype || !itype->rtype || itype->rtype == rtype); if (!itype) { itype = (item_type *)calloc(sizeof(item_type), 1); @@ -409,7 +414,7 @@ item *i_add(item ** pi, item * i) { assert(i && i->type && !i->next); while (*pi) { - int d = strcmp((*pi)->type->rtype->_name[0], i->type->rtype->_name[0]); + int d = strcmp((*pi)->type->rtype->_name, i->type->rtype->_name); if (d >= 0) break; pi = &(*pi)->next; @@ -432,7 +437,7 @@ void i_merge(item ** pi, item ** si) while (i) { item *itmp; while (*pi) { - int d = strcmp((*pi)->type->rtype->_name[0], i->type->rtype->_name[0]); + int d = strcmp((*pi)->type->rtype->_name, i->type->rtype->_name); if (d >= 0) break; pi = &(*pi)->next; @@ -456,7 +461,7 @@ item *i_change(item ** pi, const item_type * itype, int delta) { assert(itype); while (*pi) { - int d = strcmp((*pi)->type->rtype->_name[0], itype->rtype->_name[0]); + int d = strcmp((*pi)->type->rtype->_name, itype->rtype->_name); if (d >= 0) break; pi = &(*pi)->next; @@ -1044,7 +1049,7 @@ static int add_resourcename_cb(const void * match, const void * key, size_t keyl cb_get_kv(match, &rtype, sizeof(rtype)); for (i = 0; i != 2; ++i) { char buffer[128]; - const char * name = locale_string(lang, rtype->_name[i]); + const char * name = locale_string(lang, resourcename(rtype, (i==0) ? 0 : NMF_PLURAL)); if (name && transliterate(buffer, sizeof(buffer), name)) { size_t len = strlen(buffer); @@ -1095,7 +1100,7 @@ static int add_itemname_cb(const void * match, const void * key, size_t keylen, int i; for (i = 0; i != 2; ++i) { char buffer[128]; - const char * name = locale_string(lang, rtype->_name[i]); + const char * name = locale_string(lang, resourcename(rtype, (i == 0) ? 0 : NMF_PLURAL)); if (name && transliterate(buffer, sizeof(buffer), name)) { size_t len = strlen(buffer); @@ -1180,8 +1185,7 @@ int free_itype_cb(const void * match, const void * key, size_t keylen, void *cbd int free_rtype_cb(const void * match, const void * key, size_t keylen, void *cbdata) { resource_type *rtype; cb_get_kv(match, &rtype, sizeof(rtype)); - free(rtype->_name[0]); - free(rtype->_name[1]); + free(rtype->_name); free(rtype); return 0; } diff --git a/src/kernel/item.h b/src/kernel/item.h index 39b5576b8..ade5cd17a 100644 --- a/src/kernel/item.h +++ b/src/kernel/item.h @@ -64,7 +64,7 @@ extern "C" { typedef char *(*rtype_name) (const struct resource_type * rtype, int flags); typedef struct resource_type { /* --- constants --- */ - char *_name[2]; /* wie es heißt */ + char *_name; /* wie es heißt */ unsigned int flags; /* --- functions --- */ rtype_uchange uchange; @@ -254,7 +254,6 @@ extern "C" { /* creation */ resource_type *rt_get_or_create(const char *name); -// resource_type *new_resourcetype(const char **names, const char **appearances, int flags); item_type *it_get_or_create(resource_type *rtype); extern item_type *new_itemtype(resource_type * rtype, int iflags, int weight, int capacity); diff --git a/src/kernel/item.test.c b/src/kernel/item.test.c index 3613777c8..8d4285a54 100644 --- a/src/kernel/item.test.c +++ b/src/kernel/item.test.c @@ -10,6 +10,38 @@ #include #include +#include + +static void test_resourcename_no_appearance(CuTest *tc) { + const resource_type *rtype; + + test_cleanup(); + init_resources(); // creates R_SILVER + rtype = get_resourcetype(R_SILVER); + assert(rtype && rtype->itype); + assert(rtype->itype->_appearance[0] == 0); + assert(rtype->itype->_appearance[1] == 0); + CuAssertStrEquals(tc, "money", resourcename(rtype, 0)); + CuAssertStrEquals(tc, "money_p", resourcename(rtype, NMF_PLURAL)); + CuAssertStrEquals(tc, "money", resourcename(rtype, NMF_APPEARANCE)); + CuAssertStrEquals(tc, "money_p", resourcename(rtype, NMF_APPEARANCE|NMF_PLURAL)); + test_cleanup(); +} + +static void test_resourcename_with_appearance(CuTest *tc) { + item_type *itype; + + test_cleanup(); + itype = it_get_or_create(rt_get_or_create("foo")); + assert(itype && itype->rtype); + it_set_appearance(itype, "bar"); + CuAssertStrEquals(tc, "foo", resourcename(itype->rtype, 0)); + CuAssertStrEquals(tc, "foo_p", resourcename(itype->rtype, NMF_PLURAL)); + CuAssertStrEquals(tc, "bar", resourcename(itype->rtype, NMF_APPEARANCE)); + CuAssertStrEquals(tc, "bar_p", resourcename(itype->rtype, NMF_APPEARANCE | NMF_PLURAL)); + test_cleanup(); +} + static void test_uchange(CuTest * tc, unit * u, const resource_type * rtype) { int n; change_resource(u, rtype, 4); @@ -26,7 +58,6 @@ void test_change_item(CuTest * tc) unit * u; test_cleanup(); - register_resources(); init_resources(); test_create_world(); @@ -103,6 +134,8 @@ void test_findresourcetype(CuTest * tc) CuSuite *get_item_suite(void) { CuSuite *suite = CuSuiteNew(); + SUITE_ADD_TEST(suite, test_resourcename_no_appearance); + SUITE_ADD_TEST(suite, test_resourcename_with_appearance); SUITE_ADD_TEST(suite, test_change_item); SUITE_ADD_TEST(suite, test_change_person); SUITE_ADD_TEST(suite, test_resource_type); diff --git a/src/kernel/pool.c b/src/kernel/pool.c index 6f8e378f7..e38c31011 100644 --- a/src/kernel/pool.c +++ b/src/kernel/pool.c @@ -61,7 +61,7 @@ int get_resource(const unit * u, const resource_type * rtype) if (rtype == get_resourcetype(R_PERMAURA)) { return max_spellpoints(u->region, u); } - log_error("trying to get unknown resource '%s'.\n", rtype->_name[0]); + log_error("trying to get unknown resource '%s'.\n", rtype->_name); return 0; } @@ -80,7 +80,7 @@ int change_resource(unit * u, const resource_type * rtype, int change) assert(i == get_resource(u, rtype)); assert(i >= 0); if (i >= 100000000) { - log_warning("%s has %d %s\n", unitname(u), i, rtype->_name[0]); + log_warning("%s has %d %s\n", unitname(u), i, rtype->_name); } return i; } diff --git a/src/kernel/save.c b/src/kernel/save.c index 0180f0ead..092a00d12 100644 --- a/src/kernel/save.c +++ b/src/kernel/save.c @@ -411,7 +411,7 @@ void read_items(struct storage *store, item ** ilist) rtype = rt_find(ibuf); READ_INT(store, &i); if (i <= 0) { - log_error("data contains an entry with %d %s\n", i, rtype->_name[1]); + log_error("data contains an entry with %d %s\n", i, resourcename(rtype, NMF_PLURAL)); } else { if (rtype && rtype->itype) { diff --git a/src/kernel/xmlreader.c b/src/kernel/xmlreader.c index 18d284e94..bb072d8fa 100644 --- a/src/kernel/xmlreader.c +++ b/src/kernel/xmlreader.c @@ -776,7 +776,7 @@ static weapon_type *xml_readweapon(xmlXPathContextPtr xpath, item_type * itype) parse_function(node, &fun, &propValue); if (fun == NULL) { - log_error("unknown function name '%s' for item '%s'\n", (const char *)propValue, itype->rtype->_name[0]); + log_error("unknown function name '%s' for item '%s'\n", (const char *)propValue, itype->rtype->_name); xmlFree(propValue); continue; } @@ -786,7 +786,7 @@ static weapon_type *xml_readweapon(xmlXPathContextPtr xpath, item_type * itype) (bool(*)(const struct troop *, const struct weapon_type *, int *))fun; } else { - log_error("unknown function type '%s' for item '%s'\n", (const char *)propValue, itype->rtype->_name[0]); + log_error("unknown function type '%s' for item '%s'\n", (const char *)propValue, itype->rtype->_name); } xmlFree(propValue); } @@ -880,7 +880,7 @@ static item_type *xml_readitem(xmlXPathContextPtr xpath, resource_type * rtype) parse_function(node, &fun, &propValue); if (fun == NULL) { - log_error("unknown function name '%s' for item '%s'\n", (const char *)propValue, rtype->_name[0]); + log_error("unknown function name '%s' for item '%s'\n", (const char *)propValue, rtype->_name); xmlFree(propValue); continue; } @@ -901,7 +901,7 @@ static item_type *xml_readitem(xmlXPathContextPtr xpath, resource_type * rtype) (int (*)(struct unit *, int, const struct item_type *, int, struct order *))fun; } else { - log_error("unknown function type '%s' for item '%s'\n", (const char *)propValue, rtype->_name[0]); + log_error("unknown function type '%s' for item '%s'\n", (const char *)propValue, rtype->_name); } xmlFree(propValue); } @@ -997,7 +997,7 @@ static int parse_resources(xmlDocPtr doc) parse_function(node, &fun, &propValue); if (fun == NULL) { - log_error("unknown function name '%s' for resource %s\n", (const char *)propValue, rtype->_name[0]); + log_error("unknown function name '%s' for resource %s\n", (const char *)propValue, rtype->_name); xmlFree(propValue); continue; } @@ -1010,7 +1010,7 @@ static int parse_resources(xmlDocPtr doc) } else if (strcmp((const char *)propValue, "name") == 0) { rtype->name = (rtype_name) fun; } else { - log_error("unknown function type '%s' for resource %s\n", (const char *)propValue, rtype->_name[0]); + log_error("unknown function type '%s' for resource %s\n", (const char *)propValue, rtype->_name); } xmlFree(propValue); } @@ -1077,7 +1077,7 @@ static int parse_resources(xmlDocPtr doc) xmlFree(propBldg); } } else { - log_error("unknown type '%s' for resourcelimit-modifier '%s'\n", (const char *)propValue, rtype->_name[0]); + log_error("unknown type '%s' for resourcelimit-modifier '%s'\n", (const char *)propValue, rtype->_name); } xmlFree(propValue); } @@ -1112,7 +1112,7 @@ static int parse_resources(xmlDocPtr doc) assert(propValue != NULL); fun = get_function((const char *)propValue); if (fun == NULL) { - log_error("unknown limit '%s' for resource %s\n", (const char *)propValue, rtype->_name[0]); + log_error("unknown limit '%s' for resource %s\n", (const char *)propValue, rtype->_name); xmlFree(propValue); continue; } @@ -1125,7 +1125,7 @@ static int parse_resources(xmlDocPtr doc) } else if (strcmp((const char *)propValue, "limit") == 0) { rdata->limit = (rlimit_limit) fun; } else { - log_error("unknown limit '%s' for resource %s\n", (const char *)propValue, rtype->_name[0]); + log_error("unknown limit '%s' for resource %s\n", (const char *)propValue, rtype->_name); } xmlFree(propValue); } diff --git a/src/triggers/giveitem.c b/src/triggers/giveitem.c index edaae77c5..3ed044617 100644 --- a/src/triggers/giveitem.c +++ b/src/triggers/giveitem.c @@ -78,7 +78,7 @@ static void giveitem_write(const trigger * t, struct storage *store) giveitem_data *td = (giveitem_data *) t->data.v; write_unit_reference(td->u, store); WRITE_INT(store, td->number); - WRITE_TOK(store, td->itype->rtype->_name[0]); + WRITE_TOK(store, td->itype->rtype->_name); } static int giveitem_read(trigger * t, struct storage *store)