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)
|
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)
|
||||||
add_subdirectory(mmss-protocol)
|
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
|
add_executable(mmss
|
||||||
iface.c
|
config.cpp
|
||||||
log.c
|
iface.cpp
|
||||||
mmss.c
|
log.cpp
|
||||||
protocol.c
|
mmss.cpp
|
||||||
queue.c
|
protocol.cpp
|
||||||
schedule.c
|
queue.cpp
|
||||||
|
schedule.cpp
|
||||||
|
${FLEX_mmss_config_lex_OUTPUTS}
|
||||||
|
${BISON_mmss_config_parse_OUTPUTS}
|
||||||
)
|
)
|
||||||
target_link_libraries(mmss dl)
|
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) {
|
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) {
|
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->sent = mmss->now;
|
||||||
packet->source = source;
|
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) {
|
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->name = strdup(name);
|
||||||
iface->address = *address;
|
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, ...) {
|
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 mmss_logf(mmss_t *mmss, int priority, const char *format, ...) {
|
||||||
void gmrf_logf(gmrf_t *gmrf, int priority, const char *format, ...) {
|
|
||||||
char buf[1024];
|
char buf[1024];
|
||||||
size_t pos = 0;
|
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_list ap;
|
||||||
va_start(ap, format);
|
va_start(ap, format);
|
||||||
|
@ -71,3 +70,17 @@ void gmrf_logf(gmrf_t *gmrf, int priority, const char *format, ...) {
|
||||||
|
|
||||||
fprintf(stderr, "%s\n", buf);
|
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 <cassert>
|
||||||
#include <stdio.h>
|
#include <cstdio>
|
||||||
#include <stdlib.h>
|
#include <cstdlib>
|
||||||
|
|
||||||
|
|
||||||
gmrf_time_t gmrf_now(gmrf_t *gmrf) {
|
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) {
|
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;
|
size_t i;
|
||||||
for (i = 0; i < len; i++)
|
for (i = 0; i < len; i++)
|
||||||
|
@ -78,11 +78,14 @@ int main(int argc, char *argv[]) {
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
mmss_t mmss = { .now = 0 };
|
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 };
|
mmss_network_t net0 = { .mtu = 1500 }, net1 = { .mtu = 1500 };
|
||||||
gmrf_t node1 = { .name = "node1", .mmss = &mmss, .rand_seed = 1, .proto = proto };
|
gmrf_t node1 = { .name = strdup("node1"), .mmss = &mmss, .rand_seed = 1, .proto = proto };
|
||||||
gmrf_t node2 = { .name = "node2", .mmss = &mmss, .rand_seed = 2, .proto = proto };
|
gmrf_t node2 = { .name = strdup("node2"), .mmss = &mmss, .rand_seed = 2, .proto = proto };
|
||||||
gmrf_t node3 = { .name = "node3", .mmss = &mmss, .rand_seed = 3, .proto = proto };
|
gmrf_t node3 = { .name = strdup("node3"), .mmss = &mmss, .rand_seed = 3, .proto = proto };
|
||||||
|
|
||||||
node2.next = &node1;
|
node2.next = &node1;
|
||||||
node3.next = &node2;
|
node3.next = &node2;
|
||||||
|
@ -115,12 +118,12 @@ int main(int argc, char *argv[]) {
|
||||||
assert(timeout == 0);
|
assert(timeout == 0);
|
||||||
|
|
||||||
while (timeout == 0) {
|
while (timeout == 0) {
|
||||||
mmss_packet_t *packet = mmss_queue_get(&mmss, &mmss.packet_queue);
|
mmss_packet_t *packet = reinterpret_cast<mmss_packet_t*>(mmss_queue_get(&mmss, &mmss.packet_queue));
|
||||||
mmss_scheduled_t *scheduled = mmss_queue_get(&mmss, &mmss.scheduled_queue);
|
mmss_scheduled_t *scheduled = reinterpret_cast<mmss_scheduled_t*>(mmss_queue_get(&mmss, &mmss.scheduled_queue));
|
||||||
|
|
||||||
assert(packet || scheduled);
|
assert(packet || scheduled);
|
||||||
|
|
||||||
if(packet)
|
if (packet)
|
||||||
mmss_dispatch(packet);
|
mmss_dispatch(packet);
|
||||||
|
|
||||||
if (scheduled)
|
if (scheduled)
|
|
@ -27,11 +27,17 @@
|
||||||
#ifndef _GMRF_MMSS_MMSS_H_
|
#ifndef _GMRF_MMSS_MMSS_H_
|
||||||
#define _GMRF_MMSS_MMSS_H_
|
#define _GMRF_MMSS_MMSS_H_
|
||||||
|
|
||||||
|
#include "queue.hpp"
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
|
||||||
#include <gmrf/gmrf.h>
|
#include <gmrf/gmrf.h>
|
||||||
#include <mmss/protocol.h>
|
#include <mmss/protocol.h>
|
||||||
|
|
||||||
#include "queue.h"
|
}
|
||||||
|
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
struct mmss {
|
struct mmss {
|
||||||
uint64_t now;
|
uint64_t now;
|
||||||
|
@ -39,11 +45,17 @@ struct mmss {
|
||||||
mmss_queue_t scheduled_queue;
|
mmss_queue_t scheduled_queue;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct mmss_config {
|
||||||
|
mmss_network_t *networks;
|
||||||
|
gmrf_t *nodes;
|
||||||
|
};
|
||||||
|
|
||||||
struct mmss_network {
|
struct mmss_network {
|
||||||
mmss_network_t *next;
|
mmss_network_t *next;
|
||||||
|
|
||||||
gmrf_iface_t *interfaces;
|
char *name;
|
||||||
|
|
||||||
|
gmrf_iface_t *interfaces;
|
||||||
size_t mtu;
|
size_t mtu;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -63,11 +75,16 @@ struct mmss_scheduled {
|
||||||
void *arg;
|
void *arg;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct mmss_string_stack {
|
||||||
|
mmss_string_stack_t *next;
|
||||||
|
char str[];
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
struct gmrf {
|
struct gmrf {
|
||||||
gmrf_t *next;
|
gmrf_t *next;
|
||||||
|
|
||||||
const char *name;
|
char *name;
|
||||||
|
|
||||||
mmss_t *mmss;
|
mmss_t *mmss;
|
||||||
gmrf_context_t *ctx;
|
gmrf_context_t *ctx;
|
||||||
|
@ -92,11 +109,17 @@ struct gmrf_iface {
|
||||||
|
|
||||||
const mmss_protocol_t* mmss_load_protocol(const char *module);
|
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_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_dispatch(mmss_packet_t *packet);
|
||||||
void mmss_run_scheduled(mmss_scheduled_t *scheduled);
|
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) {
|
static inline int max(int a, int b) {
|
||||||
return (a > b) ? a : 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_ */
|
#endif /* _GMRF_MMSS_MMSS_H_ */
|
|
@ -24,10 +24,10 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include "mmss.h"
|
#include "mmss.hpp"
|
||||||
|
|
||||||
#include <dlfcn.h>
|
#include <dlfcn.h>
|
||||||
#include <stdio.h>
|
#include <cstdio>
|
||||||
|
|
||||||
|
|
||||||
const mmss_protocol_t* mmss_load_protocol(const char *module) {
|
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();
|
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) {
|
if (!proto) {
|
||||||
fprintf(stderr, "unable to load protocol from `%s': %s\n", module, dlerror());
|
fprintf(stderr, "unable to load protocol from `%s': %s\n", module, dlerror());
|
||||||
dlclose(handle);
|
dlclose(handle);
|
|
@ -24,10 +24,10 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include "queue.h"
|
#include "queue.hpp"
|
||||||
#include "mmss.h"
|
#include "mmss.hpp"
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <cstdlib>
|
||||||
|
|
||||||
|
|
||||||
typedef struct mmss_queue_entry mmss_queue_entry_t;
|
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)
|
while (*queue && timeout >= (*queue)->timeout)
|
||||||
queue = &(*queue)->next;
|
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->timeout = timeout;
|
||||||
entry->data = data;
|
entry->data = data;
|
|
@ -27,9 +27,9 @@
|
||||||
#ifndef _GMRF_MMSS_QUEUE_H_
|
#ifndef _GMRF_MMSS_QUEUE_H_
|
||||||
#define _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;
|
typedef struct mmss_queue_entry *mmss_queue_t;
|
|
@ -24,13 +24,11 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include "mmss.h"
|
#include "mmss.hpp"
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
|
|
||||||
void gmrf_schedule(gmrf_t *gmrf, gmrf_scheduled_func f, void *arg, unsigned delay) {
|
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->node = gmrf;
|
||||||
scheduled->f = f;
|
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) {
|
void mmss_run_scheduled(mmss_scheduled_t *scheduled) {
|
||||||
scheduled->f(scheduled->node, scheduled->node->ctx, scheduled->arg);
|
scheduled->f(scheduled->node, scheduled->node->ctx, scheduled->arg);
|
||||||
free(scheduled);
|
delete scheduled;
|
||||||
}
|
}
|
|
@ -27,9 +27,16 @@
|
||||||
#ifndef _GMRF_MMSS_TYPES_H_
|
#ifndef _GMRF_MMSS_TYPES_H_
|
||||||
#define _GMRF_MMSS_TYPES_H_
|
#define _GMRF_MMSS_TYPES_H_
|
||||||
|
|
||||||
|
#ifndef _GNU_SOURCE
|
||||||
|
#define _GNU_SOURCE
|
||||||
|
#endif
|
||||||
|
|
||||||
typedef struct mmss mmss_t;
|
typedef struct mmss mmss_t;
|
||||||
|
typedef struct mmss_config mmss_config_t;
|
||||||
typedef struct mmss_network mmss_network_t;
|
typedef struct mmss_network mmss_network_t;
|
||||||
typedef struct mmss_packet mmss_packet_t;
|
typedef struct mmss_packet mmss_packet_t;
|
||||||
typedef struct mmss_scheduled mmss_scheduled_t;
|
typedef struct mmss_scheduled mmss_scheduled_t;
|
||||||
|
|
||||||
|
typedef struct mmss_string_stack mmss_string_stack_t;
|
||||||
|
|
||||||
#endif /* _GMRF_MMSS_TYPES_H_ */
|
#endif /* _GMRF_MMSS_TYPES_H_ */
|
Reference in a new issue