summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthias Schiffer <mschiffer@universe-factory.net>2013-07-26 14:22:18 +0200
committerMatthias Schiffer <mschiffer@universe-factory.net>2013-07-26 14:22:18 +0200
commit0ffde34faac958a28842a952157852fd072834a5 (patch)
tree28a2ccbac9dec9e843bd995a42d1c82f14c4fc6d
parentac9f22678b5db6a63dd3a64313d7123000702733 (diff)
downloadgmrf-0ffde34faac958a28842a952157852fd072834a5.tar
gmrf-0ffde34faac958a28842a952157852fd072834a5.zip
Convert mmss to C++, add parser
-rw-r--r--CMakeLists.txt7
-rw-r--r--FindFLEX.cmake120
-rw-r--r--mmss/CMakeLists.txt21
-rw-r--r--mmss/config.cpp125
-rw-r--r--mmss/config.l129
-rw-r--r--mmss/config.y93
-rw-r--r--mmss/iface.cpp (renamed from mmss/iface.c)8
-rw-r--r--mmss/log.cpp (renamed from mmss/log.c)25
-rw-r--r--mmss/mmss.cpp (renamed from mmss/mmss.c)25
-rw-r--r--mmss/mmss.hpp (renamed from mmss/mmss.h)68
-rw-r--r--mmss/protocol.cpp (renamed from mmss/protocol.c)6
-rw-r--r--mmss/queue.cpp (renamed from mmss/queue.c)8
-rw-r--r--mmss/queue.hpp (renamed from mmss/queue.h)4
-rw-r--r--mmss/schedule.cpp (renamed from mmss/schedule.c)8
-rw-r--r--mmss/types.hpp (renamed from mmss/types.h)7
15 files changed, 608 insertions, 46 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 31d4066..08a9052 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -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)
diff --git a/FindFLEX.cmake b/FindFLEX.cmake
new file mode 100644
index 0000000..fe83369
--- /dev/null
+++ b/FindFLEX.cmake
@@ -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
diff --git a/mmss/CMakeLists.txt b/mmss/CMakeLists.txt
index c200d7a..cd719e0 100644
--- a/mmss/CMakeLists.txt
+++ b/mmss/CMakeLists.txt
@@ -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)
diff --git a/mmss/config.cpp b/mmss/config.cpp
new file mode 100644
index 0000000..0be95fb
--- /dev/null
+++ b/mmss/config.cpp
@@ -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;
+}
diff --git a/mmss/config.l b/mmss/config.l
new file mode 100644
index 0000000..6f20423
--- /dev/null
+++ b/mmss/config.l
@@ -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; }
+%%
diff --git a/mmss/config.y b/mmss/config.y
new file mode 100644
index 0000000..722ce25
--- /dev/null
+++ b/mmss/config.y
@@ -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);
+}
diff --git a/mmss/iface.c b/mmss/iface.cpp
index 6d636ce..441da4a 100644
--- a/mmss/iface.c
+++ b/mmss/iface.cpp
@@ -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;
diff --git a/mmss/log.c b/mmss/log.cpp
index 5599e95..eb2ce03 100644
--- a/mmss/log.c
+++ b/mmss/log.cpp
@@ -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,17 +57,30 @@ static inline const char* get_log_prefix(int log_level) {
}
}
+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] ", mmss->now/1000, mmss->now%1000);
+
+ va_list ap;
+ va_start(ap, format);
+ vsnprintf(buf+pos, sizeof(buf)-pos, format, ap);
+ va_end(ap);
+
+ 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), "[% 5u.%03u] %s: %s", gmrf->mmss->now/1000, gmrf->mmss->now%1000, gmrf->name, get_log_prefix(priority));
+ pos += snprintf_safe(buf, sizeof(buf), "%s: %s", gmrf->name, get_log_prefix(priority));
- va_list ap;
- va_start(ap, format);
+ va_list ap;
+ va_start(ap, format);
vsnprintf(buf+pos, sizeof(buf)-pos, format, ap);
va_end(ap);
- fprintf(stderr, "%s\n", buf);
+ mmss_logf(gmrf->mmss, priority, "%s", buf);
}
diff --git a/mmss/mmss.c b/mmss/mmss.cpp
index a260983..8447e5e 100644
--- a/mmss/mmss.c
+++ b/mmss/mmss.cpp
@@ -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,12 +118,12 @@ 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);
- if(packet)
+ if (packet)
mmss_dispatch(packet);
if (scheduled)
diff --git a/mmss/mmss.h b/mmss/mmss.hpp
index 4b0e206..a2c2fe2 100644
--- a/mmss/mmss.h
+++ b/mmss/mmss.hpp
@@ -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_ */
diff --git a/mmss/protocol.c b/mmss/protocol.cpp
index 046cb58..ace3560 100644
--- a/mmss/protocol.c
+++ b/mmss/protocol.cpp
@@ -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);
diff --git a/mmss/queue.c b/mmss/queue.cpp
index c7c475b..a5d2142 100644
--- a/mmss/queue.c
+++ b/mmss/queue.cpp
@@ -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;
diff --git a/mmss/queue.h b/mmss/queue.hpp
index 6e2648b..d24bff6 100644
--- a/mmss/queue.h
+++ b/mmss/queue.hpp
@@ -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;
diff --git a/mmss/schedule.c b/mmss/schedule.cpp
index 0474613..adebf19 100644
--- a/mmss/schedule.c
+++ b/mmss/schedule.cpp
@@ -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;
}
diff --git a/mmss/types.h b/mmss/types.hpp
index 04c77be..52ace0f 100644
--- a/mmss/types.h
+++ b/mmss/types.hpp
@@ -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_ */