forked from github/server
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:
parent
df4cc70abf
commit
05b7837070
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Reference in New Issue