Parser
This commit is contained in:
parent
8246b97f56
commit
882d0ed4f7
@ -6,11 +6,14 @@
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/tcp.h>
|
||||
#include <poll.h>
|
||||
|
||||
static int opensocket(const char *hostname, const char *port) {
|
||||
struct addrinfo *res = NULL, pref;
|
||||
int ret;
|
||||
int s;
|
||||
int ret, s, val;
|
||||
|
||||
pref.ai_flags = 0;
|
||||
pref.ai_family = PF_UNSPEC;
|
||||
@ -35,6 +38,15 @@ static int opensocket(const char *hostname, const char *port) {
|
||||
if (0 != connect(s, res->ai_addr, res->ai_addrlen)) {
|
||||
fprintf(stderr, "Couldn't connect socket to '%s:%s': %s\n", hostname, port, strerror(errno));
|
||||
freeaddrinfo(res);
|
||||
close(s);
|
||||
return -1;
|
||||
}
|
||||
|
||||
val = 1;
|
||||
if (0 != setsockopt(s, IPPROTO_TCP, TCP_NODELAY, &val, sizeof(val))) {
|
||||
fprintf(stderr, "Couldn't set socket option TCP_NODELAY: %s\n", strerror(errno));
|
||||
freeaddrinfo(res);
|
||||
close(s);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -82,10 +94,43 @@ void trial_wait_for_start(trial *t) {
|
||||
}
|
||||
}
|
||||
|
||||
static char buffer[16*1024];
|
||||
|
||||
void trial_check_input(trial *t) {
|
||||
ssize_t len;
|
||||
struct pollfd p;
|
||||
p.fd = t->socket;
|
||||
p.events = POLLIN;
|
||||
switch (poll(&p, 1, 0)) {
|
||||
case -1:
|
||||
switch (errno) {
|
||||
case EAGAIN:
|
||||
case EINTR:
|
||||
return;
|
||||
}
|
||||
fprintf(stderr, "poll error: %s\n", strerror(errno));
|
||||
exit(127);
|
||||
break;
|
||||
case 0:
|
||||
return;
|
||||
}
|
||||
len = read(t->socket, buffer, sizeof(buffer));
|
||||
if (len < 0) {
|
||||
fprintf(stderr, "read error: %s\n", strerror(errno));
|
||||
exit(127);
|
||||
}
|
||||
g_string_append_len(t->parse_ctx->buffer, buffer, len);
|
||||
control_parse(t);
|
||||
}
|
||||
|
||||
void trial_wait_for_input(trial *t) {
|
||||
ssize_t len = read(t->socket, buffer, sizeof(buffer));
|
||||
if (len < 0) {
|
||||
fprintf(stderr, "read error: %s\n", strerror(errno));
|
||||
exit(127);
|
||||
}
|
||||
g_string_append_len(t->parse_ctx->buffer, buffer, len);
|
||||
control_parse(t);
|
||||
}
|
||||
|
||||
void trial_free(trial *t) {
|
||||
|
@ -1,6 +1,8 @@
|
||||
#ifndef _CONTROL_H
|
||||
#define _CONTROL_H
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <unistd.h>
|
||||
#include <glib.h>
|
||||
|
||||
@ -29,7 +31,7 @@ typedef struct trial trial;
|
||||
|
||||
typedef unsigned int timestamp;
|
||||
|
||||
|
||||
#include "control_parser.h"
|
||||
|
||||
struct object {
|
||||
object_t type;
|
||||
@ -67,6 +69,7 @@ struct trial {
|
||||
|
||||
/* internal */
|
||||
int socket;
|
||||
control_parser_ctx *parse_ctx;
|
||||
};
|
||||
|
||||
/* trial */
|
||||
|
26
src/control_parser.h
Normal file
26
src/control_parser.h
Normal file
@ -0,0 +1,26 @@
|
||||
#ifndef _CONTROL_PARSER_H
|
||||
#define _CONTROL_PARSER_H
|
||||
|
||||
struct control_parser_ctx;
|
||||
typedef struct control_parser_ctx control_parser_ctx;
|
||||
|
||||
typedef enum { RUN_ERROR, RUN_DONE, RUN_GO_ON } run_t;
|
||||
|
||||
#include "control.h"
|
||||
|
||||
struct control_parser_ctx {
|
||||
int cs;
|
||||
GString *buffer;
|
||||
gsize read;
|
||||
size_t mark;
|
||||
|
||||
GString *tmp;
|
||||
double d;
|
||||
};
|
||||
|
||||
void control_parser_new(trial *t);
|
||||
void control_parser_reset(trial *t);
|
||||
void control_parser_free(trial *t);
|
||||
run_t control_parse(trial *t);
|
||||
|
||||
#endif
|
89
src/control_parser.rl
Normal file
89
src/control_parser.rl
Normal file
@ -0,0 +1,89 @@
|
||||
|
||||
#include "control_parser.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
typedef control_parser_ctx context;
|
||||
|
||||
static void extract(context *ctx, char *fpc) {
|
||||
gsize len = (fpc - ctx->buffer->str) - ctx->mark;
|
||||
g_string_truncate(ctx->tmp, 0);
|
||||
g_string_append_len(ctx->tmp, ctx->buffer->str + ctx->mark, len);
|
||||
ctx->read += len;
|
||||
}
|
||||
|
||||
%%{
|
||||
|
||||
machine control_parser;
|
||||
variable cs ctx->cs;
|
||||
|
||||
action done { fbreak; }
|
||||
action mark { ctx->mark = fpc - ctx->buffer->str; }
|
||||
action parsedouble {
|
||||
extract(ctx, fpc);
|
||||
ctx->d = strtod(ctx->tmp->str, NULL);
|
||||
}
|
||||
|
||||
sp = " ";
|
||||
|
||||
double = ( (digit | '.')* ) >mark %parsedouble;
|
||||
|
||||
init = "I" sp double sp double sp double sp double sp double sp double sp double sp double ";";
|
||||
|
||||
main := init @ done;
|
||||
}%%
|
||||
|
||||
%% write data;
|
||||
|
||||
static int control_parser_has_error(context *ctx) {
|
||||
return ctx->cs == control_parser_error;
|
||||
}
|
||||
|
||||
static int control_parser_is_finished(context *ctx) {
|
||||
return ctx->cs >= control_parser_first_final;
|
||||
}
|
||||
|
||||
void control_parser_new(trial *t) {
|
||||
context *ctx = t->parse_ctx = g_slice_new(context);
|
||||
%% write init;
|
||||
ctx->buffer = g_string_sized_new(0);
|
||||
ctx->tmp = g_string_sized_new(0);
|
||||
}
|
||||
|
||||
void control_parser_reset(trial *t) {
|
||||
context *ctx = t->parse_ctx;
|
||||
%% write init;
|
||||
g_string_truncate(ctx->tmp, 0);
|
||||
}
|
||||
|
||||
void control_parser_free(trial *t) {
|
||||
g_string_free(t->parse_ctx->buffer, TRUE);
|
||||
g_string_free(t->parse_ctx->tmp, TRUE);
|
||||
g_slice_free(context, t->parse_ctx);
|
||||
}
|
||||
|
||||
run_t control_parse(trial *t) {
|
||||
context *ctx = t->parse_ctx;
|
||||
gsize wehave;
|
||||
|
||||
if (0 < (wehave = ctx->buffer->len - ctx->read)) {
|
||||
char *p, *pe;
|
||||
|
||||
p = ctx->buffer->str + ctx->read;
|
||||
pe = p + wehave;
|
||||
|
||||
%% write exec;
|
||||
|
||||
g_string_erase(ctx->buffer, 0, ctx->read);
|
||||
ctx->mark -= ctx->read;
|
||||
ctx->read = 0;
|
||||
}
|
||||
|
||||
if (control_parser_has_error(ctx)) {
|
||||
fprintf(stderr, "Parse error\n");
|
||||
return RUN_ERROR;
|
||||
}
|
||||
if (control_parser_is_finished(ctx)) return RUN_DONE;
|
||||
return RUN_GO_ON;
|
||||
}
|
@ -6,6 +6,7 @@
|
||||
main_source = '''
|
||||
main.c
|
||||
control.c
|
||||
control_parser.rl
|
||||
'''
|
||||
|
||||
def build(bld):
|
||||
|
2
wscript
2
wscript
@ -79,6 +79,8 @@ def configure(conf):
|
||||
conf.env['CPPPATH_glib'] += [ incdir+'/glib-2.0/', incdir + '/glib-2.0/include/' ]
|
||||
CHECK_INCLUDE_FILES(conf, "glib.h", "HAVE_GLIB_H", uselib = 'glib', use = ['glib'], mandatory = 1)
|
||||
|
||||
conf.write_config_header('src/config.h')
|
||||
|
||||
|
||||
def build(bld):
|
||||
bld.add_subdirs('src')
|
||||
|
Loading…
Reference in New Issue
Block a user