Convert mmss to C++, add parser
This commit is contained in:
parent
ac9f22678b
commit
0ffde34faa
15 changed files with 609 additions and 47 deletions
|
@ -1,5 +1,10 @@
|
|||
cmake_minimum_required(VERSION 2.8.3)
|
||||
project(GMRF C)
|
||||
project(GMRF C CXX)
|
||||
|
||||
set(CMAKE_MODULE_PATH ${GMRF_SOURCE_DIR})
|
||||
|
||||
find_package(BISON 2.5 REQUIRED)
|
||||
find_package(FLEX REQUIRED)
|
||||
|
||||
add_subdirectory(mmss)
|
||||
add_subdirectory(mmss-protocol)
|
||||
|
|
120
FindFLEX.cmake
Normal file
120
FindFLEX.cmake
Normal file
|
@ -0,0 +1,120 @@
|
|||
#=============================================================================
|
||||
# Copyright 2009 Kitware, Inc.
|
||||
# Copyright 2006 Tristan Carel
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions
|
||||
# are met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
#
|
||||
# * Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in the
|
||||
# documentation and/or other materials provided with the distribution.
|
||||
#
|
||||
# * Neither the names of Kitware, Inc., the Insight Software Consortium,
|
||||
# nor the names of their contributors may be used to endorse or promote
|
||||
# products derived from this software without specific prior written
|
||||
# permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
# ------------------------------------------------------------------------------
|
||||
#
|
||||
# The above copyright and license notice applies to distributions of
|
||||
# CMake in source and binary form. Some source files contain additional
|
||||
# notices of original copyright by their contributors; see each source
|
||||
# for details. Third-party software packages supplied with CMake under
|
||||
# compatible licenses provide their own copyright notices documented in
|
||||
# corresponding subdirectories.
|
||||
#=============================================================================
|
||||
|
||||
FIND_PROGRAM(FLEX_EXECUTABLE flex DOC "path to the flex executable")
|
||||
MARK_AS_ADVANCED(FLEX_EXECUTABLE)
|
||||
|
||||
FIND_LIBRARY(FL_LIBRARY NAMES fl
|
||||
DOC "Path to the fl library")
|
||||
|
||||
FIND_PATH(FLEX_INCLUDE_DIR FlexLexer.h
|
||||
DOC "Path to the flex headers")
|
||||
|
||||
MARK_AS_ADVANCED(FL_LIBRARY FLEX_INCLUDE_DIR)
|
||||
|
||||
SET(FLEX_INCLUDE_DIRS ${FLEX_INCLUDE_DIR})
|
||||
SET(FLEX_LIBRARIES ${FL_LIBRARY})
|
||||
|
||||
IF(FLEX_EXECUTABLE)
|
||||
|
||||
EXECUTE_PROCESS(COMMAND ${FLEX_EXECUTABLE} --version
|
||||
OUTPUT_VARIABLE FLEX_version_output
|
||||
ERROR_VARIABLE FLEX_version_error
|
||||
RESULT_VARIABLE FLEX_version_result
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
IF(NOT ${FLEX_version_result} EQUAL 0)
|
||||
IF(FLEX_FIND_REQUIRED)
|
||||
MESSAGE(SEND_ERROR "Command \"${FLEX_EXECUTABLE} --version\" failed with output:\n${FLEX_version_output}\n${FLEX_version_error}")
|
||||
ELSE()
|
||||
MESSAGE("Command \"${FLEX_EXECUTABLE} --version\" failed with output:\n${FLEX_version_output}\n${FLEX_version_error}\nFLEX_VERSION will not be available")
|
||||
ENDIF()
|
||||
ELSE()
|
||||
STRING(REGEX REPLACE "^flex (.*)$" "\\1"
|
||||
FLEX_VERSION "${FLEX_version_output}")
|
||||
ENDIF()
|
||||
|
||||
#============================================================
|
||||
# FLEX_TARGET (public macro)
|
||||
#============================================================
|
||||
#
|
||||
MACRO(FLEX_TARGET Name Input Output)
|
||||
SET(FLEX_TARGET_usage "FLEX_TARGET(<Name> <Input> <Output> [COMPILE_FLAGS <string>]")
|
||||
IF(${ARGC} GREATER 3)
|
||||
IF(${ARGC} EQUAL 5)
|
||||
IF("${ARGV3}" STREQUAL "COMPILE_FLAGS")
|
||||
SET(FLEX_EXECUTABLE_opts "${ARGV4}")
|
||||
SEPARATE_ARGUMENTS(FLEX_EXECUTABLE_opts)
|
||||
ELSE()
|
||||
MESSAGE(SEND_ERROR ${FLEX_TARGET_usage})
|
||||
ENDIF()
|
||||
ELSE()
|
||||
MESSAGE(SEND_ERROR ${FLEX_TARGET_usage})
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
|
||||
STRING(REGEX REPLACE "^(.*)(\\.[^.]*)$" "\\2" _fileext "${Output}")
|
||||
STRING(REPLACE "c" "h" _fileext ${_fileext})
|
||||
STRING(REGEX REPLACE "^(.*)(\\.[^.]*)$" "\\1${_fileext}"
|
||||
OutputHeader "${Output}")
|
||||
|
||||
ADD_CUSTOM_COMMAND(OUTPUT ${Output} ${OutputHeader}
|
||||
COMMAND ${FLEX_EXECUTABLE}
|
||||
ARGS ${FLEX_EXECUTABLE_opts} -o${Output} --header-file=${OutputHeader} ${Input}
|
||||
DEPENDS ${Input}
|
||||
COMMENT "[FLEX][${Name}] Building scanner with flex ${FLEX_VERSION}"
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
|
||||
SET(FLEX_${Name}_DEFINED TRUE)
|
||||
SET(FLEX_${Name}_OUTPUTS ${Output} ${OutputHeader})
|
||||
SET(FLEX_${Name}_OUTPUT_HEADER ${OutputHeader})
|
||||
SET(FLEX_${Name}_INPUT ${Input})
|
||||
SET(FLEX_${Name}_COMPILE_FLAGS ${FLEX_EXECUTABLE_opts})
|
||||
ENDMACRO(FLEX_TARGET)
|
||||
#============================================================
|
||||
|
||||
|
||||
ENDIF(FLEX_EXECUTABLE)
|
||||
|
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(FLEX REQUIRED_VARS FLEX_EXECUTABLE
|
||||
VERSION_VAR FLEX_VERSION)
|
||||
|
||||
# FindFLEX.cmake ends here
|
|
@ -1,11 +1,18 @@
|
|||
include_directories(${GMRF_SOURCE_DIR}/include)
|
||||
include_directories(${GMRF_SOURCE_DIR}/include ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR})
|
||||
|
||||
FLEX_TARGET(mmss_config_lex config.l ${CMAKE_CURRENT_BINARY_DIR}/config.ll.cpp)
|
||||
BISON_TARGET(mmss_config_parse config.y ${CMAKE_CURRENT_BINARY_DIR}/config.yy.cpp)
|
||||
|
||||
add_executable(mmss
|
||||
iface.c
|
||||
log.c
|
||||
mmss.c
|
||||
protocol.c
|
||||
queue.c
|
||||
schedule.c
|
||||
config.cpp
|
||||
iface.cpp
|
||||
log.cpp
|
||||
mmss.cpp
|
||||
protocol.cpp
|
||||
queue.cpp
|
||||
schedule.cpp
|
||||
${FLEX_mmss_config_lex_OUTPUTS}
|
||||
${BISON_mmss_config_parse_OUTPUTS}
|
||||
)
|
||||
target_link_libraries(mmss dl)
|
||||
set_target_properties(mmss PROPERTIES COMPILE_FLAGS -std=c++11)
|
||||
|
|
125
mmss/config.cpp
Normal file
125
mmss/config.cpp
Normal file
|
@ -0,0 +1,125 @@
|
|||
/*
|
||||
Copyright (c) 2013, Matthias Schiffer <mschiffer@universe-factory.net>
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
|
||||
#include "mmss.hpp"
|
||||
#include <config.ll.hpp>
|
||||
#include <config.yy.hpp>
|
||||
|
||||
#include <libgen.h>
|
||||
|
||||
|
||||
void mmss_config_add_network(mmss_t *mmss, mmss_config_t *conf, const char *name) {
|
||||
mmss_logf(mmss, LOG_NOTICE, "Adding network `%s'", name);
|
||||
|
||||
mmss_network_t *net = new mmss_network_t;
|
||||
|
||||
net->name = strdup(name);
|
||||
net->mtu = 1500;
|
||||
|
||||
net->next = conf->networks;
|
||||
conf->networks = net;
|
||||
}
|
||||
|
||||
bool mmss_read_config(mmss_t *mmss, mmss_config_t *conf, const char *filename) {
|
||||
bool ret = true;
|
||||
char *oldcwd = get_current_dir_name();
|
||||
char *filename2 = NULL;
|
||||
char *dir = NULL;
|
||||
FILE *file;
|
||||
yyscan_t scanner;
|
||||
mmss_config_pstate *ps;
|
||||
mmss_string_stack_t *strings = NULL;
|
||||
int token;
|
||||
YYSTYPE token_val;
|
||||
YYLTYPE loc = {1, 0, 1, 0};
|
||||
int parse_ret;
|
||||
|
||||
|
||||
mmss_config_yylex_init(&scanner);
|
||||
ps = mmss_config_pstate_new();
|
||||
|
||||
if (!filename) {
|
||||
file = stdin;
|
||||
}
|
||||
else {
|
||||
file = fopen(filename, "r");
|
||||
if (!file) {
|
||||
mmss_logf(mmss, LOG_ERR, "can't open config file `%s': %s", filename, strerror(errno));
|
||||
ret = false;
|
||||
goto end_free;
|
||||
}
|
||||
}
|
||||
|
||||
mmss_config_yyset_in(file, scanner);
|
||||
|
||||
if (filename) {
|
||||
filename2 = strdup(filename);
|
||||
dir = dirname(filename2);
|
||||
|
||||
if (chdir(dir)) {
|
||||
mmss_logf(mmss, LOG_ERR, "change from directory `%s' to `%s' failed", oldcwd, dir);
|
||||
ret = false;
|
||||
goto end_free;
|
||||
}
|
||||
}
|
||||
|
||||
do {
|
||||
token = mmss_config_yylex(&token_val, &loc, scanner);
|
||||
|
||||
if (token < 0) {
|
||||
mmss_logf(mmss, LOG_ERR, "config error: %s at %s:%i:%i", token_val.error, filename, loc.first_line, loc.first_column);
|
||||
ret = false;
|
||||
goto end_free;
|
||||
}
|
||||
|
||||
if (token == TOK_STRING) {
|
||||
token_val.str->next = strings;
|
||||
strings = token_val.str;
|
||||
}
|
||||
|
||||
parse_ret = mmss_config_push_parse(ps, token, &token_val, &loc, mmss, conf, filename);
|
||||
} while (parse_ret == YYPUSH_MORE);
|
||||
|
||||
if (parse_ret)
|
||||
ret = false;
|
||||
|
||||
end_free:
|
||||
mmss_string_stack_free(strings);
|
||||
|
||||
mmss_config_pstate_delete(ps);
|
||||
mmss_config_yylex_destroy(scanner);
|
||||
|
||||
if(chdir(oldcwd))
|
||||
mmss_logf(mmss, LOG_ERR, "can't chdir to `%s': %s", oldcwd, strerror(errno));
|
||||
|
||||
free(filename2);
|
||||
free(oldcwd);
|
||||
|
||||
if (filename && file)
|
||||
fclose(file);
|
||||
|
||||
return ret;
|
||||
}
|
129
mmss/config.l
Normal file
129
mmss/config.l
Normal file
|
@ -0,0 +1,129 @@
|
|||
/*
|
||||
Copyright (c) 2013, Matthias Schiffer <mschiffer@universe-factory.net>
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
|
||||
%option prefix="mmss_config_yy"
|
||||
%option noyywrap
|
||||
%option nounput
|
||||
%option noinput
|
||||
%option bison-bridge
|
||||
%option bison-locations
|
||||
%option reentrant
|
||||
%option warn
|
||||
|
||||
|
||||
%top {
|
||||
#include <config.yy.hpp>
|
||||
}
|
||||
|
||||
%s NEEDSPACE
|
||||
%s STRING
|
||||
%s COMMENT
|
||||
|
||||
%%
|
||||
%{
|
||||
#define UPDATE_LOCATION do { \
|
||||
yylloc->first_line = yylloc->last_line; \
|
||||
yylloc->first_column = yylloc->last_column+1; \
|
||||
yylloc->last_column += yyleng; \
|
||||
} while (0)
|
||||
|
||||
#define TOKEN(tok) do { UPDATE_LOCATION; BEGIN(NEEDSPACE); return tok; } while (0)
|
||||
%}
|
||||
|
||||
<INITIAL>{
|
||||
[0-9]+ { UPDATE_LOCATION; yylval->num = atoi(yytext); BEGIN(NEEDSPACE); return TOK_INTEGER; }
|
||||
|
||||
yes { TOKEN(TOK_YES); }
|
||||
no { TOKEN(TOK_NO); }
|
||||
network { TOKEN(TOK_NETWORK); }
|
||||
|
||||
[;:\{\}] { UPDATE_LOCATION; return yytext[0]; }
|
||||
|
||||
[ \t] { yylloc->last_column++; }
|
||||
\n { yylloc->last_column = 0; yylloc->last_line++; }
|
||||
\r ;
|
||||
}
|
||||
|
||||
<NEEDSPACE>{
|
||||
[;:\{\}] { UPDATE_LOCATION; BEGIN(INITIAL); return yytext[0]; }
|
||||
|
||||
[ \t] { yylloc->last_column++; BEGIN(INITIAL); }
|
||||
\n { yylloc->last_column = 0; yylloc->last_line++; BEGIN(INITIAL); }
|
||||
\r ;
|
||||
}
|
||||
|
||||
<INITIAL>\" { UPDATE_LOCATION; BEGIN(STRING); }
|
||||
<STRING>[^"\\\n\r] { yylloc->last_column++; yymore(); }
|
||||
<STRING>\n { yylloc->last_line++; yylloc->last_column = 0; yymore(); }
|
||||
<STRING>\r { yymore(); }
|
||||
<STRING>\\. { yylloc->last_column+=2; yymore(); }
|
||||
<STRING>\\\n { yylloc->last_line++; yylloc->last_column = 0; yymore(); }
|
||||
<STRING>\" {
|
||||
int i, esc = 0;
|
||||
|
||||
for (i = 0; i < yyleng; i++) {
|
||||
if (yytext[i] == '\\') {
|
||||
i++;
|
||||
if (yytext[i] == '\n') {
|
||||
esc+=2;
|
||||
}
|
||||
else {
|
||||
yytext[i-esc-1] = yytext[i];
|
||||
esc++;
|
||||
}
|
||||
}
|
||||
else if(esc) {
|
||||
yytext[i-esc] = yytext[i];
|
||||
}
|
||||
}
|
||||
yytext[yyleng-esc-1] = 0;
|
||||
yylval->str = mmss_string_stack_dup(yytext);
|
||||
BEGIN(NEEDSPACE);
|
||||
yylloc->last_column++;
|
||||
return TOK_STRING;
|
||||
|
||||
}
|
||||
|
||||
<INITIAL,NEEDSPACE>#.* { yylloc->last_column += yyleng; }
|
||||
<INITIAL,NEEDSPACE>\/\/.* { yylloc->last_column += yyleng; }
|
||||
|
||||
<INITIAL,NEEDSPACE>\/\* { UPDATE_LOCATION; BEGIN(COMMENT); }
|
||||
<COMMENT>\*\/ { yylloc->last_column += yyleng; BEGIN(INITIAL); }
|
||||
<COMMENT>[^\n\r] { yylloc->last_column++; }
|
||||
<COMMENT>\n { yylloc->last_line++; yylloc->last_column = 0; }
|
||||
<COMMENT>\r {}
|
||||
|
||||
. {
|
||||
yylloc->first_line = yylloc->last_line;
|
||||
yylloc->first_column = yylloc->last_column+1;
|
||||
yylval->error = "syntax error";
|
||||
return -1;
|
||||
}
|
||||
|
||||
<INITIAL><<EOF>> { return 0; }
|
||||
<COMMENT><<EOF>> { yylval->error = "unterminated block comment"; return -1; }
|
||||
<STRING><<EOF>> { yylval->error = "unterminated string"; return -1; }
|
||||
%%
|
93
mmss/config.y
Normal file
93
mmss/config.y
Normal file
|
@ -0,0 +1,93 @@
|
|||
/*
|
||||
Copyright (c) 2013, Matthias Schiffer <mschiffer@universe-factory.net>
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
|
||||
%define api.pure
|
||||
%define api.push-pull push
|
||||
%name-prefix "mmss_config_"
|
||||
%locations
|
||||
%parse-param {mmss_t *mmss}
|
||||
%parse-param {mmss_config_t *conf}
|
||||
%parse-param {const char *filename}
|
||||
|
||||
|
||||
%code requires {
|
||||
#include <mmss.hpp>
|
||||
|
||||
#include <cstdio>
|
||||
}
|
||||
|
||||
%union {
|
||||
int num;
|
||||
mmss_string_stack_t *str;
|
||||
bool boolean;
|
||||
|
||||
const char *error;
|
||||
}
|
||||
|
||||
%token <num> TOK_INTEGER
|
||||
%token <str> TOK_STRING
|
||||
|
||||
%token TOK_NETWORK
|
||||
%token TOK_YES
|
||||
%token TOK_NO
|
||||
|
||||
|
||||
%code {
|
||||
void mmss_config_error(YYLTYPE *loc, mmss_t *mmss, mmss_config_t *conf, const char *filename, const char *s);
|
||||
}
|
||||
|
||||
|
||||
%type <boolean> boolean
|
||||
|
||||
%%
|
||||
|
||||
start: config
|
||||
;
|
||||
|
||||
config: config statement
|
||||
|
|
||||
;
|
||||
|
||||
statement: TOK_NETWORK network '{' network_config '}'
|
||||
;
|
||||
|
||||
network: TOK_STRING {
|
||||
mmss_config_add_network(mmss, conf, $1->str);
|
||||
}
|
||||
;
|
||||
|
||||
network_config:
|
||||
;
|
||||
|
||||
boolean: TOK_YES { $$ = true; }
|
||||
| TOK_NO { $$ = false; }
|
||||
;
|
||||
|
||||
%%
|
||||
|
||||
void mmss_config_error(YYLTYPE *loc, mmss_t *mmss, mmss_config_t *conf, const char *filename, const char *s) {
|
||||
mmss_logf(mmss, LOG_ERR, "config error: %s at %s:%i:%i", s, filename, loc->first_line, loc->first_column);
|
||||
}
|
|
@ -24,9 +24,9 @@
|
|||
*/
|
||||
|
||||
|
||||
#include "mmss.h"
|
||||
#include "mmss.hpp"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <cstdlib>
|
||||
|
||||
|
||||
gmrf_addr_t gmrf_iface_get_addr(gmrf_t *gmrf, gmrf_iface_t *iface) {
|
||||
|
@ -42,7 +42,7 @@ size_t gmrf_iface_get_mtu(gmrf_t *gmrf, gmrf_iface_t *iface) {
|
|||
}
|
||||
|
||||
static void enqueue(mmss_t *mmss, gmrf_iface_t *source, gmrf_iface_t *dest, const void *data, size_t len) {
|
||||
mmss_packet_t *packet = calloc(1, sizeof(mmss_packet_t) + len);
|
||||
mmss_packet_t *packet = reinterpret_cast<mmss_packet_t*>(calloc(1, sizeof(mmss_packet_t) + len));
|
||||
|
||||
packet->sent = mmss->now;
|
||||
packet->source = source;
|
||||
|
@ -82,7 +82,7 @@ void mmss_dispatch(mmss_packet_t *packet) {
|
|||
}
|
||||
|
||||
void mmss_add_iface(gmrf_t *node, mmss_network_t *net, const char *name, const gmrf_addr_t *address) {
|
||||
gmrf_iface_t *iface = calloc(1, sizeof(gmrf_iface_t));
|
||||
gmrf_iface_t *iface = new gmrf_iface_t;
|
||||
|
||||
iface->name = strdup(name);
|
||||
iface->address = *address;
|
|
@ -24,9 +24,9 @@
|
|||
*/
|
||||
|
||||
|
||||
#include "mmss.h"
|
||||
#include "mmss.hpp"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <cstdio>
|
||||
|
||||
|
||||
static inline int snprintf_safe(char *buffer, size_t size, const char *format, ...) {
|
||||
|
@ -57,12 +57,11 @@ static inline const char* get_log_prefix(int log_level) {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
void gmrf_logf(gmrf_t *gmrf, int priority, const char *format, ...) {
|
||||
void mmss_logf(mmss_t *mmss, int priority, const char *format, ...) {
|
||||
char buf[1024];
|
||||
size_t pos = 0;
|
||||
|
||||
pos += snprintf_safe(buf, sizeof(buf), "[% 5u.%03u] %s: %s", gmrf->mmss->now/1000, gmrf->mmss->now%1000, gmrf->name, get_log_prefix(priority));
|
||||
pos += snprintf_safe(buf, sizeof(buf), "[% 5u.%03u] ", mmss->now/1000, mmss->now%1000);
|
||||
|
||||
va_list ap;
|
||||
va_start(ap, format);
|
||||
|
@ -71,3 +70,17 @@ void gmrf_logf(gmrf_t *gmrf, int priority, const char *format, ...) {
|
|||
|
||||
fprintf(stderr, "%s\n", buf);
|
||||
}
|
||||
|
||||
void gmrf_logf(gmrf_t *gmrf, int priority, const char *format, ...) {
|
||||
char buf[1024];
|
||||
size_t pos = 0;
|
||||
|
||||
pos += snprintf_safe(buf, sizeof(buf), "%s: %s", gmrf->name, get_log_prefix(priority));
|
||||
|
||||
va_list ap;
|
||||
va_start(ap, format);
|
||||
vsnprintf(buf+pos, sizeof(buf)-pos, format, ap);
|
||||
va_end(ap);
|
||||
|
||||
mmss_logf(gmrf->mmss, priority, "%s", buf);
|
||||
}
|
|
@ -24,11 +24,11 @@
|
|||
*/
|
||||
|
||||
|
||||
#include "mmss.h"
|
||||
#include "mmss.hpp"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <cassert>
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
|
||||
|
||||
gmrf_time_t gmrf_now(gmrf_t *gmrf) {
|
||||
|
@ -36,7 +36,7 @@ gmrf_time_t gmrf_now(gmrf_t *gmrf) {
|
|||
}
|
||||
|
||||
void gmrf_random_bytes(gmrf_t *gmrf, void *buffer, size_t len) {
|
||||
uint8_t *data = buffer;
|
||||
uint8_t *data = reinterpret_cast<uint8_t*>(buffer);
|
||||
|
||||
size_t i;
|
||||
for (i = 0; i < len; i++)
|
||||
|
@ -78,11 +78,14 @@ int main(int argc, char *argv[]) {
|
|||
return 1;
|
||||
|
||||
mmss_t mmss = { .now = 0 };
|
||||
mmss_config_t conf = {};
|
||||
|
||||
mmss_read_config(&mmss, &conf, "babel_test.mmss");
|
||||
|
||||
mmss_network_t net0 = { .mtu = 1500 }, net1 = { .mtu = 1500 };
|
||||
gmrf_t node1 = { .name = "node1", .mmss = &mmss, .rand_seed = 1, .proto = proto };
|
||||
gmrf_t node2 = { .name = "node2", .mmss = &mmss, .rand_seed = 2, .proto = proto };
|
||||
gmrf_t node3 = { .name = "node3", .mmss = &mmss, .rand_seed = 3, .proto = proto };
|
||||
gmrf_t node1 = { .name = strdup("node1"), .mmss = &mmss, .rand_seed = 1, .proto = proto };
|
||||
gmrf_t node2 = { .name = strdup("node2"), .mmss = &mmss, .rand_seed = 2, .proto = proto };
|
||||
gmrf_t node3 = { .name = strdup("node3"), .mmss = &mmss, .rand_seed = 3, .proto = proto };
|
||||
|
||||
node2.next = &node1;
|
||||
node3.next = &node2;
|
||||
|
@ -115,8 +118,8 @@ int main(int argc, char *argv[]) {
|
|||
assert(timeout == 0);
|
||||
|
||||
while (timeout == 0) {
|
||||
mmss_packet_t *packet = mmss_queue_get(&mmss, &mmss.packet_queue);
|
||||
mmss_scheduled_t *scheduled = mmss_queue_get(&mmss, &mmss.scheduled_queue);
|
||||
mmss_packet_t *packet = reinterpret_cast<mmss_packet_t*>(mmss_queue_get(&mmss, &mmss.packet_queue));
|
||||
mmss_scheduled_t *scheduled = reinterpret_cast<mmss_scheduled_t*>(mmss_queue_get(&mmss, &mmss.scheduled_queue));
|
||||
|
||||
assert(packet || scheduled);
|
||||
|
|
@ -27,11 +27,17 @@
|
|||
#ifndef _GMRF_MMSS_MMSS_H_
|
||||
#define _GMRF_MMSS_MMSS_H_
|
||||
|
||||
#include "queue.hpp"
|
||||
|
||||
extern "C" {
|
||||
|
||||
#include <gmrf/gmrf.h>
|
||||
#include <mmss/protocol.h>
|
||||
|
||||
#include "queue.h"
|
||||
}
|
||||
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
|
||||
struct mmss {
|
||||
uint64_t now;
|
||||
|
@ -39,11 +45,17 @@ struct mmss {
|
|||
mmss_queue_t scheduled_queue;
|
||||
};
|
||||
|
||||
struct mmss_config {
|
||||
mmss_network_t *networks;
|
||||
gmrf_t *nodes;
|
||||
};
|
||||
|
||||
struct mmss_network {
|
||||
mmss_network_t *next;
|
||||
|
||||
gmrf_iface_t *interfaces;
|
||||
char *name;
|
||||
|
||||
gmrf_iface_t *interfaces;
|
||||
size_t mtu;
|
||||
};
|
||||
|
||||
|
@ -63,11 +75,16 @@ struct mmss_scheduled {
|
|||
void *arg;
|
||||
};
|
||||
|
||||
struct mmss_string_stack {
|
||||
mmss_string_stack_t *next;
|
||||
char str[];
|
||||
};
|
||||
|
||||
|
||||
struct gmrf {
|
||||
gmrf_t *next;
|
||||
|
||||
const char *name;
|
||||
char *name;
|
||||
|
||||
mmss_t *mmss;
|
||||
gmrf_context_t *ctx;
|
||||
|
@ -92,11 +109,17 @@ struct gmrf_iface {
|
|||
|
||||
const mmss_protocol_t* mmss_load_protocol(const char *module);
|
||||
|
||||
void mmss_config_add_network(mmss_t *mmss, mmss_config_t *conf, const char *name);
|
||||
|
||||
bool mmss_read_config(mmss_t *mmss, mmss_config_t *conf, const char *filename);
|
||||
|
||||
void mmss_add_iface(gmrf_t *node, mmss_network_t *net, const char *name, const gmrf_addr_t *address);
|
||||
|
||||
void mmss_dispatch(mmss_packet_t *packet);
|
||||
void mmss_run_scheduled(mmss_scheduled_t *scheduled);
|
||||
|
||||
void mmss_logf(mmss_t *mmss, int priority, const char *format, ...);
|
||||
|
||||
|
||||
static inline int max(int a, int b) {
|
||||
return (a > b) ? a : b;
|
||||
|
@ -107,4 +130,43 @@ static inline int min(int a, int b) {
|
|||
}
|
||||
|
||||
|
||||
static inline size_t alignto(size_t l, size_t a) {
|
||||
return ((l+a-1)/a)*a;
|
||||
}
|
||||
|
||||
static inline mmss_string_stack_t* mmss_string_stack_dup(const char *str) {
|
||||
mmss_string_stack_t *ret = reinterpret_cast<mmss_string_stack_t*>(std::malloc(alignto(sizeof(mmss_string_stack_t) + strlen(str) + 1, 8)));
|
||||
ret->next = NULL;
|
||||
std::strcpy(ret->str, str);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline mmss_string_stack_t* mmss_string_stack_dupn(const char *str, size_t len) {
|
||||
size_t str_len = strnlen(str, len);
|
||||
mmss_string_stack_t *ret = reinterpret_cast<mmss_string_stack_t*>(std::malloc(alignto(sizeof(mmss_string_stack_t) + str_len + 1, 8)));
|
||||
ret->next = NULL;
|
||||
std::strncpy(ret->str, str, str_len);
|
||||
ret->str[str_len] = 0;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline mmss_string_stack_t* mmss_string_stack_push(mmss_string_stack_t *stack, const char *str) {
|
||||
mmss_string_stack_t *ret = reinterpret_cast<mmss_string_stack_t*>(std::malloc(alignto(sizeof(mmss_string_stack_t) + strlen(str) + 1, 8)));
|
||||
ret->next = stack;
|
||||
std::strcpy(ret->str, str);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline void mmss_string_stack_free(mmss_string_stack_t *str) {
|
||||
while(str) {
|
||||
mmss_string_stack_t *next = str->next;
|
||||
std::free(str);
|
||||
str = next;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif /* _GMRF_MMSS_MMSS_H_ */
|
|
@ -24,10 +24,10 @@
|
|||
*/
|
||||
|
||||
|
||||
#include "mmss.h"
|
||||
#include "mmss.hpp"
|
||||
|
||||
#include <dlfcn.h>
|
||||
#include <stdio.h>
|
||||
#include <cstdio>
|
||||
|
||||
|
||||
const mmss_protocol_t* mmss_load_protocol(const char *module) {
|
||||
|
@ -38,7 +38,7 @@ const mmss_protocol_t* mmss_load_protocol(const char *module) {
|
|||
}
|
||||
|
||||
dlerror();
|
||||
const mmss_protocol_t *proto = dlsym(handle, "mmss_protocol_info");
|
||||
const mmss_protocol_t *proto = reinterpret_cast<const mmss_protocol_t*>(dlsym(handle, "mmss_protocol_info"));
|
||||
if (!proto) {
|
||||
fprintf(stderr, "unable to load protocol from `%s': %s\n", module, dlerror());
|
||||
dlclose(handle);
|
|
@ -24,10 +24,10 @@
|
|||
*/
|
||||
|
||||
|
||||
#include "queue.h"
|
||||
#include "mmss.h"
|
||||
#include "queue.hpp"
|
||||
#include "mmss.hpp"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <cstdlib>
|
||||
|
||||
|
||||
typedef struct mmss_queue_entry mmss_queue_entry_t;
|
||||
|
@ -43,7 +43,7 @@ void mmss_queue_put(mmss_t *mmss, mmss_queue_t *queue, void *data, uint64_t time
|
|||
while (*queue && timeout >= (*queue)->timeout)
|
||||
queue = &(*queue)->next;
|
||||
|
||||
mmss_queue_entry_t *entry = malloc(sizeof(mmss_queue_entry_t));
|
||||
mmss_queue_entry_t *entry = new mmss_queue_entry_t;
|
||||
|
||||
entry->timeout = timeout;
|
||||
entry->data = data;
|
|
@ -27,9 +27,9 @@
|
|||
#ifndef _GMRF_MMSS_QUEUE_H_
|
||||
#define _GMRF_MMSS_QUEUE_H_
|
||||
|
||||
#include <stdint.h>
|
||||
#include "types.hpp"
|
||||
|
||||
#include "types.h"
|
||||
#include <cstdint>
|
||||
|
||||
|
||||
typedef struct mmss_queue_entry *mmss_queue_t;
|
|
@ -24,13 +24,11 @@
|
|||
*/
|
||||
|
||||
|
||||
#include "mmss.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "mmss.hpp"
|
||||
|
||||
|
||||
void gmrf_schedule(gmrf_t *gmrf, gmrf_scheduled_func f, void *arg, unsigned delay) {
|
||||
mmss_scheduled_t *scheduled = calloc(1, sizeof(mmss_scheduled_t));
|
||||
mmss_scheduled_t *scheduled = new mmss_scheduled_t;
|
||||
|
||||
scheduled->node = gmrf;
|
||||
scheduled->f = f;
|
||||
|
@ -41,5 +39,5 @@ void gmrf_schedule(gmrf_t *gmrf, gmrf_scheduled_func f, void *arg, unsigned dela
|
|||
|
||||
void mmss_run_scheduled(mmss_scheduled_t *scheduled) {
|
||||
scheduled->f(scheduled->node, scheduled->node->ctx, scheduled->arg);
|
||||
free(scheduled);
|
||||
delete scheduled;
|
||||
}
|
|
@ -27,9 +27,16 @@
|
|||
#ifndef _GMRF_MMSS_TYPES_H_
|
||||
#define _GMRF_MMSS_TYPES_H_
|
||||
|
||||
#ifndef _GNU_SOURCE
|
||||
#define _GNU_SOURCE
|
||||
#endif
|
||||
|
||||
typedef struct mmss mmss_t;
|
||||
typedef struct mmss_config mmss_config_t;
|
||||
typedef struct mmss_network mmss_network_t;
|
||||
typedef struct mmss_packet mmss_packet_t;
|
||||
typedef struct mmss_scheduled mmss_scheduled_t;
|
||||
|
||||
typedef struct mmss_string_stack mmss_string_stack_t;
|
||||
|
||||
#endif /* _GMRF_MMSS_TYPES_H_ */
|
Reference in a new issue