Merge branch 'master' of gitorious.org:eressea/server

This commit is contained in:
Enno Rehling 2012-05-22 22:01:57 -07:00
commit 22ccb5cf95
13 changed files with 152 additions and 121 deletions

View File

@ -319,8 +319,9 @@ static critbit_tree * special_resources(void)
char buffer[32]; char buffer[32];
int i; int i;
for (i=0;special[i];++i) { for (i=0;special[i];++i) {
cb_new_kv(special[i], &i, sizeof(int), buffer); size_t len = strlen(special[i]);
cb_insert(&cb, buffer, strlen(special[i])+1+sizeof(int)); len = cb_new_kv(special[i], len, &i, sizeof(int), buffer);
cb_insert(&cb, buffer, len);
} }
} }
return &cb; return &cb;

View File

@ -1989,11 +1989,12 @@ static void init_translations(const struct locale *lang, int ut, const char * (*
char * str = transliterate(buffer, sizeof(buffer)-sizeof(int), key); char * str = transliterate(buffer, sizeof(buffer)-sizeof(int), key);
if (str) { if (str) {
critbit_tree * cb = (critbit_tree *)*tokens; critbit_tree * cb = (critbit_tree *)*tokens;
size_t len = strlen(str);
if (!cb) { if (!cb) {
*tokens = cb = (critbit_tree *)calloc(1, sizeof(critbit_tree *)); *tokens = cb = (critbit_tree *)calloc(1, sizeof(critbit_tree *));
} }
cb_new_kv(str, &i, sizeof(int), buffer); len = cb_new_kv(str, len, &i, sizeof(int), buffer);
cb_insert(cb, buffer, strlen(str)+1+sizeof(int)); cb_insert(cb, buffer, len);
} else { } else {
log_error("could not transliterate '%s'\n", key); log_error("could not transliterate '%s'\n", key);
} }

View File

@ -178,8 +178,8 @@ void it_register(item_type * itype)
size_t len = strlen(name); size_t len = strlen(name);
assert(len<sizeof(buffer)-sizeof(itype)); assert(len<sizeof(buffer)-sizeof(itype));
cb_new_kv(name, &itype, sizeof(itype), buffer); len = cb_new_kv(name, len, &itype, sizeof(itype), buffer);
if (cb_insert(&cb_items, buffer, len+1+sizeof(itype))) { if (cb_insert(&cb_items, buffer, len)) {
rt_register(itype->rtype); rt_register(itype->rtype);
} }
} }
@ -299,8 +299,8 @@ void rt_register(resource_type * rtype)
size_t len = strlen(name); size_t len = strlen(name);
assert(len<sizeof(buffer)-sizeof(rtype)); assert(len<sizeof(buffer)-sizeof(rtype));
cb_new_kv(name, &rtype, sizeof(rtype), buffer); len = cb_new_kv(name, len, &rtype, sizeof(rtype), buffer);
cb_insert(&cb_resources, buffer, len+1+sizeof(rtype)); cb_insert(&cb_resources, buffer, len);
} }
const resource_type *item2resource(const item_type * itype) const resource_type *item2resource(const item_type * itype)
@ -1120,8 +1120,8 @@ static int add_itemname_cb(const void * match, const void * key, size_t keylen,
if (name && transliterate(buffer, sizeof(buffer), name)) { if (name && transliterate(buffer, sizeof(buffer), name)) {
size_t len = strlen(buffer); size_t len = strlen(buffer);
assert(len+sizeof(itype)<sizeof(buffer)); assert(len+sizeof(itype)<sizeof(buffer));
cb_new_kv(buffer, &itype, sizeof(itype), buffer); len = cb_new_kv(buffer, len, &itype, sizeof(itype), buffer);
cb_insert(cb, buffer, len+1+sizeof(itype)); cb_insert(cb, buffer, len);
} }
} }
return 0; return 0;

View File

@ -24,47 +24,62 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include "magic.h" #include "magic.h"
#include "unit.h" #include "unit.h"
/* libc includes */
#include <assert.h>
#include <string.h>
/* util includes */ /* util includes */
#include <util/critbit.h>
#include <util/goodies.h> #include <util/goodies.h>
#include <util/language.h> #include <util/language.h>
#include <util/log.h> #include <util/log.h>
#include <util/umlaut.h> #include <util/umlaut.h>
#include <util/quicklist.h> #include <util/quicklist.h>
quicklist *spells = NULL; /* libc includes */
#include <assert.h>
#include <string.h>
spell * create_spell(const char * name) static critbit_tree cb_spells;
{ quicklist * spells;
spell * sp = (spell *) calloc(1, sizeof(spell));
sp->sname = strdup(name); void free_spells(void) {
return sp; cb_clear(&cb_spells);
ql_free(spells);
spells = 0;
} }
void register_spell(spell * sp) spell * create_spell(const char * name, unsigned int id)
{ {
if (sp->id == 0) { spell * sp;
sp->id = hashstring(sp->sname); char buffer[64];
size_t len = strlen(name);
assert(len+sizeof(sp)<sizeof(buffer));
if (find_spell(name)) {
log_error("create_spell: duplicate name '%s'\n", name);
return 0;
} }
sp = (spell *) calloc(1, sizeof(spell));
len = cb_new_kv(name, len, &sp, sizeof(sp), buffer);
if (cb_insert(&cb_spells, buffer, len)) {
sp->id = id ? id : hashstring(name);
sp->sname = strdup(name);
add_spell(&spells, sp); add_spell(&spells, sp);
return sp;
}
free(sp);
return 0;
} }
spell *find_spell(const char *name) spell *find_spell(const char *name)
{ {
quicklist *ql = spells; const char * match;
int qi; spell * sp = 0;
for (qi = 0; ql; ql_advance(&ql, &qi, 1)) { match = cb_find_str(&cb_spells, name);
spell *sp = (spell *) ql_get(ql, qi); if (match) {
if (strcmp(name, sp->sname) == 0) { cb_get_kv(match, &sp, sizeof(sp));
return sp; } else {
}
}
log_warning("find_spell: could not find spell '%s'\n", name); log_warning("find_spell: could not find spell '%s'\n", name);
return 0; }
return sp;
} }
/* ------------------------------------------------------------- */ /* ------------------------------------------------------------- */

View File

@ -22,16 +22,6 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
extern "C" { extern "C" {
#endif #endif
struct fighter;
struct spell;
struct border_type;
struct attrib_type;
struct curse_type;
struct castorder;
struct curse;
struct region;
struct unit;
/* Prototypen */ /* Prototypen */
int use_item_power(struct region *r, struct unit *u); int use_item_power(struct region *r, struct unit *u);
@ -44,15 +34,14 @@ extern "C" {
extern struct attrib_type at_unitdissolve; extern struct attrib_type at_unitdissolve;
extern struct attrib_type at_wdwpyramid; extern struct attrib_type at_wdwpyramid;
extern struct quicklist *spells; extern struct spell * create_spell(const char * name, unsigned int id);
extern struct spell * find_spell(const char *name);
extern struct spell * create_spell(const char * name); extern struct spell * find_spellbyid(unsigned int i);
extern void register_spell(struct spell *sp); extern struct spell * get_spellfromtoken(struct sc_mage *mage, const char *s,
extern struct spell *find_spell(const char *name);
extern struct spell *find_spellbyid(unsigned int i);
extern struct spell *get_spellfromtoken(struct sc_mage *mage, const char *s,
const struct locale *lang); const struct locale *lang);
extern void free_spells(void);
extern struct quicklist * spells;
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -1,4 +1,7 @@
#include <platform.h>
#include <util/quicklist.h> #include <util/quicklist.h>
#include <kernel/types.h>
#include <kernel/spell.h> #include <kernel/spell.h>
#include <kernel/magic.h> #include <kernel/magic.h>
@ -7,23 +10,48 @@
#include <stdlib.h> #include <stdlib.h>
static void test_register_spell(CuTest * tc) static void test_create_spell(CuTest * tc)
{ {
spell * sp; spell * sp;
test_cleanup();
CuAssertPtrEquals(tc, 0, spells);
CuAssertPtrEquals(tc, 0, find_spell("testspell")); CuAssertPtrEquals(tc, 0, find_spell("testspell"));
CuAssertPtrEquals(tc, spells, 0); sp = create_spell("testspell", 0);
sp = create_spell("testspell");
sp->magietyp = 5;
register_spell(sp);
CuAssertIntEquals(tc, 1, ql_length(spells));
CuAssertPtrEquals(tc, sp, find_spell("testspell")); CuAssertPtrEquals(tc, sp, find_spell("testspell"));
CuAssertPtrNotNull(tc, spells);
}
static void test_create_duplicate_spell(CuTest * tc)
{
spell *sp;
test_cleanup();
CuAssertPtrEquals(tc, 0, find_spell("testspell"));
sp = create_spell("testspell", 0);
CuAssertPtrEquals(tc, 0, create_spell("testspell", 0));
CuAssertPtrEquals(tc, sp, find_spell("testspell"));
}
static void test_create_spell_with_id(CuTest * tc)
{
spell *sp;
test_cleanup();
CuAssertPtrEquals(tc, 0, find_spellbyid(42));
sp = create_spell("testspell", 42);
CuAssertPtrEquals(tc, sp, find_spellbyid(42));
CuAssertPtrEquals(tc, 0, create_spell("testspell", 47));
CuAssertPtrEquals(tc, 0, find_spellbyid(47));
} }
CuSuite *get_spell_suite(void) CuSuite *get_spell_suite(void)
{ {
CuSuite *suite = CuSuiteNew(); CuSuite *suite = CuSuiteNew();
SUITE_ADD_TEST(suite, test_register_spell); SUITE_ADD_TEST(suite, test_create_spell);
SUITE_ADD_TEST(suite, test_create_duplicate_spell);
SUITE_ADD_TEST(suite, test_create_spell_with_id);
return suite; return suite;
} }

View File

@ -1481,13 +1481,14 @@ static int parse_spells(xmlDocPtr doc)
int k; int k;
spell_component *component; spell_component *component;
spell *sp; spell *sp;
int valid = 1; unsigned int index;
static int modes[] = { 0, PRECOMBATSPELL, COMBATSPELL, POSTCOMBATSPELL }; static int modes[] = { 0, PRECOMBATSPELL, COMBATSPELL, POSTCOMBATSPELL };
/* spellname */ /* spellname */
index = xml_ivalue(node, "index", 0);
propValue = xmlGetProp(node, BAD_CAST "name"); propValue = xmlGetProp(node, BAD_CAST "name");
assert(propValue != NULL); assert(propValue != NULL);
sp = create_spell((const char *)propValue); sp = create_spell((const char *)propValue, index);
xmlFree(propValue); xmlFree(propValue);
propValue = xmlGetProp(node, BAD_CAST "parameters"); propValue = xmlGetProp(node, BAD_CAST "parameters");
@ -1513,7 +1514,6 @@ static int parse_spells(xmlDocPtr doc)
xmlFree(propValue); xmlFree(propValue);
/* level, rank and flags */ /* level, rank and flags */
sp->id = xml_ivalue(node, "index", 0);
sp->level = xml_ivalue(node, "level", -1); sp->level = xml_ivalue(node, "level", -1);
sp->rank = (char)xml_ivalue(node, "rank", -1); sp->rank = (char)xml_ivalue(node, "rank", -1);
if (xml_bvalue(node, "los", false)) if (xml_bvalue(node, "los", false))
@ -1544,7 +1544,6 @@ static int parse_spells(xmlDocPtr doc)
cast = get_function(sp->sname); cast = get_function(sp->sname);
if (!cast) { if (!cast) {
log_error("no spell cast function registered for '%s'\n", sp->sname); log_error("no spell cast function registered for '%s'\n", sp->sname);
valid = 0;
} }
strlcpy(zText+7, sp->sname, sizeof(zText)-7); strlcpy(zText+7, sp->sname, sizeof(zText)-7);
fumble = get_function(zText); fumble = get_function(zText);
@ -1558,10 +1557,8 @@ static int parse_spells(xmlDocPtr doc)
if (strcmp((const char *)propValue, "cast") == 0) { if (strcmp((const char *)propValue, "cast") == 0) {
if (fun) { if (fun) {
cast = fun; cast = fun;
valid = 1;
} else { } else {
log_error("unknown function name '%s' for spell '%s'\n", (const char *)propValue, sp->sname); log_error("unknown function name '%s' for spell '%s'\n", (const char *)propValue, sp->sname);
valid = 0;
} }
} else if (fun && strcmp((const char *)propValue, "fumble") == 0) { } else if (fun && strcmp((const char *)propValue, "fumble") == 0) {
fumble = fun; fumble = fun;
@ -1576,7 +1573,6 @@ static int parse_spells(xmlDocPtr doc)
xmlXPathFreeObject(result); xmlXPathFreeObject(result);
} }
if (valid) {
/* reading eressea/spells/spell/resource */ /* reading eressea/spells/spell/resource */
xpath->node = node; xpath->node = node;
result = xmlXPathEvalExpression(BAD_CAST "resource", xpath); result = xmlXPathEvalExpression(BAD_CAST "resource", xpath);
@ -1615,11 +1611,6 @@ static int parse_spells(xmlDocPtr doc)
} }
xmlXPathFreeObject(result); xmlXPathFreeObject(result);
} }
if (valid) {
register_spell(sp);
}
}
} }
xmlXPathFreeObject(spells); xmlXPathFreeObject(spells);

View File

@ -109,6 +109,7 @@ void test_cleanup(void)
global.functions.wage = NULL; global.functions.wage = NULL;
default_locale = 0; default_locale = 0;
locales = 0; /* TODO: this is evil and leaky */ locales = 0; /* TODO: this is evil and leaky */
free_spells(); /* TODO: this is just as bad! */
free_gamedata(); free_gamedata();
} }

View File

@ -46,6 +46,7 @@ void * make_external_node(const void * key, size_t keylen)
ptrdiff_t numvalue = (char *)data - (char*)0; ptrdiff_t numvalue = (char *)data - (char*)0;
assert((numvalue&1)==0); assert((numvalue&1)==0);
#endif #endif
assert(keylen);
memcpy(data, &keylen, sizeof(size_t)); memcpy(data, &keylen, sizeof(size_t));
memcpy(data+sizeof(size_t), key, keylen); memcpy(data+sizeof(size_t), key, keylen);
return (void*)(data+1); return (void*)(data+1);
@ -286,7 +287,7 @@ const void * cb_find(critbit_tree * cb, const void * key, size_t keylen)
ptr = node->child[branch]; ptr = node->child[branch];
} }
from_external_node(ptr, &str, &len); from_external_node(ptr, &str, &len);
if (len==keylen && memcmp(key, str, keylen)==0) { if (len>=keylen && memcmp(key, str, keylen)==0) {
return str; return str;
} }
return 0; return 0;
@ -330,14 +331,15 @@ int cb_erase(critbit_tree * cb, const void * key, size_t keylen)
} }
} }
size_t cb_new_kv(const char *key, void * value, size_t len, void * dst) size_t cb_new_kv(const char *key, size_t keylen, void * value, size_t len, void * out)
{ {
size_t keylen = strlen(key)+1; char * dst = (char*)out;
if (dst!=key) { if (dst!=key) {
memcpy(dst, key, keylen); memcpy(dst, key, keylen);
} }
memcpy((char*)dst+keylen, value, len); dst[keylen] = 0;
return len+keylen; memcpy(dst+keylen+1, value, len);
return len+keylen+1;
} }
void cb_get_kv(const void *kv, void * value, size_t len) 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) \ #define cb_find_prefix_str(cb, key, results, numresults, offset) \
cb_find_prefix(cb, (void *)key, strlen(key), results, numresults, offset) cb_find_prefix(cb, (void *)key, strlen(key), results, numresults, offset)
size_t cb_new_kv(const char *key, void * value, size_t len, void * dst); size_t cb_new_kv(const char *key, size_t keylen, void * value, size_t len, void * out);
void cb_get_kv(const void *kv, void * value, size_t len); void cb_get_kv(const void *kv, void * value, size_t len);
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -45,6 +45,6 @@ void register_function(pf_generic fun, const char *name)
size_t len = strlen(name); size_t len = strlen(name);
assert(len<sizeof(buffer)-sizeof(fun)); assert(len<sizeof(buffer)-sizeof(fun));
cb_new_kv(name, &fun, sizeof(fun), buffer); len = cb_new_kv(name, len, &fun, sizeof(fun), buffer);
cb_insert(&cb_functions, buffer, len+1+sizeof(fun)); cb_insert(&cb_functions, buffer, len);
} }

View File

@ -19,9 +19,12 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include <string.h> #include <string.h>
#include <errno.h> #include <errno.h>
#define QL_MAXSIZE 14 /* total struct is 64 bytes */ #define QL_MAXSIZE 14 /* max. number of elements unrolled into one node */
#define QL_LIMIT 7 #define QL_LIMIT 7 /* this many or fewer number in a node => attempt merge */
/* The total size of this struct is 64 bytes on a 32-bit system with
* normal alignment. YMMV, so on a 64-bit system, twiddle the
* constants above */
struct quicklist { struct quicklist {
struct quicklist *next; struct quicklist *next;
int num_elements; int num_elements;
@ -170,11 +173,11 @@ int ql_advance(struct quicklist **iterator, int *index, int stride)
void ql_free(struct quicklist *ql) void ql_free(struct quicklist *ql)
{ {
if (!ql) while (ql) {
return; quicklist * qn = ql;
if (ql->next) ql = ql->next;
ql_free(ql->next); free(qn);
free(ql); }
} }
int ql_set_remove(struct quicklist **qlp, void *data) int ql_set_remove(struct quicklist **qlp, void *data)

View File

@ -162,8 +162,8 @@ void add_function(const char *symbol, evalfun parse)
size_t len = strlen(symbol); size_t len = strlen(symbol);
assert(len+1+sizeof(parse)<=sizeof(buffer)); assert(len+1+sizeof(parse)<=sizeof(buffer));
cb_new_kv(symbol, &parse, sizeof(parse), buffer); len = cb_new_kv(symbol, len, &parse, sizeof(parse), buffer);
cb_insert(&functions, buffer, len+1+sizeof(parse)); cb_insert(&functions, buffer, len);
} }
static evalfun find_function(const char *symbol) static evalfun find_function(const char *symbol)