start putting the new parser into the server.

This commit is contained in:
Enno Rehling 2018-09-29 21:19:24 +02:00
parent b03da543b6
commit 965c8ce990
3 changed files with 145 additions and 29 deletions

View File

@ -20,6 +20,32 @@
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
static void begin_orders(unit *u) {
if (u->flags & UFL_ORDERS) {
order **ordp;
/* alle wiederholbaren, langen befehle werden gesichert: */
u->flags |= UFL_ORDERS;
u->old_orders = u->orders;
ordp = &u->old_orders;
while (*ordp) {
order *ord = *ordp;
keyword_t kwd = getkeyword(ord);
if (!is_repeated(kwd)) {
*ordp = ord->next;
ord->next = NULL;
free_order(ord);
}
else {
ordp = &ord->next;
}
}
}
else {
free_orders(&u->orders);
}
u->orders = NULL;
}
static unit *unitorders(input *in, faction *f) static unit *unitorders(input *in, faction *f)
{ {
int i; int i;
@ -34,29 +60,7 @@ static unit *unitorders(input *in, faction *f)
if (u && u->faction == f) { if (u && u->faction == f) {
order **ordp; order **ordp;
if (u->flags & UFL_ORDERS) { begin_orders(u);
/* alle wiederholbaren, langen befehle werden gesichert: */
u->flags |= UFL_ORDERS;
u->old_orders = u->orders;
ordp = &u->old_orders;
while (*ordp) {
order *ord = *ordp;
keyword_t kwd = getkeyword(ord);
if (!is_repeated(kwd)) {
*ordp = ord->next;
ord->next = NULL;
free_order(ord);
}
else {
ordp = &ord->next;
}
}
}
else {
free_orders(&u->orders);
}
u->orders = 0;
ordp = &u->orders; ordp = &u->orders;
for (;;) { for (;;) {
@ -152,10 +156,6 @@ int read_orders(input *in)
int nfactions = 0; int nfactions = 0;
struct faction *f = NULL; struct faction *f = NULL;
const struct locale *lang = default_locale; const struct locale *lang = default_locale;
OP_Parser parser;
parser = OP_ParserCreate();
OP_ParserFree(parser);
/* TODO: recognize UTF8 BOM */ /* TODO: recognize UTF8 BOM */
b = in->getbuf(in->data); b = in->getbuf(in->data);
@ -231,8 +231,101 @@ static const char * file_getbuf(void *data)
return getbuf(F, ENCODING_UTF8); return getbuf(F, ENCODING_UTF8);
} }
typedef struct parser_state {
unit *u;
faction *f;
order **next_order;
} parser_state;
static void handle_faction(void *userData, int no, const char *password) {
parser_state *state = (parser_state *)userData;
faction * f = state->f = findfaction(no);
if (!f) {
log_debug("orders for unknown faction %s", itoa36(no));
}
else {
if (!checkpasswd(f, password)) {
log_debug("invalid password for faction %s", itoa36(no));
ADDMSG(&f->msgs, msg_message("wrongpasswd", "password", password));
}
}
}
static void handle_unit(void *userData, int no) {
parser_state *state = (parser_state *)userData;
unit * u = findunit(no);
state->u = NULL;
if (!u) {
/* TODO: error message */
}
else if (u->faction != state->f) {
/* TODO: error message */
}
else {
state->u = u;
begin_orders(u);
state->next_order = &u->orders;
}
}
static void handle_order(void *userData, const char *str) {
parser_state *state = (parser_state *)userData;
unit * u = state->u;
order *ord;
ord = parse_order(str, u->faction->locale);
if (ord) {
*state->next_order = ord;
state->next_order = &ord->next;
}
else {
ADDMSG(&u->faction->msgs, msg_message("parse_error", "unit command", u, str));
}
}
int parseorders(FILE *F)
{
char buf[2048];
int done = 0, err = 0;
OP_Parser parser;
parser_state state = { NULL, NULL };
parser = OP_ParserCreate();
if (!parser) {
/* TODO: error message */
return errno;
}
OP_SetUnitHandler(parser, handle_unit);
OP_SetFactionHandler(parser, handle_faction);
OP_SetOrderHandler(parser, handle_order);
OP_SetUserData(parser, &state);
while (!done) {
size_t len = (int)fread(buf, 1, sizeof(buf), F);
if (ferror(F)) {
/* TODO: error message */
err = errno;
break;
}
done = feof(F);
if (OP_Parse(parser, buf, len, done) == OP_STATUS_ERROR) {
/* TODO: error message */
err = -1;
break;
}
}
OP_ParserFree(parser);
return err;
}
int readorders(FILE *F) int readorders(FILE *F)
{ {
#undef NEW_PARSER
#ifdef NEW_PARSER
return parseorders(F);
#else
input in; input in;
int result; int result;
@ -240,4 +333,5 @@ int readorders(FILE *F)
in.data = F; in.data = F;
result = read_orders(&in); result = read_orders(&in);
return result; return result;
#endif
} }

View File

@ -18,9 +18,27 @@ struct OrderParserStruct {
int m_lineNumber; int m_lineNumber;
}; };
void OP_SetUnitHandler(OP_Parser op, OP_UnitHandler handler)
{
op->m_unitHandler = handler;
}
void OP_SetFactionHandler(OP_Parser op, OP_FactionHandler handler) {
op->m_factionHandler = handler;
}
void OP_SetOrderHandler(OP_Parser op, OP_OrderHandler handler) {
op->m_orderHandler = handler;
}
void OP_SetUserData(OP_Parser op, void *userData) {
op->m_userData = userData;
}
OP_Parser OP_ParserCreate(void) OP_Parser OP_ParserCreate(void)
{ {
return NULL; OP_Parser parser = calloc(1, sizeof(struct OrderParserStruct));
return parser;
} }
void OP_ParserFree(OP_Parser op) { void OP_ParserFree(OP_Parser op) {

View File

@ -25,10 +25,14 @@ enum OP_Status {
typedef void(*OP_FactionHandler) (void *userData, int no, const char *password); typedef void(*OP_FactionHandler) (void *userData, int no, const char *password);
typedef void(*OP_UnitHandler) (void *userData, int no); typedef void(*OP_UnitHandler) (void *userData, int no);
typedef void(*OP_OrderHandler) (void *userData, const char *str, size_t len); typedef void(*OP_OrderHandler) (void *userData, const char *str);
OP_Parser OP_ParserCreate(void); OP_Parser OP_ParserCreate(void);
void OP_ParserFree(OP_Parser op); void OP_ParserFree(OP_Parser op);
enum OP_Status OP_Parse(OP_Parser op, const char *s, int len, int isFinal); enum OP_Status OP_Parse(OP_Parser op, const char *s, int len, int isFinal);
void OP_SetUnitHandler(OP_Parser op, OP_UnitHandler handler);
void OP_SetFactionHandler(OP_Parser op, OP_FactionHandler handler);
void OP_SetOrderHandler(OP_Parser op, OP_OrderHandler handler);
void OP_SetUserData(OP_Parser op, void *userData);
#endif #endif