forked from github/server
Merge branch 'checker' of github.com:ennorehling/eressea into checker
This commit is contained in:
commit
64752deb26
|
@ -41,7 +41,7 @@ int eressea_read_orders(const char * filename) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
log_info("reading orders from %s", filename);
|
log_info("reading orders from %s", filename);
|
||||||
return readorders(F);
|
return parseorders(F);
|
||||||
}
|
}
|
||||||
|
|
||||||
int eressea_export_json(const char * filename, int flags) {
|
int eressea_export_json(const char * filename, int flags) {
|
||||||
|
|
|
@ -2,10 +2,50 @@
|
||||||
#include <platform.h>
|
#include <platform.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "util/parser.h"
|
#include "util/order_parser.h"
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
|
typedef struct parser_state {
|
||||||
|
FILE * F;
|
||||||
|
} parser_state;
|
||||||
|
|
||||||
|
static void handle_order(void *userData, const char *str) {
|
||||||
|
parser_state * state = (parser_state*)userData;
|
||||||
|
fputs(str, state->F);
|
||||||
|
fputc('\n', state->F);
|
||||||
|
}
|
||||||
|
|
||||||
|
int parsefile(FILE *F) {
|
||||||
|
OP_Parser parser;
|
||||||
|
char buf[1024];
|
||||||
|
int done = 0, err = 0;
|
||||||
|
parser_state state = { NULL };
|
||||||
|
|
||||||
|
state.F = stdout;
|
||||||
|
|
||||||
|
parser = OP_ParserCreate();
|
||||||
|
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 = (int)OP_GetErrorCode(parser);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
OP_ParserFree(parser);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char **argv) {
|
int main(int argc, char **argv) {
|
||||||
FILE * F = stdin;
|
FILE * F = stdin;
|
||||||
if (argc >= 1) {
|
if (argc >= 1) {
|
||||||
|
@ -15,8 +55,10 @@ int main(int argc, char **argv) {
|
||||||
perror(filename);
|
perror(filename);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
parsefile(F);
|
||||||
|
if (F != stdin) {
|
||||||
fclose(F);
|
fclose(F);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -245,10 +245,15 @@ static void handle_faction(void *userData, int no, const char *password) {
|
||||||
log_debug("orders for unknown faction %s", itoa36(no));
|
log_debug("orders for unknown faction %s", itoa36(no));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (!checkpasswd(f, password)) {
|
if (checkpasswd(f, password)) {
|
||||||
|
f->lastorders = turn;
|
||||||
|
}
|
||||||
|
else {
|
||||||
log_debug("invalid password for faction %s", itoa36(no));
|
log_debug("invalid password for faction %s", itoa36(no));
|
||||||
ADDMSG(&f->msgs, msg_message("wrongpasswd", "password", password));
|
ADDMSG(&f->msgs, msg_message("wrongpasswd", "password", password));
|
||||||
}
|
}
|
||||||
|
state->u = NULL;
|
||||||
|
state->next_order = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -272,10 +277,45 @@ static void handle_unit(void *userData, int no) {
|
||||||
|
|
||||||
static void handle_order(void *userData, const char *str) {
|
static void handle_order(void *userData, const char *str) {
|
||||||
parser_state *state = (parser_state *)userData;
|
parser_state *state = (parser_state *)userData;
|
||||||
unit * u = state->u;
|
const char * tok, *input = str;
|
||||||
order *ord;
|
char buffer[16];
|
||||||
|
const struct locale *lang;
|
||||||
|
param_t p;
|
||||||
|
faction * f = state->f;
|
||||||
|
|
||||||
ord = parse_order(str, u->faction->locale);
|
lang = f ? f->locale : default_locale;
|
||||||
|
tok = parse_token(&input, buffer, sizeof(buffer));
|
||||||
|
p = findparam(tok, lang);
|
||||||
|
if (p == P_FACTION || p == P_GAMENAME) {
|
||||||
|
tok = parse_token(&input, buffer, sizeof(buffer));
|
||||||
|
if (tok) {
|
||||||
|
int no = atoi36(tok);
|
||||||
|
tok = parse_token(&input, buffer, sizeof(buffer));
|
||||||
|
handle_faction(userData, no, tok);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* TODO: log_error() */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (p == P_UNIT) {
|
||||||
|
tok = parse_token(&input, buffer, sizeof(buffer));
|
||||||
|
if (tok) {
|
||||||
|
int no = atoi36(tok);
|
||||||
|
handle_unit(userData, no);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (p == P_NEXT) {
|
||||||
|
state->f = NULL;
|
||||||
|
state->u = NULL;
|
||||||
|
state->next_order = NULL;
|
||||||
|
}
|
||||||
|
else if (p == P_REGION) {
|
||||||
|
state->u = NULL;
|
||||||
|
state->next_order = NULL;
|
||||||
|
}
|
||||||
|
else if (state->u) {
|
||||||
|
unit * u = state->u;
|
||||||
|
order * ord = parse_order(str, lang);
|
||||||
if (ord) {
|
if (ord) {
|
||||||
*state->next_order = ord;
|
*state->next_order = ord;
|
||||||
state->next_order = &ord->next;
|
state->next_order = &ord->next;
|
||||||
|
@ -284,11 +324,11 @@ static void handle_order(void *userData, const char *str) {
|
||||||
ADDMSG(&u->faction->msgs, msg_message("parse_error", "unit command", u, str));
|
ADDMSG(&u->faction->msgs, msg_message("parse_error", "unit command", u, 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 };
|
||||||
|
@ -298,8 +338,6 @@ int parseorders(FILE *F)
|
||||||
/* TODO: error message */
|
/* TODO: error message */
|
||||||
return errno;
|
return errno;
|
||||||
}
|
}
|
||||||
OP_SetUnitHandler(parser, handle_unit);
|
|
||||||
OP_SetFactionHandler(parser, handle_faction);
|
|
||||||
OP_SetOrderHandler(parser, handle_order);
|
OP_SetOrderHandler(parser, handle_order);
|
||||||
OP_SetUserData(parser, &state);
|
OP_SetUserData(parser, &state);
|
||||||
|
|
||||||
|
@ -313,7 +351,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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -323,16 +361,11 @@ int parseorders(FILE *F)
|
||||||
|
|
||||||
int readorders(FILE *F)
|
int readorders(FILE *F)
|
||||||
{
|
{
|
||||||
#undef NEW_PARSER
|
|
||||||
#ifdef NEW_PARSER
|
|
||||||
return parseorders(F);
|
|
||||||
#else
|
|
||||||
input in;
|
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
|
input in;
|
||||||
in.getbuf = file_getbuf;
|
in.getbuf = file_getbuf;
|
||||||
in.data = F;
|
in.data = F;
|
||||||
result = read_orders(&in);
|
result = read_orders(&in);
|
||||||
return result;
|
return result;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,7 @@ extern "C" {
|
||||||
|
|
||||||
int read_orders(struct input *in);
|
int read_orders(struct input *in);
|
||||||
int readorders(FILE *F);
|
int readorders(FILE *F);
|
||||||
|
int parseorders(FILE *F);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
|
@ -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>
|
||||||
|
|
||||||
|
@ -13,21 +13,15 @@ struct OrderParserStruct {
|
||||||
void *m_userData;
|
void *m_userData;
|
||||||
char *m_buffer;
|
char *m_buffer;
|
||||||
char *m_bufferPtr;
|
char *m_bufferPtr;
|
||||||
|
size_t m_bufferSize;
|
||||||
const char *m_bufferEnd;
|
const char *m_bufferEnd;
|
||||||
OP_FactionHandler m_factionHandler;
|
|
||||||
OP_UnitHandler m_unitHandler;
|
|
||||||
OP_OrderHandler m_orderHandler;
|
OP_OrderHandler m_orderHandler;
|
||||||
enum OP_Error m_errorCode;
|
enum OP_Error m_errorCode;
|
||||||
int m_lineNumber;
|
int m_lineNumber;
|
||||||
};
|
};
|
||||||
|
|
||||||
void OP_SetUnitHandler(OP_Parser parser, OP_UnitHandler handler)
|
enum OP_Error OP_GetErrorCode(OP_Parser parser) {
|
||||||
{
|
return parser->m_errorCode;
|
||||||
parser->m_unitHandler = handler;
|
|
||||||
}
|
|
||||||
|
|
||||||
void OP_SetFactionHandler(OP_Parser parser, OP_FactionHandler handler) {
|
|
||||||
parser->m_factionHandler = handler;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void OP_SetOrderHandler(OP_Parser parser, OP_OrderHandler handler) {
|
void OP_SetOrderHandler(OP_Parser parser, OP_OrderHandler handler) {
|
||||||
|
@ -42,6 +36,7 @@ static void buffer_free(OP_Parser parser)
|
||||||
{
|
{
|
||||||
/* TODO: recycle buffers, reduce mallocs. */
|
/* TODO: recycle buffers, reduce mallocs. */
|
||||||
free(parser->m_buffer);
|
free(parser->m_buffer);
|
||||||
|
parser->m_bufferSize = 0;
|
||||||
parser->m_bufferEnd = parser->m_bufferPtr = parser->m_buffer = NULL;
|
parser->m_bufferEnd = parser->m_bufferPtr = parser->m_buffer = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -65,8 +60,28 @@ void OP_ParserFree(OP_Parser parser) {
|
||||||
|
|
||||||
static enum OP_Error buffer_append(OP_Parser parser, const char *s, int len)
|
static enum OP_Error buffer_append(OP_Parser parser, const char *s, int len)
|
||||||
{
|
{
|
||||||
|
size_t total = len + 1;
|
||||||
|
size_t remain = parser->m_bufferEnd - parser->m_bufferPtr;
|
||||||
|
total += remain;
|
||||||
|
if (remain > 0) {
|
||||||
|
/* there is remaining data in the buffer, should we move it to the front? */
|
||||||
|
if (total <= parser->m_bufferSize) {
|
||||||
|
/* reuse existing buffer */
|
||||||
|
memmove(parser->m_buffer, parser->m_bufferPtr, remain);
|
||||||
|
memcpy(parser->m_buffer + remain, s, len);
|
||||||
|
parser->m_buffer[total - 1] = '\0';
|
||||||
|
parser->m_bufferPtr = parser->m_buffer;
|
||||||
|
parser->m_bufferEnd = parser->m_bufferPtr + total - 1;
|
||||||
|
return OP_ERROR_NONE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (parser->m_bufferPtr >= parser->m_bufferEnd) {
|
||||||
|
buffer_free(parser);
|
||||||
|
}
|
||||||
|
|
||||||
if (parser->m_buffer == NULL) {
|
if (parser->m_buffer == NULL) {
|
||||||
parser->m_buffer = malloc(len + 1);
|
parser->m_bufferSize = len + 1;
|
||||||
|
parser->m_buffer = malloc(parser->m_bufferSize);
|
||||||
if (!parser->m_buffer) {
|
if (!parser->m_buffer) {
|
||||||
return OP_ERROR_NO_MEMORY;
|
return OP_ERROR_NO_MEMORY;
|
||||||
}
|
}
|
||||||
|
@ -76,28 +91,26 @@ static enum OP_Error buffer_append(OP_Parser parser, const char *s, int len)
|
||||||
parser->m_bufferEnd = parser->m_buffer + len;
|
parser->m_bufferEnd = parser->m_buffer + len;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
size_t total = len;
|
|
||||||
char * buffer;
|
char * buffer;
|
||||||
total += (parser->m_bufferEnd - parser->m_bufferPtr);
|
|
||||||
/* TODO: recycle buffers, reduce mallocs. */
|
/* TODO: recycle buffers, reduce mallocs. */
|
||||||
buffer = malloc(total + 1);
|
if (parser->m_bufferSize < total) {
|
||||||
memcpy(buffer, parser->m_bufferPtr, total - len);
|
parser->m_bufferSize = total;
|
||||||
memcpy(buffer + total - len, s, len);
|
buffer = malloc(parser->m_bufferSize);
|
||||||
buffer[total] = '\0';
|
if (!buffer) {
|
||||||
free(parser->m_buffer);
|
|
||||||
parser->m_buffer = buffer;
|
|
||||||
if (!parser->m_buffer) {
|
|
||||||
return OP_ERROR_NO_MEMORY;
|
return OP_ERROR_NO_MEMORY;
|
||||||
}
|
}
|
||||||
|
memcpy(buffer, parser->m_bufferPtr, total - len - 1);
|
||||||
|
memcpy(buffer + total - len - 1, s, len);
|
||||||
|
free(parser->m_buffer);
|
||||||
|
parser->m_buffer = buffer;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
memcpy(parser->m_buffer, parser->m_bufferPtr, total - len);
|
||||||
|
memcpy(parser->m_buffer + total - len, s, len);
|
||||||
|
}
|
||||||
|
parser->m_buffer[total - 1] = '\0';
|
||||||
parser->m_bufferPtr = parser->m_buffer;
|
parser->m_bufferPtr = parser->m_buffer;
|
||||||
parser->m_bufferEnd = parser->m_buffer + total;
|
parser->m_bufferEnd = parser->m_buffer + total - 1;
|
||||||
}
|
|
||||||
return OP_ERROR_NONE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static enum OP_Error handle_line(OP_Parser parser) {
|
|
||||||
if (parser->m_orderHandler) {
|
|
||||||
parser->m_orderHandler(parser->m_userData, parser->m_bufferPtr);
|
|
||||||
}
|
}
|
||||||
return OP_ERROR_NONE;
|
return OP_ERROR_NONE;
|
||||||
}
|
}
|
||||||
|
@ -105,12 +118,23 @@ static enum OP_Error handle_line(OP_Parser parser) {
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static enum OP_Error handle_line(OP_Parser parser) {
|
||||||
|
if (parser->m_orderHandler) {
|
||||||
|
char * str = skip_spaces(parser->m_bufferPtr);
|
||||||
|
if (*str) {
|
||||||
|
parser->m_orderHandler(parser->m_userData, str);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return OP_ERROR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
static enum OP_Status parse_buffer(OP_Parser parser, int isFinal)
|
static enum OP_Status parse_buffer(OP_Parser parser, int isFinal)
|
||||||
{
|
{
|
||||||
char * pos = strpbrk(parser->m_bufferPtr, "\\;\n");
|
char * pos = strpbrk(parser->m_bufferPtr, "\\;\n");
|
||||||
|
@ -118,6 +142,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':
|
||||||
|
@ -172,18 +197,21 @@ 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? */
|
||||||
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;
|
||||||
|
@ -192,25 +220,46 @@ 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 */
|
||||||
|
continue_comment = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (*next) {
|
||||||
|
/* end comment parsing, begin parsing a new line */
|
||||||
|
pos = next + 1;
|
||||||
|
continue_comment = 0;
|
||||||
|
}
|
||||||
|
else if (!continue_comment) {
|
||||||
|
/* 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;
|
ptrdiff_t skip = parser->m_bufferEnd - parser->m_bufferPtr;
|
||||||
if (skip > 1) {
|
assert(skip >= continue_comment);
|
||||||
parser->m_bufferPtr += (skip - 1);
|
if (skip >= continue_comment) {
|
||||||
|
/* should always be true */
|
||||||
|
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;
|
||||||
}
|
}
|
||||||
|
/* 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;
|
||||||
|
@ -228,10 +277,6 @@ enum OP_Status OP_Parse(OP_Parser parser, const char *s, int len, int isFinal)
|
||||||
{
|
{
|
||||||
enum OP_Error code;
|
enum OP_Error code;
|
||||||
|
|
||||||
if (parser->m_bufferPtr >= parser->m_bufferEnd) {
|
|
||||||
buffer_free(parser);
|
|
||||||
}
|
|
||||||
|
|
||||||
code = buffer_append(parser, s, len);
|
code = buffer_append(parser, s, len);
|
||||||
if (code != OP_ERROR_NONE) {
|
if (code != OP_ERROR_NONE) {
|
||||||
parser->m_errorCode = code;
|
parser->m_errorCode = code;
|
||||||
|
|
|
@ -29,17 +29,14 @@ enum OP_Error {
|
||||||
OP_ERROR_SYNTAX
|
OP_ERROR_SYNTAX
|
||||||
};
|
};
|
||||||
|
|
||||||
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);
|
typedef void(*OP_OrderHandler) (void *userData, const char *str);
|
||||||
|
|
||||||
OP_Parser OP_ParserCreate(void);
|
OP_Parser OP_ParserCreate(void);
|
||||||
void OP_ParserFree(OP_Parser parser);
|
void OP_ParserFree(OP_Parser parser);
|
||||||
void OP_ParserReset(OP_Parser parser);
|
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_SetUnitHandler(OP_Parser parser, OP_UnitHandler handler);
|
|
||||||
void OP_SetFactionHandler(OP_Parser parser, OP_FactionHandler handler);
|
|
||||||
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
|
||||||
|
|
|
@ -32,35 +32,90 @@ static void test_parse_orders(CuTest *tc) {
|
||||||
OP_SetUserData(parser, lastline);
|
OP_SetUserData(parser, lastline);
|
||||||
OP_SetOrderHandler(parser, copy_line);
|
OP_SetOrderHandler(parser, copy_line);
|
||||||
CuAssertPtrNotNull(tc, parser);
|
CuAssertPtrNotNull(tc, parser);
|
||||||
|
|
||||||
lastline[0] = 0;
|
lastline[0] = 0;
|
||||||
CuAssertIntEquals(tc, OP_STATUS_OK, OP_Parse(parser, "Hello World", 11, 1));
|
CuAssertIntEquals(tc, OP_STATUS_OK, OP_Parse(parser, "Hello World", 11, 1));
|
||||||
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, "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);
|
||||||
|
|
||||||
lastline[0] = 0;
|
lastline[0] = 0;
|
||||||
CuAssertIntEquals(tc, OP_STATUS_OK, OP_Parse(parser, "Hello World\n", 12, 1));
|
CuAssertIntEquals(tc, OP_STATUS_OK, OP_Parse(parser, "Hello World\n", 12, 1));
|
||||||
CuAssertStrEquals(tc, "Hello World", lastline);
|
CuAssertStrEquals(tc, "Hello World", lastline);
|
||||||
OP_ParserReset(parser);
|
OP_ParserReset(parser);
|
||||||
|
|
||||||
lastline[0] = 0;
|
lastline[0] = 0;
|
||||||
CuAssertIntEquals(tc, OP_STATUS_OK, OP_Parse(parser, "Hello\\\n World", 13, 1));
|
CuAssertIntEquals(tc, OP_STATUS_OK, OP_Parse(parser, "Hello\\\n World", 13, 1));
|
||||||
CuAssertStrEquals(tc, "Hello World", lastline);
|
CuAssertStrEquals(tc, "Hello World", lastline);
|
||||||
OP_ParserReset(parser);
|
OP_ParserReset(parser);
|
||||||
|
|
||||||
lastline[0] = 0;
|
lastline[0] = 0;
|
||||||
CuAssertIntEquals(tc, OP_STATUS_OK, OP_Parse(parser, "Hello;World", 11, 1));
|
CuAssertIntEquals(tc, OP_STATUS_OK, OP_Parse(parser, "Hello;World", 11, 1));
|
||||||
CuAssertStrEquals(tc, "Hello", lastline);
|
CuAssertStrEquals(tc, "Hello", lastline);
|
||||||
OP_ParserReset(parser);
|
OP_ParserReset(parser);
|
||||||
|
|
||||||
lastline[0] = 0;
|
lastline[0] = 0;
|
||||||
CuAssertIntEquals(tc, OP_STATUS_OK, OP_Parse(parser, "Hello\\World", 11, 1));
|
CuAssertIntEquals(tc, OP_STATUS_OK, OP_Parse(parser, "Hello\\World", 11, 1));
|
||||||
CuAssertStrEquals(tc, "Hello\\World", lastline);
|
CuAssertStrEquals(tc, "Hello\\World", 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, ";\n", 2, 0));
|
||||||
CuAssertIntEquals(tc, OP_STATUS_OK, OP_Parse(parser, "World", 5, 1));
|
CuAssertIntEquals(tc, OP_STATUS_OK, OP_Parse(parser, "Hello World", 11, 1));
|
||||||
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, ";Hello \\", 8, 0));
|
||||||
|
CuAssertIntEquals(tc, OP_STATUS_OK, OP_Parse(parser, "\nWorld\n", 7, 0));
|
||||||
|
CuAssertIntEquals(tc, OP_STATUS_OK, OP_Parse(parser, "Enno", 4, 1));
|
||||||
|
CuAssertStrEquals(tc, "Enno", lastline);
|
||||||
|
OP_ParserReset(parser);
|
||||||
|
|
||||||
|
lastline[0] = 0;
|
||||||
|
CuAssertIntEquals(tc, OP_STATUS_OK, OP_Parse(parser, ";Hello", 6, 0));
|
||||||
|
CuAssertIntEquals(tc, OP_STATUS_OK, OP_Parse(parser, "World\n", 6, 0));
|
||||||
|
CuAssertIntEquals(tc, OP_STATUS_OK, OP_Parse(parser, "Enno", 4, 1));
|
||||||
|
CuAssertStrEquals(tc, "Enno", lastline);
|
||||||
|
OP_ParserReset(parser);
|
||||||
|
|
||||||
lastline[0] = 0;
|
lastline[0] = 0;
|
||||||
CuAssertIntEquals(tc, OP_STATUS_OK, OP_Parse(parser, "Hello\\World \\", 14, 1));
|
CuAssertIntEquals(tc, OP_STATUS_OK, OP_Parse(parser, "Hello\\World \\", 14, 1));
|
||||||
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, "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;
|
||||||
|
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