fix parser to keep a reference to the order it is parsing.

make push/popstate not crash. pass unit tests.
This commit is contained in:
Enno Rehling 2017-11-10 07:56:56 +01:00
parent df4cc70abf
commit 05b7837070
6 changed files with 32 additions and 6 deletions

View File

@ -523,8 +523,13 @@ keyword_t init_order(const struct order *ord, const struct locale *lang)
init_tokens_str(skillname(sk, lang));
}
else {
const char *str;
parser_od = odata_load(ord->id);
init_tokens_str(OD_STRING(parser_od));
if (parser_od) {
odata_addref(parser_od);
}
str = OD_STRING(parser_od);
init_tokens_ex(str, parser_od, odata_release);
}
return kwd;
}

View File

@ -31,6 +31,11 @@ void odata_release(order_data * od)
}
}
void odata_addref(order_data *od)
{
++od->_refcount;
}
order_data *odata_load(int id)
{
return db_load_order(id);

View File

@ -14,6 +14,7 @@ extern "C" {
void odata_create(order_data **pdata, size_t len, const char *str);
void odata_release(order_data * od);
void odata_addref(order_data *od);
order_data *odata_load(int id);
int odata_save(order_data *od);

View File

@ -371,7 +371,7 @@ int teach_cmd(unit * teacher, struct order *ord)
token = getstrtoken();
/* Beginne die Fehlermeldung */
if (token && isparam(token, teacher->faction->locale, P_TEMP)) {
if (isparam(token, teacher->faction->locale, P_TEMP)) {
token = getstrtoken();
sprintf(tbuf, "%s %s", LOC(teacher->faction->locale,
parameters[P_TEMP]), token);

View File

@ -16,6 +16,8 @@
typedef struct parser_state {
const char *current_token;
struct parser_state *next;
void *data;
void(*dtor)(void *);
} parser_state;
static parser_state *states;
@ -50,17 +52,26 @@ static int eatwhitespace_c(const char **str_p)
return ret;
}
void init_tokens_str(const char *initstr)
void init_tokens_ex(const char *initstr, void *data, void (*dtor)(void *))
{
if (states == NULL) {
states = malloc(sizeof(parser_state));
states = calloc(1, sizeof(parser_state));
}
else if (states->dtor) {
states->dtor(states->data);
}
states->dtor = dtor;
states->data = data;
states->current_token = initstr;
}
void init_tokens_str(const char *initstr) {
init_tokens_ex(initstr, NULL, NULL);
}
void parser_pushstate(void)
{
parser_state *new_state = malloc(sizeof(parser_state));
parser_state *new_state = calloc(1, sizeof(parser_state));
new_state->current_token = NULL;
new_state->next = states;
states = new_state;
@ -69,6 +80,9 @@ void parser_pushstate(void)
void parser_popstate(void)
{
parser_state *new_state = states->next;
if (states->dtor) {
states->dtor(states->data);
}
free(states);
states = new_state;
}

View File

@ -18,6 +18,7 @@
extern "C" {
#endif
void init_tokens_ex(const char *initstr, void *data, void(*dtor)(void *));
void init_tokens_str(const char *initstr); /* initialize token parsing */
void skip_token(void);
const char *parse_token_depr(const char **str);