Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
A
Actor Framework
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
cpp-libs
Actor Framework
Commits
83e9248d
Commit
83e9248d
authored
Jun 16, 2018
by
Dominik Charousset
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Remove obsolete code
parent
b1a512e2
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
0 additions
and
591 deletions
+0
-591
libcaf_core/CMakeLists.txt
libcaf_core/CMakeLists.txt
+0
-1
libcaf_core/caf/detail/parse_ini.hpp
libcaf_core/caf/detail/parse_ini.hpp
+0
-57
libcaf_core/src/parse_ini.cpp
libcaf_core/src/parse_ini.cpp
+0
-234
libcaf_core/test/parse_ini.cpp
libcaf_core/test/parse_ini.cpp
+0
-299
No files found.
libcaf_core/CMakeLists.txt
View file @
83e9248d
...
@@ -77,7 +77,6 @@ set(LIBCAF_CORE_SRCS
...
@@ -77,7 +77,6 @@ set(LIBCAF_CORE_SRCS
src/monitorable_actor.cpp
src/monitorable_actor.cpp
src/node_id.cpp
src/node_id.cpp
src/outbound_path.cpp
src/outbound_path.cpp
src/parse_ini.cpp
src/pec.cpp
src/pec.cpp
src/pretty_type_name.cpp
src/pretty_type_name.cpp
src/private_thread.cpp
src/private_thread.cpp
...
...
libcaf_core/caf/detail/parse_ini.hpp
deleted
100644 → 0
View file @
b1a512e2
/******************************************************************************
* ____ _ _____ *
* / ___| / \ | ___| C++ *
* | | / _ \ | |_ Actor *
* | |___ / ___ \| _| Framework *
* \____/_/ \_|_| *
* *
* Copyright 2011-2018 Dominik Charousset *
* *
* Distributed under the terms and conditions of the BSD 3-Clause License or *
* (at your option) under the terms and conditions of the Boost Software *
* License 1.0. See accompanying files LICENSE and LICENSE_ALTERNATIVE. *
* *
* If you did not receive a copy of the license files, see *
* http://opensource.org/licenses/BSD-3-Clause and *
* http://www.boost.org/LICENSE_1_0.txt. *
******************************************************************************/
#pragma once
#include <string>
#include <istream>
#include <functional>
#include "caf/atom.hpp"
#include "caf/variant.hpp"
#include "caf/optional.hpp"
#include "caf/config_value.hpp"
namespace
caf
{
namespace
detail
{
struct
parse_ini_t
{
/// Denotes an optional error output stream
using
opt_err
=
optional
<
std
::
ostream
&>
;
/// Denotes a callback for consuming configuration values.
using
config_consumer
=
std
::
function
<
bool
(
size_t
,
std
::
string
,
config_value
&
,
opt_err
)
>
;
/// Parse the given input stream as INI formatted data and
/// calls the consumer with every key-value pair.
/// @param input Input stream of INI formatted text.
/// @param consumer_fun Callback consuming generated key-value pairs.
/// @param errors Output stream for parser errors.
void
operator
()(
std
::
istream
&
input
,
const
config_consumer
&
consumer_fun
,
opt_err
errors
=
none
)
const
;
};
constexpr
parse_ini_t
parse_ini
=
parse_ini_t
{};
}
// namespace detail
}
// namespace caf
libcaf_core/src/parse_ini.cpp
deleted
100644 → 0
View file @
b1a512e2
/******************************************************************************
* ____ _ _____ *
* / ___| / \ | ___| C++ *
* | | / _ \ | |_ Actor *
* | |___ / ___ \| _| Framework *
* \____/_/ \_|_| *
* *
* Copyright 2011-2018 Dominik Charousset *
* *
* Distributed under the terms and conditions of the BSD 3-Clause License or *
* (at your option) under the terms and conditions of the Boost Software *
* License 1.0. See accompanying files LICENSE and LICENSE_ALTERNATIVE. *
* *
* If you did not receive a copy of the license files, see *
* http://opensource.org/licenses/BSD-3-Clause and *
* http://www.boost.org/LICENSE_1_0.txt. *
******************************************************************************/
#include "caf/detail/parse_ini.hpp"
#include <string>
#include <vector>
#include <iostream>
#include <algorithm>
namespace
caf
{
namespace
detail
{
namespace
{
// TODO: replace with generic lambda when switching to C++14
// Wraps a temporary into an (lvalue) config_value and calls `consumer_fun`.
struct
consumer_t
{
const
parse_ini_t
::
config_consumer
&
consumer_fun
;
parse_ini_t
::
opt_err
&
errors
;
template
<
class
T
>
void
operator
()(
size_t
ln
,
std
::
string
name
,
T
&&
x
)
{
config_value
tmp
{
std
::
forward
<
T
>
(
x
)};
consumer_fun
(
ln
,
std
::
move
(
name
),
tmp
,
errors
);
}
};
}
// namespace <anonymous>
void
parse_ini_t
::
operator
()(
std
::
istream
&
input
,
const
config_consumer
&
consumer_fun
,
opt_err
errors
)
const
{
consumer_t
consumer
{
consumer_fun
,
errors
};
std
::
string
group
;
std
::
string
line
;
size_t
ln
=
0
;
// line number
auto
print
=
[
&
](
const
char
*
category
,
const
char
*
str
)
{
if
(
errors
)
*
errors
<<
category
<<
" INI file line "
<<
ln
<<
": "
<<
str
<<
std
::
endl
;
};
auto
print_error
=
[
&
](
const
char
*
str
)
{
print
(
"[ERROR]"
,
str
);
};
auto
print_warning
=
[
&
](
const
char
*
str
)
{
print
(
"[WARNING]"
,
str
);
};
while
(
std
::
getline
(
input
,
line
))
{
++
ln
;
// get begin-of-line (bol) and end-of-line (eol), ignoring whitespaces
auto
eol
=
find_if_not
(
line
.
rbegin
(),
line
.
rend
(),
::
isspace
).
base
();
auto
bol
=
find_if_not
(
line
.
begin
(),
eol
,
::
isspace
);
// ignore empty lines and lines starting with ';' (comment)
if
(
bol
==
eol
||
*
bol
==
';'
)
continue
;
// do we read a group name?
if
(
*
bol
==
'['
)
{
if
(
*
(
eol
-
1
)
!=
']'
)
print_error
(
"missing ] at end of line"
);
else
group
.
assign
(
bol
+
1
,
eol
-
1
);
// skip further processing of this line
continue
;
}
// do we have a group name yet? (prohibit ungrouped values)
if
(
group
.
empty
())
{
print_error
(
"value outside of a group"
);
continue
;
}
// position of the equal sign
auto
eqs
=
find
(
bol
,
eol
,
'='
);
if
(
eqs
==
eol
)
{
print_error
(
"no '=' found"
);
continue
;
}
if
(
bol
==
eqs
)
{
print_error
(
"line starting with '='"
);
continue
;
}
if
((
eqs
+
1
)
==
eol
)
{
print_error
(
"line ends with '='"
);
continue
;
}
// our keys have the format "<group>.<config-name>"
auto
key
=
group
;
key
+=
'.'
;
// ignore any whitespace between config-name and equal sign
key
.
insert
(
key
.
end
(),
bol
,
find_if
(
bol
,
eqs
,
::
isspace
));
// begin-of-value, ignoring whitespaces after '='
auto
bov
=
find_if_not
(
eqs
+
1
,
eol
,
::
isspace
);
// auto-detect what we are dealing with
auto
icase_eq
=
[](
char
x
,
char
y
)
{
return
tolower
(
x
)
==
tolower
(
y
);
};
if
(
std
::
equal
(
bov
,
eol
,
"true"
,
icase_eq
))
{
consumer
(
ln
,
std
::
move
(
key
),
true
);
}
else
if
(
std
::
equal
(
bov
,
eol
,
"false"
,
icase_eq
))
{
consumer
(
ln
,
std
::
move
(
key
),
false
);
}
else
if
(
*
bov
==
'\''
)
{
// end-of-atom iterator
auto
eoa
=
eol
-
1
;
if
(
bov
==
eoa
)
{
print_error
(
"stray '"
);
continue
;
}
if
(
*
eoa
!=
'\''
)
{
print_error
(
"atom not terminated by '"
);
continue
;
}
++
bov
;
// skip leading '
if
(
std
::
distance
(
bov
,
eoa
)
>
10
)
{
print_error
(
"atoms are not allowed to have more than 10 characters"
);
continue
;
}
// found an atom value, copy it into a null-terminated buffer
char
buf
[
11
];
std
::
copy
(
bov
,
eoa
,
buf
);
buf
[
std
::
distance
(
bov
,
eoa
)]
=
'\0'
;
atom_value
result
=
atom
(
buf
);
consumer
(
ln
,
std
::
move
(
key
),
result
);
}
else
if
(
*
bov
==
'"'
)
{
// end-of-string iterator
auto
eos
=
eol
-
1
;
if
(
bov
==
eos
)
{
print_error
(
R"(stray '"')"
);
continue
;
}
if
(
*
eos
!=
'"'
)
{
print_error
(
R"(string not terminated by '"')"
);
continue
;
}
// found a string, remove first and last char from string,
// start escaping string sequence
auto
last_char_backslash
=
false
;
std
::
string
result
;
result
.
reserve
(
static_cast
<
size_t
>
(
std
::
distance
(
bov
,
eos
)));
// skip leading " and iterate up to the trailing "
++
bov
;
for
(;
bov
!=
eos
;
++
bov
)
{
if
(
last_char_backslash
)
{
switch
(
*
bov
)
{
case
'n'
:
result
+=
'\n'
;
break
;
case
't'
:
result
+=
'\t'
;
break
;
default:
result
+=
*
bov
;
}
last_char_backslash
=
false
;
}
else
if
(
*
bov
==
'\\'
)
{
last_char_backslash
=
true
;
}
else
{
result
+=
*
bov
;
}
}
if
(
last_char_backslash
)
print_warning
(
"trailing quotation mark escaped"
);
consumer
(
ln
,
std
::
move
(
key
),
std
::
move
(
result
));
}
else
{
bool
is_neg
=
*
bov
==
'-'
;
if
(
is_neg
&&
++
bov
==
eol
)
{
print_error
(
"'-' is not a number"
);
continue
;
}
auto
set_ival
=
[
&
](
int
base
,
int
prefix_len
,
const
char
*
err
)
{
auto
advanced_bov
=
bov
+
prefix_len
;
const
char
*
str_begin
=
&*
(
advanced_bov
);
const
char
*
str_end
=
str_begin
+
std
::
distance
(
advanced_bov
,
eol
);
char
*
e
;
int64_t
res
=
std
::
strtoll
(
str_begin
,
&
e
,
base
);
// check if we reached the end
if
(
e
!=
str_end
)
print_error
(
err
);
else
consumer
(
ln
,
std
::
move
(
key
),
is_neg
?
-
res
:
res
);
};
auto
set_dval
=
[
&
]
{
const
char
*
str_begin
=
&*
(
bov
);
const
char
*
str_end
=
str_begin
+
std
::
distance
(
bov
,
eol
);
char
*
e
;
double
res
=
std
::
strtod
(
str_begin
,
&
e
);
if
(
e
!=
str_end
)
print_error
(
"invalid value"
);
else
consumer
(
ln
,
std
::
move
(
key
),
is_neg
?
-
res
:
res
);
};
// check for number prefixes (0 for octal, 0x for hex, 0b for binary)
if
(
*
bov
==
'0'
&&
std
::
distance
(
bov
,
eol
)
>
1
)
switch
(
*
(
bov
+
1
))
{
case
'x'
:
case
'X'
:
set_ival
(
16
,
2
,
"invalid hex value"
);
break
;
case
'b'
:
case
'B'
:
set_ival
(
2
,
2
,
"invalid binary value"
);
break
;
default:
if
(
all_of
(
bov
,
eol
,
::
isdigit
))
set_ival
(
8
,
1
,
"invalid oct value"
);
else
set_dval
();
}
else
{
// no suffix, try parsing the line as integer or double
if
(
all_of
(
bov
,
eol
,
::
isdigit
))
set_ival
(
10
,
0
,
"invalid decimal value"
);
else
set_dval
();
}
}
}
}
}
// namespace detail
}
// namespace caf
libcaf_core/test/parse_ini.cpp
deleted
100644 → 0
View file @
b1a512e2
/******************************************************************************
* ____ _ _____ *
* / ___| / \ | ___| C++ *
* | | / _ \ | |_ Actor *
* | |___ / ___ \| _| Framework *
* \____/_/ \_|_| *
* *
* Copyright 2011-2018 Dominik Charousset *
* *
* Distributed under the terms and conditions of the BSD 3-Clause License or *
* (at your option) under the terms and conditions of the Boost Software *
* License 1.0. See accompanying files LICENSE and LICENSE_ALTERNATIVE. *
* *
* If you did not receive a copy of the license files, see *
* http://opensource.org/licenses/BSD-3-Clause and *
* http://www.boost.org/LICENSE_1_0.txt. *
******************************************************************************/
#include "caf/config.hpp"
#define CAF_SUITE parse_ini
#include "caf/test/unit_test.hpp"
#include <sstream>
#include <iostream>
#include "caf/string_algorithms.hpp"
#include "caf/all.hpp"
#include "caf/detail/parse_ini.hpp"
#include "caf/detail/safe_equal.hpp"
#define ERROR_HANDLER \
[&](error& err) { CAF_FAIL(system.render(err)); }
using
namespace
caf
;
namespace
{
constexpr
const
char
*
case1
=
R"__(
[scheduler]
policy="work-sharing"
max-threads=2
; the middleman
[middleman]
automatic-connections=true
[nexus]
host="127.0.0.1"
port=4242
[cash]
greeting="Hi there, this is \"CASH!\"\n ~\\~ use at your own risk ~\\~"
)__"
;
constexpr
const
char
*
case2
=
R"__(
[test]
foo=-0xff
bar=034
baz=-0.23
buzz=1E-34
bazz=0b10101010110011
bizz=-1
)__"
;
constexpr
const
char
*
case3
=
R"__("
[whoops
foo="bar"
[test]
; provoke some more errors
foo bar
=42
baz=
foo="
bar="foo
some-int=42
some-string="hi there!\"
neg=-
wtf=0x3733T
not-a-bin=0b101002
hu=0779
hop=--"hiho"
)__"
;
class
message_visitor
:
public
static_visitor
<
message
>
{
public:
template
<
class
T
>
message
operator
()(
T
&
value
)
const
{
return
make_message
(
std
::
move
(
value
));
}
};
struct
config
:
actor_system_config
{
config
()
{
parse
(
test
::
engine
::
argc
(),
test
::
engine
::
argv
());
}
};
struct
fixture
{
actor_system_config
cfg
;
actor_system
system
;
fixture
()
:
system
(
cfg
)
{
// nop
}
template
<
class
F
>
void
load_impl
(
F
consumer
,
const
char
*
str
)
{
std
::
stringstream
ss
;
std
::
stringstream
err
;
ss
<<
str
;
detail
::
parse_ini
(
ss
,
consumer
,
static_cast
<
std
::
ostream
&>
(
err
));
split
(
errors
,
err
.
str
(),
is_any_of
(
"
\n
"
),
token_compress_on
);
}
void
load_to_config_server
(
const
char
*
str
)
{
config_server
=
actor_cast
<
actor
>
(
system
.
registry
().
get
(
atom
(
"ConfigServ"
)));
// clear config
scoped_actor
self
{
system
};
self
->
request
(
config_server
,
infinite
,
get_atom
::
value
,
"*"
).
receive
(
[
&
](
std
::
vector
<
std
::
pair
<
std
::
string
,
message
>>&
msgs
)
{
for
(
auto
&
kvp
:
msgs
)
self
->
send
(
config_server
,
put_atom
::
value
,
kvp
.
first
,
message
{});
},
ERROR_HANDLER
);
auto
consume
=
[
&
](
size_t
,
std
::
string
key
,
config_value
&
value
,
optional
<
std
::
ostream
&>
)
{
message_visitor
mv
;
anon_send
(
config_server
,
put_atom
::
value
,
std
::
move
(
key
),
visit
(
mv
,
value
));
return
true
;
};
load_impl
(
consume
,
str
);
}
void
load
(
const
char
*
str
)
{
auto
consume
=
[
&
](
size_t
,
std
::
string
key
,
config_value
&
value
,
optional
<
std
::
ostream
&>
)
{
values
.
emplace
(
std
::
move
(
key
),
std
::
move
(
value
));
return
true
;
};
load_impl
(
consume
,
str
);
}
bool
has_error
(
const
char
*
err
)
{
return
std
::
any_of
(
errors
.
begin
(),
errors
.
end
(),
[
=
](
const
std
::
string
&
str
)
{
return
str
==
err
;
});
}
template
<
class
T
>
bool
config_server_has
(
const
char
*
key
,
const
T
&
what
)
{
using
type
=
typename
std
::
conditional
<
std
::
is_convertible
<
T
,
std
::
string
>::
value
,
std
::
string
,
typename
std
::
conditional
<
std
::
is_integral
<
T
>::
value
&&
!
std
::
is_same
<
T
,
bool
>::
value
,
int64_t
,
T
>::
type
>::
type
;
bool
result
=
false
;
scoped_actor
self
{
system
};
self
->
request
(
config_server
,
infinite
,
get_atom
::
value
,
key
).
receive
(
[
&
](
std
::
string
&
,
message
&
msg
)
{
msg
.
apply
(
[
&
](
type
&
val
)
{
result
=
detail
::
safe_equal
(
what
,
val
);
}
);
},
ERROR_HANDLER
);
return
result
;
}
template
<
class
T
>
bool
value_is
(
const
char
*
key
,
const
T
&
what
)
{
if
(
config_server
)
return
config_server_has
(
key
,
what
);
auto
&
cv
=
values
[
key
];
using
type
=
typename
std
::
conditional
<
std
::
is_convertible
<
T
,
std
::
string
>::
value
,
std
::
string
,
typename
std
::
conditional
<
std
::
is_integral
<
T
>::
value
&&
!
std
::
is_same
<
T
,
bool
>::
value
,
int64_t
,
T
>::
type
>::
type
;
auto
ptr
=
get_if
<
type
>
(
&
cv
);
return
ptr
!=
nullptr
&&
detail
::
safe_equal
(
*
ptr
,
what
);
}
size_t
num_values
()
{
if
(
config_server
)
{
size_t
result
=
0
;
scoped_actor
self
{
system
};
self
->
request
(
config_server
,
infinite
,
get_atom
::
value
,
"*"
).
receive
(
[
&
](
std
::
vector
<
std
::
pair
<
std
::
string
,
message
>>&
msgs
)
{
for
(
auto
&
kvp
:
msgs
)
if
(
!
kvp
.
second
.
empty
())
++
result
;
},
ERROR_HANDLER
);
return
result
;
}
return
values
.
size
();
}
void
check_case1
()
{
CAF_CHECK
(
errors
.
empty
());
CAF_CHECK
(
num_values
()
==
6
);
CAF_CHECK
(
value_is
(
"nexus.port"
,
4242
));
CAF_CHECK
(
value_is
(
"nexus.host"
,
"127.0.0.1"
));
CAF_CHECK
(
value_is
(
"scheduler.policy"
,
"work-sharing"
));
CAF_CHECK
(
value_is
(
"scheduler.max-threads"
,
2
));
CAF_CHECK
(
value_is
(
"middleman.automatic-connections"
,
true
));
CAF_CHECK
(
value_is
(
"cash.greeting"
,
"Hi there, this is
\"
CASH!
\"\n
~
\\
~ use at your own risk ~
\\
~"
));
}
void
check_case2
()
{
CAF_CHECK
(
errors
.
empty
());
CAF_CHECK
(
num_values
()
==
6
);
CAF_CHECK
(
value_is
(
"test.foo"
,
-
0xff
));
CAF_CHECK
(
value_is
(
"test.bar"
,
034
));
CAF_CHECK
(
value_is
(
"test.baz"
,
-
0.23
));
CAF_CHECK
(
value_is
(
"test.buzz"
,
1E-34
));
CAF_CHECK
(
value_is
(
"test.bazz"
,
10931
));
CAF_CHECK
(
value_is
(
"test.bizz"
,
-
1
));
}
void
check_case3
()
{
CAF_CHECK
(
has_error
(
"[ERROR] INI file line 2: missing ] at end of line"
));
CAF_CHECK
(
has_error
(
"[ERROR] INI file line 3: value outside of a group"
));
CAF_CHECK
(
has_error
(
"[ERROR] INI file line 6: no '=' found"
));
CAF_CHECK
(
has_error
(
"[ERROR] INI file line 7: line starting with '='"
));
CAF_CHECK
(
has_error
(
"[ERROR] INI file line 8: line ends with '='"
));
CAF_CHECK
(
has_error
(
"[ERROR] INI file line 9: stray '
\"
'"
));
CAF_CHECK
(
has_error
(
"[ERROR] INI file line 10: string not terminated by '
\"
'"
));
CAF_CHECK
(
has_error
(
"[WARNING] INI file line 12: trailing quotation mark escaped"
));
CAF_CHECK
(
has_error
(
"[ERROR] INI file line 13: '-' is not a number"
));
CAF_CHECK
(
has_error
(
"[ERROR] INI file line 14: invalid hex value"
));
CAF_CHECK
(
has_error
(
"[ERROR] INI file line 15: invalid binary value"
));
CAF_CHECK
(
has_error
(
"[ERROR] INI file line 16: invalid oct value"
));
CAF_CHECK
(
has_error
(
"[ERROR] INI file line 17: invalid value"
));
CAF_CHECK
(
num_values
()
==
2
);
CAF_CHECK
(
value_is
(
"test.some-int"
,
42
));
CAF_CHECK
(
value_is
(
"test.some-string"
,
"hi there!"
));
}
std
::
map
<
std
::
string
,
config_value
>
values
;
actor
config_server
;
std
::
vector
<
std
::
string
>
errors
;
};
}
// namespace <anonymous>
CAF_TEST_FIXTURE_SCOPE
(
parse_ini_tests
,
fixture
)
CAF_TEST
(
simple_ini
)
{
load
(
case1
);
check_case1
();
}
CAF_TEST
(
numbers
)
{
load
(
case2
);
check_case2
();
}
CAF_TEST
(
errors
)
{
load
(
case3
);
check_case3
();
}
CAF_TEST
(
simple_ini_via_config_server
)
{
load_to_config_server
(
case1
);
CAF_CHECK
(
values
.
empty
());
check_case1
();
}
CAF_TEST
(
numbers_via_config_server
)
{
load_to_config_server
(
case2
);
CAF_CHECK
(
values
.
empty
());
check_case2
();
}
CAF_TEST
(
errors_via_config_server
)
{
load_to_config_server
(
case3
);
CAF_CHECK
(
values
.
empty
());
check_case3
();
}
CAF_TEST_FIXTURE_SCOPE_END
()
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