forked from github/server
Merge branch 'master' of gitorious.org:eressea/server
This commit is contained in:
commit
22ccb5cf95
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------- */
|
/* ------------------------------------------------------------- */
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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)
|
||||||
|
|
Loading…
Reference in New Issue