Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
What's new
10
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Open sidebar
BC
public
belr
Commits
818f9a68
Commit
818f9a68
authored
Oct 15, 2020
by
Simon Morlat
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add facility to connect parser to C function taking const char* and other structs.
Add corresponding test.
parent
3469391a
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
195 additions
and
21 deletions
+195
-21
include/belr/parser.h
include/belr/parser.h
+15
-0
tester/CMakeLists.txt
tester/CMakeLists.txt
+1
-0
tester/belr-tester.cpp
tester/belr-tester.cpp
+33
-6
tester/belr-tester.h
tester/belr-tester.h
+4
-0
tester/grammar-tester.cpp
tester/grammar-tester.cpp
+5
-15
tester/parser.cpp
tester/parser.cpp
+137
-0
No files found.
include/belr/parser.h
View file @
818f9a68
...
...
@@ -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
));
...
...
tester/CMakeLists.txt
View file @
818f9a68
...
...
@@ -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
}
"
)
...
...
tester/belr-tester.cpp
View file @
818f9a68
...
...
@@ -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
);
}
...
...
tester/belr-tester.h
View file @
818f9a68
...
...
@@ -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
));
...
...
tester/grammar-tester.cpp
View file @
818f9a68
...
...
@@ -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
);
...
...
tester/parser.cpp
0 → 100644
View file @
818f9a68
/*
* 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
};
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment