forked from github/server
finditemtype works as tested.
starting to think about removing default_locale in lieu of a hierarchical system.
This commit is contained in:
parent
5ab1b2881a
commit
1e9c10fbe2
7 changed files with 63 additions and 49 deletions
|
@ -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
|
||||
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 {
|
||||
|
|
Loading…
Reference in a new issue