diff --git a/src/orderfile.c b/src/orderfile.c index 33a9c19f7..450e1b0c1 100644 --- a/src/orderfile.c +++ b/src/orderfile.c @@ -21,6 +21,9 @@ #include #include +static FILE *dlog; +static int orders_parsed, units_parsed, factions_parsed; + static void begin_orders(unit *u) { if (u->flags & UFL_ORDERS) { order **ordp; @@ -52,6 +55,7 @@ static unit *unitorders(input *in, faction *f) int i; unit *u; + ++units_parsed; if (!f) return NULL; @@ -109,6 +113,11 @@ static unit *unitorders(input *in, faction *f) } } /* Nun wird der Befehl erzeut und eingeh�ngt */ + ++orders_parsed; + if (dlog) { + fputs(s, dlog); + fputc('\n', dlog); + } *ordp = parse_order(s, u->faction->locale); if (*ordp) { ordp = &(*ordp)->next; @@ -131,6 +140,7 @@ static faction *factionorders(void) int fid = getid(); faction *f = findfaction(fid); + ++factions_parsed; if (f != NULL && (f->flags & FFL_NPC) == 0) { char token[128]; const char *pass = gettoken(token, sizeof(token)); @@ -241,6 +251,7 @@ typedef struct 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); + ++factions_parsed; if (!f) { log_debug("orders for unknown faction %s", itoa36(no)); } @@ -258,6 +269,7 @@ static void handle_unit(void *userData, int no) { parser_state *state = (parser_state *)userData; unit * u = findunit(no); + ++units_parsed; state->u = NULL; if (!u) { /* TODO: error message */ @@ -313,6 +325,11 @@ static void handle_order(void *userData, const char *str) { else if (state->u) { unit * u = state->u; order * ord = parse_order(str, lang); + ++orders_parsed; + if (dlog) { + fputs(str, dlog); + fputc('\n', dlog); + } if (ord) { *state->next_order = ord; state->next_order = &ord->next; @@ -325,7 +342,7 @@ static void handle_order(void *userData, const char *str) { int parseorders(FILE *F) { - char buf[2048]; + char buf[4096]; int done = 0, err = 0; OP_Parser parser; parser_state state = { NULL, NULL }; @@ -356,18 +373,28 @@ int parseorders(FILE *F) return err; } +#define NEW_PARSER int readorders(FILE *F) { -#define NEW_PARSER -#ifdef NEW_PARSER - return parseorders(F); -#else - input in; int result; - in.getbuf = file_getbuf; - in.data = F; - result = read_orders(&in); - return result; + orders_parsed = 0; + units_parsed = 0; + factions_parsed = 0; + +#ifdef NEW_PARSER + dlog = fopen("orders.new.log", "w+"); + result = parseorders(F); +#else + dlog = fopen("orders.old.log", "w+"); + { + input in; + in.getbuf = file_getbuf; + in.data = F; + result = read_orders(&in); + } #endif + fclose(dlog); + log_debug("%d orders read.", orders_parsed); + return result; } diff --git a/src/util/order_parser.c b/src/util/order_parser.c index 88a42f0ab..55b03accd 100644 --- a/src/util/order_parser.c +++ b/src/util/order_parser.c @@ -175,12 +175,16 @@ static enum OP_Status parse_buffer(OP_Parser parser, int isFinal) } else { /* is this backslash the final character? */ - next = skip_spaces(pos + 1); + next = skip_spaces(next + 1); if (*next == '\n') { /* we have a multi-line comment! */ pos = next + 1; ++parser->m_lineNumber; } + else if (*next == '\0') { + /* cannot find the EOL char yet, stream is dry. keep ; and \ */ + continue_comment = 2; + } else { /* keep looking for a backslash */ pos = next; @@ -206,7 +210,7 @@ static enum OP_Status parse_buffer(OP_Parser parser, int isFinal) pos = next + 1; continue_comment = 0; } - else { + else if (!continue_comment) { /* reached end of input naturally, need more data to finish */ continue_comment = 1; } @@ -214,12 +218,16 @@ static enum OP_Status parse_buffer(OP_Parser parser, int isFinal) if (continue_comment) { ptrdiff_t skip = parser->m_bufferEnd - parser->m_bufferPtr; - continue_comment = 0; - if (skip > 0) { + assert(skip >= continue_comment); + if (skip >= continue_comment) { /* should always be true */ - parser->m_bufferPtr += (skip - 1); + parser->m_bufferPtr += (skip - continue_comment); parser->m_bufferPtr[0] = ';'; } + if (continue_comment == 2) { + parser->m_bufferPtr[1] = '\\'; + } + continue_comment = 0; return OP_STATUS_OK; } /* continue the outer loop */ diff --git a/src/util/order_parser.test.c b/src/util/order_parser.test.c index 1034e3d0a..d43f661fb 100644 --- a/src/util/order_parser.test.c +++ b/src/util/order_parser.test.c @@ -39,7 +39,24 @@ static void test_parse_orders(CuTest *tc) { OP_ParserReset(parser); lastline[0] = 0; - CuAssertIntEquals(tc, OP_STATUS_OK, OP_Parse(parser, "Hello World;\nError", 18, 1)); + CuAssertIntEquals(tc, OP_STATUS_OK, OP_Parse(parser, "Error;\nHello World", 18, 1)); + CuAssertStrEquals(tc, "Hello World", lastline); + OP_ParserReset(parser); + + lastline[0] = 0; + CuAssertIntEquals(tc, OP_STATUS_OK, OP_Parse(parser, "Hello World;\\\nError", 19, 1)); + CuAssertStrEquals(tc, "Hello World", lastline); + OP_ParserReset(parser); + + lastline[0] = 0; + CuAssertIntEquals(tc, OP_STATUS_OK, OP_Parse(parser, "Hello World;\\", 13, 0)); + CuAssertIntEquals(tc, OP_STATUS_OK, OP_Parse(parser, "\nError", 6, 1)); + CuAssertStrEquals(tc, "Hello World", lastline); + OP_ParserReset(parser); + + lastline[0] = 0; + CuAssertIntEquals(tc, OP_STATUS_OK, OP_Parse(parser, "Hello \\", 7, 0)); + CuAssertIntEquals(tc, OP_STATUS_OK, OP_Parse(parser, "\nWorld", 6, 1)); CuAssertStrEquals(tc, "Hello World", lastline); OP_ParserReset(parser);