From 965c8ce990d774e43644536c41c102e038d54913 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sat, 29 Sep 2018 21:19:24 +0200 Subject: [PATCH] start putting the new parser into the server. --- src/orderfile.c | 148 ++++++++++++++++++++++++++++++++-------- src/util/order_parser.c | 20 +++++- src/util/order_parser.h | 6 +- 3 files changed, 145 insertions(+), 29 deletions(-) diff --git a/src/orderfile.c b/src/orderfile.c index 97008f4db..a4f47a4e3 100644 --- a/src/orderfile.c +++ b/src/orderfile.c @@ -20,6 +20,32 @@ #include #include +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) { int i; @@ -34,29 +60,7 @@ static unit *unitorders(input *in, faction *f) if (u && u->faction == f) { order **ordp; - if (u->flags & UFL_ORDERS) { - /* 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; - + begin_orders(u); ordp = &u->orders; for (;;) { @@ -152,10 +156,6 @@ int read_orders(input *in) int nfactions = 0; struct faction *f = NULL; const struct locale *lang = default_locale; - OP_Parser parser; - - parser = OP_ParserCreate(); - OP_ParserFree(parser); /* TODO: recognize UTF8 BOM */ b = in->getbuf(in->data); @@ -231,8 +231,101 @@ static const char * file_getbuf(void *data) 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) { +#undef NEW_PARSER +#ifdef NEW_PARSER + return parseorders(F); +#else input in; int result; @@ -240,4 +333,5 @@ int readorders(FILE *F) in.data = F; result = read_orders(&in); return result; +#endif } diff --git a/src/util/order_parser.c b/src/util/order_parser.c index 691686276..363f12c92 100644 --- a/src/util/order_parser.c +++ b/src/util/order_parser.c @@ -18,9 +18,27 @@ struct OrderParserStruct { 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) { - return NULL; + OP_Parser parser = calloc(1, sizeof(struct OrderParserStruct)); + return parser; } void OP_ParserFree(OP_Parser op) { diff --git a/src/util/order_parser.h b/src/util/order_parser.h index ee98b72a6..7600ee3da 100644 --- a/src/util/order_parser.h +++ b/src/util/order_parser.h @@ -25,10 +25,14 @@ enum OP_Status { typedef void(*OP_FactionHandler) (void *userData, int no, const char *password); 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); void OP_ParserFree(OP_Parser op); 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