fix error in multi-line comments at stream border.

This commit is contained in:
Enno Rehling 2018-10-03 19:47:32 +02:00
parent 854decc4f1
commit fbce8f326a
3 changed files with 68 additions and 16 deletions

View file

@ -21,6 +21,9 @@
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
static FILE *dlog;
static int orders_parsed, units_parsed, factions_parsed;
static void begin_orders(unit *u) { static void begin_orders(unit *u) {
if (u->flags & UFL_ORDERS) { if (u->flags & UFL_ORDERS) {
order **ordp; order **ordp;
@ -52,6 +55,7 @@ static unit *unitorders(input *in, faction *f)
int i; int i;
unit *u; unit *u;
++units_parsed;
if (!f) if (!f)
return NULL; return NULL;
@ -109,6 +113,11 @@ static unit *unitorders(input *in, faction *f)
} }
} }
/* Nun wird der Befehl erzeut und eingeh<65>ngt */ /* Nun wird der Befehl erzeut und eingeh<65>ngt */
++orders_parsed;
if (dlog) {
fputs(s, dlog);
fputc('\n', dlog);
}
*ordp = parse_order(s, u->faction->locale); *ordp = parse_order(s, u->faction->locale);
if (*ordp) { if (*ordp) {
ordp = &(*ordp)->next; ordp = &(*ordp)->next;
@ -131,6 +140,7 @@ static faction *factionorders(void)
int fid = getid(); int fid = getid();
faction *f = findfaction(fid); faction *f = findfaction(fid);
++factions_parsed;
if (f != NULL && (f->flags & FFL_NPC) == 0) { if (f != NULL && (f->flags & FFL_NPC) == 0) {
char token[128]; char token[128];
const char *pass = gettoken(token, sizeof(token)); 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) { static void handle_faction(void *userData, int no, const char *password) {
parser_state *state = (parser_state *)userData; parser_state *state = (parser_state *)userData;
faction * f = state->f = findfaction(no); faction * f = state->f = findfaction(no);
++factions_parsed;
if (!f) { if (!f) {
log_debug("orders for unknown faction %s", itoa36(no)); 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; parser_state *state = (parser_state *)userData;
unit * u = findunit(no); unit * u = findunit(no);
++units_parsed;
state->u = NULL; state->u = NULL;
if (!u) { if (!u) {
/* TODO: error message */ /* TODO: error message */
@ -313,6 +325,11 @@ static void handle_order(void *userData, const char *str) {
else if (state->u) { else if (state->u) {
unit * u = state->u; unit * u = state->u;
order * ord = parse_order(str, lang); order * ord = parse_order(str, lang);
++orders_parsed;
if (dlog) {
fputs(str, dlog);
fputc('\n', dlog);
}
if (ord) { if (ord) {
*state->next_order = ord; *state->next_order = ord;
state->next_order = &ord->next; state->next_order = &ord->next;
@ -325,7 +342,7 @@ static void handle_order(void *userData, const char *str) {
int parseorders(FILE *F) int parseorders(FILE *F)
{ {
char buf[2048]; char buf[4096];
int done = 0, err = 0; int done = 0, err = 0;
OP_Parser parser; OP_Parser parser;
parser_state state = { NULL, NULL }; parser_state state = { NULL, NULL };
@ -356,18 +373,28 @@ int parseorders(FILE *F)
return err; return err;
} }
#define NEW_PARSER
int readorders(FILE *F) int readorders(FILE *F)
{ {
#define NEW_PARSER
#ifdef NEW_PARSER
return parseorders(F);
#else
input in;
int result; int result;
in.getbuf = file_getbuf; orders_parsed = 0;
in.data = F; units_parsed = 0;
result = read_orders(&in); factions_parsed = 0;
return result;
#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 #endif
fclose(dlog);
log_debug("%d orders read.", orders_parsed);
return result;
} }

View file

@ -175,12 +175,16 @@ static enum OP_Status parse_buffer(OP_Parser parser, int isFinal)
} }
else { else {
/* is this backslash the final character? */ /* is this backslash the final character? */
next = skip_spaces(pos + 1); next = skip_spaces(next + 1);
if (*next == '\n') { if (*next == '\n') {
/* we have a multi-line comment! */ /* we have a multi-line comment! */
pos = next + 1; pos = next + 1;
++parser->m_lineNumber; ++parser->m_lineNumber;
} }
else if (*next == '\0') {
/* cannot find the EOL char yet, stream is dry. keep ; and \ */
continue_comment = 2;
}
else { else {
/* keep looking for a backslash */ /* keep looking for a backslash */
pos = next; pos = next;
@ -206,7 +210,7 @@ static enum OP_Status parse_buffer(OP_Parser parser, int isFinal)
pos = next + 1; pos = next + 1;
continue_comment = 0; continue_comment = 0;
} }
else { else if (!continue_comment) {
/* reached end of input naturally, need more data to finish */ /* reached end of input naturally, need more data to finish */
continue_comment = 1; continue_comment = 1;
} }
@ -214,12 +218,16 @@ static enum OP_Status parse_buffer(OP_Parser parser, int isFinal)
if (continue_comment) { if (continue_comment) {
ptrdiff_t skip = parser->m_bufferEnd - parser->m_bufferPtr; ptrdiff_t skip = parser->m_bufferEnd - parser->m_bufferPtr;
continue_comment = 0; assert(skip >= continue_comment);
if (skip > 0) { if (skip >= continue_comment) {
/* should always be true */ /* should always be true */
parser->m_bufferPtr += (skip - 1); parser->m_bufferPtr += (skip - continue_comment);
parser->m_bufferPtr[0] = ';'; parser->m_bufferPtr[0] = ';';
} }
if (continue_comment == 2) {
parser->m_bufferPtr[1] = '\\';
}
continue_comment = 0;
return OP_STATUS_OK; return OP_STATUS_OK;
} }
/* continue the outer loop */ /* continue the outer loop */

View file

@ -39,7 +39,24 @@ static void test_parse_orders(CuTest *tc) {
OP_ParserReset(parser); OP_ParserReset(parser);
lastline[0] = 0; 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); CuAssertStrEquals(tc, "Hello World", lastline);
OP_ParserReset(parser); OP_ParserReset(parser);