Commit 818f9a68 authored by Simon Morlat's avatar Simon Morlat

Add facility to connect parser to C function taking const char* and other structs.

Add corresponding test.
parent 3469391a
......@@ -302,6 +302,21 @@ inline std::function< _retT (_arg1T,_arg2T)> make_fn(_retT (*arg)(_arg1T,_arg2T)
return std::function< _retT (_arg1T,_arg2T)>(arg);
}
template <typename _retT, typename _arg1T>
struct StringToCharMapper{
StringToCharMapper(const std::function< _retT (_arg1T, const char*)> &cfunc) : mCFunc(cfunc){
}
std::function< _retT (_arg1T, const char*)> mCFunc;
_retT operator()(_arg1T arg1, const std::string & arg2){
return mCFunc(arg1, arg2.c_str());
}
};
template <typename _retT, typename _arg1T>
inline std::function< _retT (_arg1T, const std::string &)> make_fn(_retT (*arg)(_arg1T, const char*)){
return StringToCharMapper<_retT, _arg1T>(arg);
}
template <typename _klassT, typename _argT>
inline std::function< void (_klassT*,_argT)> make_fn(void (_klassT::*arg)(_argT)){
return std::function< void (_klassT*,_argT)>(std::mem_fn(arg));
......
......@@ -40,6 +40,7 @@ set(HEADER_FILES_CXX belr-tester.h)
set(SOURCE_FILES_CXX
belr-tester.cpp
grammar-tester.cpp
parser.cpp
)
string(REPLACE ";" " " LINK_FLAGS_STR "${LINK_FLAGS}")
......
......@@ -19,6 +19,12 @@
#include "belr-tester.h"
#include "bctoolbox/logging.h"
#include <fstream>
#include <sstream>
using namespace::std;
namespace belr{
std::string bcTesterFile(const std::string &name){
char *file = bc_tester_file(name.c_str());
......@@ -34,6 +40,22 @@ std::string bcTesterRes(const std::string &name){
return ret;
}
std::string openFile(const std::string &name) {
std::ifstream istr(name, std::ios::binary);
if (!istr.is_open()) {
bctbx_error("Fail to open %s", name.c_str());
BC_FAIL("Fail to open file");
return "";
}
std::stringstream tmpStream;
tmpStream << istr.rdbuf();
return tmpStream.str();;
}
}
int main(int argc, char *argv[]) {
int i;
......@@ -41,13 +63,17 @@ int main(int argc, char *argv[]) {
belr_tester_init(NULL);
if (strstr(argv[0], ".libs")) {
int prefix_length = (int)(strstr(argv[0], ".libs") - argv[0]) + 1;
char prefix[200] = { 0 };
snprintf(prefix, sizeof(prefix)-1, "%s%.*s", argv[0][0] == '/' ? "" : "./", prefix_length, argv[0]);
bc_tester_set_resource_dir_prefix(prefix);
bc_tester_set_writable_dir_prefix(prefix);
char *dirname = bctbx_dirname(argv[0]);
std::string resDir = string(dirname) + "/../share/belr-tester/res/";
std::string testResource = resDir + "sipgrammar.txt";
bctbx_free(dirname);
if (bctbx_file_exist(testResource.c_str()) == 0){
bc_tester_set_resource_dir_prefix(resDir.c_str());
printf("Resource dir set to %s\n", resDir.c_str());
}else{
bc_tester_set_resource_dir_prefix("./res");
}
bc_tester_set_writable_dir_prefix("./");
for(i = 1; i < argc; ++i) {
int ret = bc_tester_parse_args(argc, argv, i);
......@@ -84,6 +110,7 @@ void belr_tester_init(void(*ftester_printf)(int level, const char *fmt, va_list
bc_tester_init(ftester_printf, BCTBX_LOG_MESSAGE, BCTBX_LOG_ERROR, ".");
bc_tester_add_suite(&grammar_suite);
bc_tester_add_suite(&parser_suite);
}
......
......@@ -35,14 +35,18 @@
#include <chrono>
namespace belr{
std::string bcTesterFile(const std::string &name);
std::string bcTesterRes(const std::string &name);
std::string openFile(const std::string &name);
}
#ifdef __cplusplus
extern "C" {
#endif
extern test_suite_t grammar_suite;
extern test_suite_t parser_suite;
void belr_tester_init(void(*ftester_printf)(int level, const char *fmt, va_list args));
......
......@@ -19,21 +19,11 @@
#include "belr-tester.h"
#include <cstdio>
#include "bctoolbox/logging.h"
using namespace::std;
using namespace::belr;
static string openFile(const string &name) {
ifstream istr(name, std::ios::binary);
if (!istr.is_open()) {
BC_FAIL(name);
}
stringstream tmpStream;
tmpStream << istr.rdbuf();
string tmp = tmpStream.str();
return tmp;
}
static bool parseMessage(shared_ptr<Grammar> grammar, const string &message) {
shared_ptr<DebugParser> parser = make_shared<DebugParser>(grammar);
......@@ -51,9 +41,9 @@ static bool parseMessage(shared_ptr<Grammar> grammar, const string &message) {
static void sipgrammar_save_and_load(void) {
string grammarToParse = bcTesterRes("res/sipgrammar.txt");
string grammarToParse = bcTesterRes("sipgrammar.txt");
string grammarDump = bcTesterFile("grammarDump.bin");
string sipmessage = openFile(bcTesterRes("res/register.txt"));
string sipmessage = openFile(bcTesterRes("register.txt"));
remove(grammarDump.c_str());
......@@ -98,8 +88,8 @@ static void sipgrammar_save_and_load(void) {
* with a parser handler, as the recognizer behind it was named "token".
*/
static void aliases_rules(void) {
string grammarToParse = bcTesterRes("res/sipgrammar.txt");
string sipmessage = openFile(bcTesterRes("res/response.txt"));
string grammarToParse = bcTesterRes("sipgrammar.txt");
string sipmessage = openFile(bcTesterRes("response.txt"));
BC_ASSERT_TRUE(sipmessage.size() > 0);
......
/*
* Copyright (c) 2016-2019 Belledonne Communications SARL.
*
* This file is part of belr - a language recognition library for ABNF-defined grammars.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "belr-tester.h"
#include <cstdio>
using namespace::std;
using namespace::belr;
typedef struct sip_uri{
char *user;
char *host;
} sip_uri_t;
typedef struct sip_response{
sip_uri_t *from;
sip_uri_t *to;
}sip_response_t;
sip_uri_t * sip_uri_create(void){
return bctbx_new0(sip_uri_t, 1);
}
void sip_uri_set_user(sip_uri_t *uri, const char *user){
uri->user = bctbx_strdup(user);
}
void sip_uri_set_host(sip_uri_t *uri, const char *host){
uri->host = bctbx_strdup(host);
}
void sip_uri_destroy(sip_uri_t *uri){
if (uri->host) bctbx_free(uri->host);
if (uri->user) bctbx_free(uri->user);
bctbx_free(uri);
}
sip_response_t * sip_response_create(void){
return bctbx_new0(sip_response_t, 1);
}
void sip_response_set_from(sip_response_t *resp, sip_uri_t *uri){
resp->from = uri;
}
void sip_response_set_to(sip_response_t *resp, sip_uri_t *uri){
resp->to = uri;
}
void sip_response_destroy(sip_response_t *resp){
if (resp->from) sip_uri_destroy(resp->from);
if (resp->to) sip_uri_destroy(resp->to);
bctbx_free(resp);
}
static void parser_connected_to_c_functions(void) {
string grammarToParse = bcTesterRes("sipgrammar.txt");
string sipmessage = openFile(bcTesterRes("response.txt"));
BC_ASSERT_TRUE(sipmessage.size() > 0);
ABNFGrammarBuilder builder;
//Read grammar put it in object grammar
shared_ptr<Grammar> grammar=builder.createFromAbnfFile(grammarToParse, make_shared<CoreRules>());
BC_ASSERT_FALSE(!grammar);
if (!grammar) return;
shared_ptr<Parser<void*>> parser = make_shared<Parser<void*>>(grammar);
parser->setHandler("response", make_fn(&sip_response_create))
->setCollector("from", make_fn(&sip_response_set_from))
->setCollector("to", make_fn(&sip_response_set_to));
parser->setHandler("from", make_fn(&sip_uri_create))
->setCollector("user", make_fn(&sip_uri_set_user))
->setCollector("host", make_fn(&sip_uri_set_host));
parser->setHandler("to", make_fn(&sip_uri_create))
->setCollector("user", make_fn(&sip_uri_set_user))
->setCollector("host", make_fn(&sip_uri_set_host));
size_t pos = 0;
void * elem = parser->parseInput("response", sipmessage, &pos);
BC_ASSERT_PTR_NOT_NULL(elem);
if (!elem) return;
BC_ASSERT_EQUAL(pos, sipmessage.size(), int, "%i");
sip_response_t *resp = (sip_response_t*)elem;
sip_uri_t *from = resp->from;
sip_uri_t *to = resp->to;
BC_ASSERT_PTR_NOT_NULL(from);
BC_ASSERT_PTR_NOT_NULL(to);
if (from && to){
BC_ASSERT_STRING_EQUAL(from->user, "smorlat2");
BC_ASSERT_STRING_EQUAL(to->user, "smorlat2");
BC_ASSERT_STRING_EQUAL(from->host, "siptest.linphone.org");
BC_ASSERT_STRING_EQUAL(to->host, "siptest.linphone.org");
}
sip_response_destroy(resp);
}
static test_t tests[] = {
TEST_NO_TAG("Parser connected to C functions", parser_connected_to_c_functions),
};
test_suite_t parser_suite = {
"Parser",
NULL,
NULL,
NULL,
NULL,
sizeof(tests) / sizeof(tests[0]),
tests
};
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment