forked from github/server
fix comment parsing at end of input
This commit is contained in:
parent
b439e48a22
commit
6c1d266c12
|
@ -348,7 +348,7 @@ int parseorders(FILE *F)
|
||||||
done = feof(F);
|
done = feof(F);
|
||||||
if (OP_Parse(parser, buf, len, done) == OP_STATUS_ERROR) {
|
if (OP_Parse(parser, buf, len, done) == OP_STATUS_ERROR) {
|
||||||
/* TODO: error message */
|
/* TODO: error message */
|
||||||
err = -1;
|
err = (int)OP_GetErrorCode(parser);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
#include "order_parser.h"
|
#include "order_parser.h"
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <ctype.h>
|
#include <wctype.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
@ -19,6 +19,10 @@ struct OrderParserStruct {
|
||||||
int m_lineNumber;
|
int m_lineNumber;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum OP_Error OP_GetErrorCode(OP_Parser parser) {
|
||||||
|
return parser->m_errorCode;
|
||||||
|
}
|
||||||
|
|
||||||
void OP_SetOrderHandler(OP_Parser parser, OP_OrderHandler handler) {
|
void OP_SetOrderHandler(OP_Parser parser, OP_OrderHandler handler) {
|
||||||
parser->m_orderHandler = handler;
|
parser->m_orderHandler = handler;
|
||||||
}
|
}
|
||||||
|
@ -87,8 +91,9 @@ static enum OP_Error buffer_append(OP_Parser parser, const char *s, int len)
|
||||||
static char *skip_spaces(char *pos) {
|
static char *skip_spaces(char *pos) {
|
||||||
char *next;
|
char *next;
|
||||||
for (next = pos; *next && *next != '\n'; ++next) {
|
for (next = pos; *next && *next != '\n'; ++next) {
|
||||||
|
wint_t wch = *(unsigned char *)next;
|
||||||
/* TODO: handle unicode whitespace */
|
/* TODO: handle unicode whitespace */
|
||||||
if (!isspace(*next)) break;
|
if (!iswspace(wch)) break;
|
||||||
}
|
}
|
||||||
return next;
|
return next;
|
||||||
}
|
}
|
||||||
|
@ -110,6 +115,7 @@ static enum OP_Status parse_buffer(OP_Parser parser, int isFinal)
|
||||||
enum OP_Error code;
|
enum OP_Error code;
|
||||||
size_t len = pos - parser->m_bufferPtr;
|
size_t len = pos - parser->m_bufferPtr;
|
||||||
char *next;
|
char *next;
|
||||||
|
int continue_comment = 0;
|
||||||
|
|
||||||
switch (*pos) {
|
switch (*pos) {
|
||||||
case '\n':
|
case '\n':
|
||||||
|
@ -164,9 +170,8 @@ static enum OP_Status parse_buffer(OP_Parser parser, int isFinal)
|
||||||
if (next) {
|
if (next) {
|
||||||
if (*next == '\n') {
|
if (*next == '\n') {
|
||||||
/* no more lines in this comment, we're done: */
|
/* no more lines in this comment, we're done: */
|
||||||
pos = next + 1;
|
|
||||||
++parser->m_lineNumber;
|
++parser->m_lineNumber;
|
||||||
break;
|
break; /* exit loop */
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* is this backslash the final character? */
|
/* is this backslash the final character? */
|
||||||
|
@ -184,25 +189,42 @@ static enum OP_Status parse_buffer(OP_Parser parser, int isFinal)
|
||||||
}
|
}
|
||||||
} while (next && *next);
|
} while (next && *next);
|
||||||
|
|
||||||
if (next && pos < parser->m_bufferEnd) {
|
if (!next) {
|
||||||
/* we skip the comment, and there is more data in the buffer */
|
/* we exhausted the buffer before we finished the line */
|
||||||
parser->m_bufferPtr = pos;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
/* we exhausted the buffer before we got to the end of the comment */
|
|
||||||
if (isFinal) {
|
if (isFinal) {
|
||||||
/* the input ended on this comment line, which is fine */
|
/* this comment was at the end of the file, it just has no newline. done! */
|
||||||
return OP_STATUS_OK;
|
return OP_STATUS_OK;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* skip what we have of the comment, keep the semicolon, keep going */
|
/* there is more of this line in the next buffer, save the semicolon */
|
||||||
ptrdiff_t skip = parser->m_bufferEnd - parser->m_bufferPtr;
|
continue_comment = 1;
|
||||||
if (skip > 1) {
|
|
||||||
parser->m_bufferPtr += (skip - 1);
|
|
||||||
parser->m_bufferPtr[0] = ';';
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
if (*next) {
|
||||||
|
/* end comment parsing, begin parsing a new line */
|
||||||
|
pos = next + 1;
|
||||||
|
continue_comment = 0;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* reached end of input naturally, need more data to finish */
|
||||||
|
continue_comment = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (continue_comment) {
|
||||||
|
ptrdiff_t skip = parser->m_bufferEnd - parser->m_bufferPtr;
|
||||||
|
continue_comment = 0;
|
||||||
|
if (skip > 0) {
|
||||||
|
/* should always be true */
|
||||||
|
parser->m_bufferPtr += (skip - 1);
|
||||||
|
parser->m_bufferPtr[0] = ';';
|
||||||
|
}
|
||||||
|
return OP_STATUS_OK;
|
||||||
|
}
|
||||||
|
/* continue the outer loop */
|
||||||
|
parser->m_bufferPtr = pos;
|
||||||
|
pos = strpbrk(pos, "\\;\n");
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
parser->m_errorCode = OP_ERROR_SYNTAX;
|
parser->m_errorCode = OP_ERROR_SYNTAX;
|
||||||
|
|
|
@ -37,5 +37,6 @@ void OP_ParserReset(OP_Parser parser);
|
||||||
enum OP_Status OP_Parse(OP_Parser parser, const char *s, int len, int isFinal);
|
enum OP_Status OP_Parse(OP_Parser parser, const char *s, int len, int isFinal);
|
||||||
void OP_SetOrderHandler(OP_Parser parser, OP_OrderHandler handler);
|
void OP_SetOrderHandler(OP_Parser parser, OP_OrderHandler handler);
|
||||||
void OP_SetUserData(OP_Parser parser, void *userData);
|
void OP_SetUserData(OP_Parser parser, void *userData);
|
||||||
|
enum OP_Error OP_GetErrorCode(OP_Parser parser);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -57,16 +57,22 @@ static void test_parse_orders(CuTest *tc) {
|
||||||
CuAssertStrEquals(tc, "Hello\\World", lastline);
|
CuAssertStrEquals(tc, "Hello\\World", lastline);
|
||||||
OP_ParserReset(parser);
|
OP_ParserReset(parser);
|
||||||
|
|
||||||
|
lastline[0] = 0;
|
||||||
|
CuAssertIntEquals(tc, OP_STATUS_OK, OP_Parse(parser, ";\n", 2, 0));
|
||||||
|
CuAssertIntEquals(tc, OP_STATUS_OK, OP_Parse(parser, "Hello World", 11, 1));
|
||||||
|
CuAssertStrEquals(tc, "Hello World", lastline);
|
||||||
|
OP_ParserReset(parser);
|
||||||
|
|
||||||
lastline[0] = 0;
|
lastline[0] = 0;
|
||||||
CuAssertIntEquals(tc, OP_STATUS_OK, OP_Parse(parser, ";Hello \\", 8, 0));
|
CuAssertIntEquals(tc, OP_STATUS_OK, OP_Parse(parser, ";Hello \\", 8, 0));
|
||||||
CuAssertIntEquals(tc, OP_STATUS_OK, OP_Parse(parser, "\nWorld\n", 7, 1));
|
CuAssertIntEquals(tc, OP_STATUS_OK, OP_Parse(parser, "\nWorld\n", 7, 0));
|
||||||
CuAssertIntEquals(tc, OP_STATUS_OK, OP_Parse(parser, "Enno", 4, 1));
|
CuAssertIntEquals(tc, OP_STATUS_OK, OP_Parse(parser, "Enno", 4, 1));
|
||||||
CuAssertStrEquals(tc, "Enno", lastline);
|
CuAssertStrEquals(tc, "Enno", lastline);
|
||||||
OP_ParserReset(parser);
|
OP_ParserReset(parser);
|
||||||
|
|
||||||
lastline[0] = 0;
|
lastline[0] = 0;
|
||||||
CuAssertIntEquals(tc, OP_STATUS_OK, OP_Parse(parser, ";Hello", 6, 0));
|
CuAssertIntEquals(tc, OP_STATUS_OK, OP_Parse(parser, ";Hello", 6, 0));
|
||||||
CuAssertIntEquals(tc, OP_STATUS_OK, OP_Parse(parser, "World\n", 6, 1));
|
CuAssertIntEquals(tc, OP_STATUS_OK, OP_Parse(parser, "World\n", 6, 0));
|
||||||
CuAssertIntEquals(tc, OP_STATUS_OK, OP_Parse(parser, "Enno", 4, 1));
|
CuAssertIntEquals(tc, OP_STATUS_OK, OP_Parse(parser, "Enno", 4, 1));
|
||||||
CuAssertStrEquals(tc, "Enno", lastline);
|
CuAssertStrEquals(tc, "Enno", lastline);
|
||||||
OP_ParserReset(parser);
|
OP_ParserReset(parser);
|
||||||
|
@ -82,6 +88,11 @@ static void test_parse_orders(CuTest *tc) {
|
||||||
CuAssertStrEquals(tc, "World", lastline);
|
CuAssertStrEquals(tc, "World", lastline);
|
||||||
OP_ParserReset(parser);
|
OP_ParserReset(parser);
|
||||||
|
|
||||||
|
lastline[0] = 0;
|
||||||
|
CuAssertIntEquals(tc, OP_STATUS_OK, OP_Parse(parser, "Hello\n", 6, 0));
|
||||||
|
CuAssertIntEquals(tc, OP_STATUS_OK, OP_Parse(parser, "World\n", 6, 1));
|
||||||
|
CuAssertStrEquals(tc, "World", lastline);
|
||||||
|
OP_ParserReset(parser);
|
||||||
lastline[0] = 0;
|
lastline[0] = 0;
|
||||||
CuAssertIntEquals(tc, OP_STATUS_OK, OP_Parse(parser, "Hello \\", 7, 0));
|
CuAssertIntEquals(tc, OP_STATUS_OK, OP_Parse(parser, "Hello \\", 7, 0));
|
||||||
CuAssertIntEquals(tc, OP_STATUS_OK, OP_Parse(parser, "\nWorld", 6, 1));
|
CuAssertIntEquals(tc, OP_STATUS_OK, OP_Parse(parser, "\nWorld", 6, 1));
|
||||||
|
|
Loading…
Reference in New Issue