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)); init_tokens_str(skillname(sk, lang));
} }
else { else {
const char *str;
parser_od = odata_load(ord->id); 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; 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) order_data *odata_load(int id)
{ {
return db_load_order(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_create(order_data **pdata, size_t len, const char *str);
void odata_release(order_data * od); void odata_release(order_data * od);
void odata_addref(order_data *od);
order_data *odata_load(int id); order_data *odata_load(int id);
int odata_save(order_data *od); int odata_save(order_data *od);

View File

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

View File

@ -16,6 +16,8 @@
typedef struct parser_state { typedef struct parser_state {
const char *current_token; const char *current_token;
struct parser_state *next; struct parser_state *next;
void *data;
void(*dtor)(void *);
} parser_state; } parser_state;
static parser_state *states; static parser_state *states;
@ -50,17 +52,26 @@ static int eatwhitespace_c(const char **str_p)
return ret; return ret;
} }
void init_tokens_str(const char *initstr) void init_tokens_ex(const char *initstr, void *data, void (*dtor)(void *))
{ {
if (states == NULL) { 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; states->current_token = initstr;
} }
void init_tokens_str(const char *initstr) {
init_tokens_ex(initstr, NULL, NULL);
}
void parser_pushstate(void) 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->current_token = NULL;
new_state->next = states; new_state->next = states;
states = new_state; states = new_state;
@ -69,6 +80,9 @@ void parser_pushstate(void)
void parser_popstate(void) void parser_popstate(void)
{ {
parser_state *new_state = states->next; parser_state *new_state = states->next;
if (states->dtor) {
states->dtor(states->data);
}
free(states); free(states);
states = new_state; states = new_state;
} }
@ -254,7 +268,7 @@ unsigned int atoip(const char *s)
int n; int n;
assert(s); assert(s);
n = (s[0] >='0' && s[0]<='9'); n = (s[0] >= '0' && s[0] <= '9');
n = n ? atoi(s) : 0; n = n ? atoi(s) : 0;
if (n < 0) if (n < 0)

View File

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