finditemtype works as tested.

starting to think about removing default_locale in lieu of a hierarchical system.
This commit is contained in:
Enno Rehling 2012-05-21 13:18:05 -07:00
parent 5ab1b2881a
commit 1e9c10fbe2
7 changed files with 63 additions and 49 deletions

View file

@ -56,6 +56,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include <stdlib.h>
#include <string.h>
static critbit_tree inames[MAXLOCALES];
static critbit_tree cb_resources;
static critbit_tree cb_items;
luxury_type *luxurytypes;
@ -1100,46 +1101,49 @@ attrib_type at_showitem = {
"showitem"
};
/* static local_names *inames; */
static int add_itemname_cb(const void * match, const void * key, size_t keylen, void *data)
{
struct locale * lang = (struct locale *)data;
int i = locale_index(lang);
critbit_tree * cb = inames+i;
item_type *itype;
cb_get_kv(match, &itype, sizeof(itype));
for (i = 0; i!=2;++i) {
char buffer[64];
const char * name = locale_string(lang, itype->rtype->_name[i]);
if (name && transliterate(buffer, sizeof(buffer), name)) {
size_t len = strlen(buffer);
assert(len+sizeof(itype)<sizeof(buffer));
cb_new_kv(buffer, &itype, sizeof(itype), buffer);
cb_insert(cb, buffer, len+1+sizeof(itype));
}
}
return 0;
}
const item_type *finditemtype(const char *name, const struct locale *lang)
{
local_names *inames = 0;
const void * matches[CB_BATCHSIZE];
local_names *in = inames;
variant token;
int i = locale_index(lang);
critbit_tree * cb = inames+i;
char buffer[64];
while (in) {
if (in->lang == lang)
break;
in = in->next;
if (transliterate(buffer, sizeof(buffer), name)) {
const void * match;
if (!cb->root) {
/* first-time initialization of item names for this locale */
cb_foreach(&cb_items, "", 0, add_itemname_cb, (void *)lang);
}
if (cb_find_prefix(cb, buffer, strlen(buffer), &match, 1, 0)) {
const item_type * itype = 0;
cb_get_kv(match, (void*)&itype, sizeof(itype));
return itype;
}
} else {
log_debug("finditemtype: transliterate failed for '%s'\n", name);
}
if (!in) {
int m, offset = 0;
in = (local_names *)calloc(1, sizeof(local_names));
in->next = inames;
in->lang = lang;
do {
m = cb_find_prefix(&cb_items, "", 0, matches, CB_BATCHSIZE, offset);
if (m) {
int i;
offset += m;
for (i=0;i!=m;++i) {
item_type *itype;
cb_get_kv(matches[i], &itype, sizeof(itype));
token.v = (void *)itype;
addtoken(&in->names, locale_string(lang, itype->rtype->_name[0]), token);
addtoken(&in->names, locale_string(lang, itype->rtype->_name[1]), token);
}
}
} while (m==CB_BATCHSIZE);
inames = in;
}
if (findtoken(in->names, name, &token) == E_TOK_NOMATCH) {
return 0;
}
return (const item_type *)token.v;
return 0;
}
static void init_resourcelimit(attrib * a)
@ -1197,6 +1201,8 @@ int free_rtype_cb(const void * match, const void * key, size_t keylen, void *cbd
void test_clear_resources(void)
{
int i;
memset((void *)olditemtype, 0, sizeof(olditemtype));
memset((void *)oldresourcetype, 0, sizeof(oldresourcetype));
memset((void *)oldpotiontype, 0, sizeof(oldpotiontype));
@ -1209,7 +1215,9 @@ void test_clear_resources(void)
r_hp = r_silver = r_aura = r_permaura = r_unit = 0;
i_silver = 0;
/* inames = 0; TODO: this is a terrible hack, the whole inames global state must die */
for (i=0; i!=MAXLOCALES; ++i) {
cb_clear(inames+i);
}
}
#endif

View file

@ -31,28 +31,34 @@ void test_resource_type(CuTest * tc)
void test_finditemtype(CuTest * tc)
{
struct item_type *itype;
const char *names[4] = { "herp" , "herp_p", "derp", "derp_p" };
const item_type *itype, *iresult;
const char *names[] = { "herp" , "herp_p" };
struct locale * lang = make_locale("de");
test_cleanup();
locale_setstring(lang, names[0], "Foo");
itype = test_create_itemtype(names);
CuAssertPtrNotNull(tc, itype);
locale_setstring(lang, names[0], "Foo");
locale_setstring(lang, names[1], "Foos");
iresult = finditemtype("Foo", lang);
CuAssertPtrEquals(tc, (void*)itype, (void*)iresult);
}
#if 0
locale_setstring(lang, names[1], "Foos");
CuAssertPtrEquals(tc, (void*)itype, (void*)finditemtype("Foo", lang));
CuAssertPtrEquals(tc, (void*)itype, (void*)finditemtype("Foos", lang));
test_cleanup();
itype = test_create_itemtype(names+2);
CuAssertPtrNotNull(tc, itype);
locale_setstring(lang, names[2], "Bar");
locale_setstring(lang, names[3], "Bars");
CuAssertPtrEquals(tc, (void*)0, (void*)finditemtype("Foo", lang));
CuAssertPtrEquals(tc, (void*)itype, (void*)finditemtype("Bar", lang));
CuAssertPtrEquals(tc, (void*)itype, (void*)finditemtype("Bars", lang));
}
#endif
CuSuite *get_item_suite(void)
{

View file

@ -330,13 +330,14 @@ int cb_erase(critbit_tree * cb, const void * key, size_t keylen)
}
}
void cb_new_kv(const char *key, void * value, size_t len, void * dst)
size_t cb_new_kv(const char *key, void * value, size_t len, void * dst)
{
size_t keylen = strlen(key)+1;
if (dst!=key) {
memcpy(dst, key, keylen);
}
memcpy((char*)dst+keylen, value, len);
return len+keylen;
}
void cb_get_kv(const void *kv, void * value, size_t len)

View file

@ -47,7 +47,7 @@ void cb_clear(critbit_tree * cb);
#define cb_find_prefix_str(cb, key, results, numresults, offset) \
cb_find_prefix(cb, (void *)key, strlen(key), results, numresults, offset)
void cb_new_kv(const char *key, void * value, size_t len, void * dst);
size_t cb_new_kv(const char *key, void * value, size_t len, void * dst);
void cb_get_kv(const void *kv, void * value, size_t len);
#ifdef __cplusplus

View file

@ -127,7 +127,7 @@ const char *locale_getstring(const locale * lang, const char *key)
const char *locale_string(const locale * lang, const char *key)
{
assert(lang != 0);
assert(lang);
if (key != NULL) {
unsigned int hkey = hashstring(key);
@ -136,8 +136,6 @@ const char *locale_string(const locale * lang, const char *key)
if (*key == 0)
return NULL;
if (lang == NULL)
return key;
find = lang->strings[id];
while (find) {
if (find->hashkey == hkey) {
@ -153,8 +151,8 @@ const char *locale_string(const locale * lang, const char *key)
}
if (!find) {
log_warning("missing translation for \"%s\" in locale %s\n", key, lang->name);
if (lang != default_locale) {
return locale_string(default_locale, key);
if (lang->fallback) {
return locale_string(lang->fallback, key);
}
return 0;
}

View file

@ -19,6 +19,7 @@ typedef struct locale {
unsigned int hashkey;
const char *name;
struct locale_str *strings[SMAXHASH];
struct locale *fallback;
} locale;
extern locale *default_locale;

View file

@ -125,7 +125,7 @@ void addtoken(void ** root, const char *str, variant id)
0, ""}
};
assert(root);
assert(root && str);
if (!*root) {
tk = *root = calloc(1, sizeof(tnode));
} else {