Merge pull request #559 from ennorehling/develop

fix syntaxtree memory leak
This commit is contained in:
Enno Rehling 2016-09-07 17:02:45 +01:00 committed by GitHub
commit 149d1a43a6
4 changed files with 25 additions and 26 deletions

View file

@ -288,14 +288,12 @@ static void perform_join(void)
static syntaxtree * build_syntax(void) { static syntaxtree * build_syntax(void) {
syntaxtree *slang, *stree = stree_create(); syntaxtree *slang, *stree = stree_create();
for (slang = stree; slang; slang = slang->next) { for (slang = stree; slang; slang = slang->next) {
struct tnode *leaf = 0; stree_add(slang, LOC(slang->lang, alliance_kwd[ALLIANCE_KICK]), &cmd_kick);
add_command(&leaf, NULL, LOC(slang->lang, alliance_kwd[ALLIANCE_KICK]), &cmd_kick); stree_add(slang, LOC(slang->lang, alliance_kwd[ALLIANCE_LEAVE]), &cmd_leave);
add_command(&leaf, NULL, LOC(slang->lang, alliance_kwd[ALLIANCE_LEAVE]), &cmd_leave); stree_add(slang, LOC(slang->lang, alliance_kwd[ALLIANCE_TRANSFER]), &cmd_transfer);
add_command(&leaf, NULL, LOC(slang->lang, alliance_kwd[ALLIANCE_TRANSFER]), &cmd_transfer); stree_add(slang, LOC(slang->lang, alliance_kwd[ALLIANCE_NEW]), &cmd_new);
add_command(&leaf, NULL, LOC(slang->lang, alliance_kwd[ALLIANCE_NEW]), &cmd_new); stree_add(slang, LOC(slang->lang, alliance_kwd[ALLIANCE_INVITE]), &cmd_invite);
add_command(&leaf, NULL, LOC(slang->lang, alliance_kwd[ALLIANCE_INVITE]), &cmd_invite); stree_add(slang, LOC(slang->lang, alliance_kwd[ALLIANCE_JOIN]), &cmd_join);
add_command(&leaf, NULL, LOC(slang->lang, alliance_kwd[ALLIANCE_JOIN]), &cmd_join);
slang->root = leaf;
} }
return stree; return stree;
} }

View file

@ -30,7 +30,7 @@
typedef struct command { typedef struct command {
parser fun; parser fun;
void *nodes; struct command *next;
} command; } command;
void *stree_find(const syntaxtree * stree, const struct locale *lang) void *stree_find(const syntaxtree * stree, const struct locale *lang)
@ -44,6 +44,11 @@ void *stree_find(const syntaxtree * stree, const struct locale *lang)
} }
void stree_free(syntaxtree *stree) { void stree_free(syntaxtree *stree) {
while (stree->cmds) {
command *next = stree->cmds->next;
free(stree->cmds);
stree->cmds = next;
}
while (stree) { while (stree) {
syntaxtree *snext = stree->next; syntaxtree *snext = stree->next;
freetokens(stree->root); freetokens(stree->root);
@ -61,24 +66,23 @@ syntaxtree *stree_create(void)
stree->lang = lang; stree->lang = lang;
stree->next = sroot; stree->next = sroot;
stree->root = 0; stree->root = 0;
stree->cmds = 0;
sroot = stree; sroot = stree;
lang = nextlocale(lang); lang = nextlocale(lang);
} }
return sroot; return sroot;
} }
void void stree_add(struct syntaxtree *stree, const char *str, parser fun) {
add_command(struct tnode **keys, void *tnext,
const char *str, parser fun)
{
command *cmd = (command *)malloc(sizeof(command)); command *cmd = (command *)malloc(sizeof(command));
variant var; variant var;
assert(str); assert(str);
cmd->fun = fun; cmd->fun = fun;
cmd->nodes = tnext;
var.v = cmd; var.v = cmd;
addtoken(keys, str, var); cmd->next = stree->cmds;
stree->cmds = cmd;
addtoken(&stree->root, str, var);
} }
static int do_command_i(const struct tnode *keys, struct unit *u, struct order *ord) static int do_command_i(const struct tnode *keys, struct unit *u, struct order *ord)
@ -90,12 +94,8 @@ static int do_command_i(const struct tnode *keys, struct unit *u, struct order *
c = gettoken(token, sizeof(token)); c = gettoken(token, sizeof(token));
if (findtoken(keys, c, &var) == E_TOK_SUCCESS) { if (findtoken(keys, c, &var) == E_TOK_SUCCESS) {
command *cmd = (command *)var.v; command *cmd = (command *)var.v;
if (cmd->nodes && *c) { if (cmd->fun) {
assert(!cmd->fun); cmd->fun(0, u, ord);
return do_command_i(cmd->nodes, u, ord);
}
else if (cmd->fun) {
cmd->fun(cmd->nodes, u, ord);
return E_TOK_SUCCESS; return E_TOK_SUCCESS;
} }
} }

View file

@ -20,19 +20,20 @@ extern "C" {
struct order; struct order;
struct unit; struct unit;
struct tnode; struct tnode;
struct command;
typedef struct syntaxtree { typedef struct syntaxtree {
const struct locale *lang; const struct locale *lang;
struct tnode *root; struct tnode *root;
struct syntaxtree *next; struct syntaxtree *next;
struct command *cmds;
} syntaxtree; } syntaxtree;
typedef void(*parser) (const void *nodes, struct unit * u, struct order *); typedef void(*parser) (const void *nodes, struct unit * u, struct order *);
void add_command(struct tnode **troot, void *tnext,
const char *str, parser fun);
void do_command(const struct tnode *troot, struct unit *u, struct order *); void do_command(const struct tnode *troot, struct unit *u, struct order *);
struct syntaxtree *stree_create(void); struct syntaxtree *stree_create(void);
void stree_add(struct syntaxtree *, const char *str, parser fun);
void stree_free(struct syntaxtree *); void stree_free(struct syntaxtree *);
void *stree_find(const struct syntaxtree *stree, void *stree_find(const struct syntaxtree *stree,
const struct locale *lang); const struct locale *lang);

View file

@ -37,8 +37,8 @@ static void test_command(CuTest * tc) {
CuAssertPtrEquals(tc, loc, (struct locale *)st->lang); CuAssertPtrEquals(tc, loc, (struct locale *)st->lang);
CuAssertPtrEquals(tc, 0, st->root); CuAssertPtrEquals(tc, 0, st->root);
CuAssertPtrEquals(tc, 0, st->next); CuAssertPtrEquals(tc, 0, st->next);
add_command(&st->root, 0, "two", parser_two); stree_add(st, "two", parser_two);
add_command(&st->root, 0, "six", parser_six); stree_add(st, "six", parser_six);
CuAssertPtrNotNull(tc, st->root); CuAssertPtrNotNull(tc, st->root);
CuAssertPtrEquals(tc, st->root, stree_find(st, loc)); CuAssertPtrEquals(tc, st->root, stree_find(st, loc));
u = test_create_unit(test_create_faction(0), test_create_region(0, 0, 0)); u = test_create_unit(test_create_faction(0), test_create_region(0, 0, 0));
@ -54,4 +54,4 @@ CuSuite *get_command_suite(void)
CuSuite *suite = CuSuiteNew(); CuSuite *suite = CuSuiteNew();
SUITE_ADD_TEST(suite, test_command); SUITE_ADD_TEST(suite, test_command);
return suite; return suite;
} }