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
7f414346
Commit
7f414346
authored
Sep 08, 2020
by
Dominik Charousset
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Fix handling of CLI arguments
parent
844ad3db
Changes
6
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
113 additions
and
50 deletions
+113
-50
libcaf_core/caf/config_value.hpp
libcaf_core/caf/config_value.hpp
+62
-41
libcaf_core/caf/detail/parse.hpp
libcaf_core/caf/detail/parse.hpp
+2
-0
libcaf_core/src/detail/parse.cpp
libcaf_core/src/detail/parse.cpp
+17
-0
libcaf_core/test/config_option_set.cpp
libcaf_core/test/config_option_set.cpp
+15
-5
libcaf_core/test/config_value.cpp
libcaf_core/test/config_value.cpp
+11
-2
libcaf_core/test/inspector-tests.hpp
libcaf_core/test/inspector-tests.hpp
+6
-2
No files found.
libcaf_core/caf/config_value.hpp
View file @
7f414346
...
@@ -785,47 +785,6 @@ private:
...
@@ -785,47 +785,6 @@ private:
}
}
};
};
template
<
class
T
>
struct
inspect_config_value_access
{
static
std
::
string
type_name
()
{
return
to_string
(
type_name_or_anonymous
<
T
>
());
}
static
optional
<
T
>
get_if
(
const
config_value
*
x
)
{
config_value_reader
reader
{
x
};
auto
tmp
=
T
{};
if
(
detail
::
load_value
(
reader
,
tmp
))
return
optional
<
T
>
{
std
::
move
(
tmp
)};
return
none
;
}
static
bool
is
(
const
config_value
&
x
)
{
return
get_if
(
&
x
)
!=
none
;
}
static
T
get
(
const
config_value
&
x
)
{
auto
result
=
get_if
(
&
x
);
if
(
!
result
)
CAF_RAISE_ERROR
(
"invalid type found"
);
return
std
::
move
(
*
result
);
}
template
<
class
Nested
>
static
void
parse_cli
(
string_parser_state
&
ps
,
T
&
,
Nested
)
{
// TODO: we could try to read a config_value here and then deserialize the
// value from that.
ps
.
code
=
pec
::
invalid_argument
;
}
static
config_value
convert
(
const
T
&
x
)
{
config_value
result
;
config_value_writer
writer
{
&
result
};
if
(
!
detail
::
save_value
(
writer
,
x
))
CAF_RAISE_ERROR
(
"unable to convert type to a config_value"
);
return
result
;
}
};
}
// namespace detail
}
// namespace detail
// -- SumType access of dictionary values --------------------------------------
// -- SumType access of dictionary values --------------------------------------
...
@@ -932,6 +891,68 @@ config_value make_config_value_list(Ts&&... xs) {
...
@@ -932,6 +891,68 @@ config_value make_config_value_list(Ts&&... xs) {
// -- inspection API -----------------------------------------------------------
// -- inspection API -----------------------------------------------------------
namespace
detail
{
template
<
class
T
>
struct
inspect_config_value_access
{
static
std
::
string
type_name
()
{
return
to_string
(
type_name_or_anonymous
<
T
>
());
}
static
optional
<
T
>
get_if
(
const
config_value
*
x
)
{
config_value_reader
reader
{
x
};
auto
tmp
=
T
{};
if
(
detail
::
load_value
(
reader
,
tmp
))
return
optional
<
T
>
{
std
::
move
(
tmp
)};
return
none
;
}
static
bool
is
(
const
config_value
&
x
)
{
return
get_if
(
&
x
)
!=
none
;
}
static
T
get
(
const
config_value
&
x
)
{
auto
result
=
get_if
(
&
x
);
if
(
!
result
)
CAF_RAISE_ERROR
(
"invalid type found"
);
return
std
::
move
(
*
result
);
}
template
<
class
Nested
>
static
void
parse_cli
(
string_parser_state
&
ps
,
T
&
x
,
Nested
token
)
{
auto
first
=
ps
.
i
;
config_value
tmp
;
detail
::
parse
(
ps
,
tmp
);
// If the first attempt fails, rewind the parser state and try parsing the
// input as a string. This allows unescaped inputs.
if
(
ps
.
code
!=
pec
::
success
)
{
ps
.
code
=
pec
::
success
;
ps
.
i
=
first
;
std
::
string
str
;
config_value_access_t
<
std
::
string
>::
parse_cli
(
ps
,
str
,
token
);
if
(
ps
.
code
==
pec
::
success
)
tmp
=
config_value
{
std
::
move
(
str
)};
}
if
(
ps
.
code
==
pec
::
success
)
{
if
(
auto
res
=
caf
::
get_if
<
T
>
(
&
tmp
))
{
x
=
detail
::
move_if_not_ptr
(
res
);
}
else
{
ps
.
code
=
pec
::
invalid_argument
;
}
}
}
static
config_value
convert
(
const
T
&
x
)
{
config_value
result
;
config_value_writer
writer
{
&
result
};
if
(
!
detail
::
save_value
(
writer
,
x
))
CAF_RAISE_ERROR
(
"unable to convert type to a config_value"
);
return
result
;
}
};
}
// namespace detail
template
<
>
template
<
>
struct
variant_inspector_traits
<
config_value
>
{
struct
variant_inspector_traits
<
config_value
>
{
using
value_type
=
config_value
;
using
value_type
=
config_value
;
...
...
libcaf_core/caf/detail/parse.hpp
View file @
7f414346
...
@@ -115,6 +115,8 @@ CAF_CORE_EXPORT void parse(string_parser_state& ps, ipv6_endpoint& x);
...
@@ -115,6 +115,8 @@ CAF_CORE_EXPORT void parse(string_parser_state& ps, ipv6_endpoint& x);
CAF_CORE_EXPORT
void
parse
(
string_parser_state
&
ps
,
uri
&
x
);
CAF_CORE_EXPORT
void
parse
(
string_parser_state
&
ps
,
uri
&
x
);
CAF_CORE_EXPORT
void
parse
(
string_parser_state
&
ps
,
config_value
&
x
);
// -- variadic utility ---------------------------------------------------------
// -- variadic utility ---------------------------------------------------------
template
<
class
...
Ts
>
template
<
class
...
Ts
>
...
...
libcaf_core/src/detail/parse.cpp
View file @
7f414346
...
@@ -18,9 +18,11 @@
...
@@ -18,9 +18,11 @@
#include "caf/detail/parse.hpp"
#include "caf/detail/parse.hpp"
#include "caf/detail/config_consumer.hpp"
#include "caf/detail/consumer.hpp"
#include "caf/detail/consumer.hpp"
#include "caf/detail/parser/chars.hpp"
#include "caf/detail/parser/chars.hpp"
#include "caf/detail/parser/read_bool.hpp"
#include "caf/detail/parser/read_bool.hpp"
#include "caf/detail/parser/read_config.hpp"
#include "caf/detail/parser/read_floating_point.hpp"
#include "caf/detail/parser/read_floating_point.hpp"
#include "caf/detail/parser/read_ipv4_address.hpp"
#include "caf/detail/parser/read_ipv4_address.hpp"
#include "caf/detail/parser/read_ipv6_address.hpp"
#include "caf/detail/parser/read_ipv6_address.hpp"
...
@@ -161,6 +163,21 @@ void parse(string_parser_state& ps, uri& x) {
...
@@ -161,6 +163,21 @@ void parse(string_parser_state& ps, uri& x) {
x
=
builder
.
make
();
x
=
builder
.
make
();
}
}
void
parse
(
string_parser_state
&
ps
,
config_value
&
x
)
{
ps
.
skip_whitespaces
();
if
(
ps
.
at_end
())
{
ps
.
code
=
pec
::
unexpected_eof
;
return
;
}
// Safe the string as fallback.
string_view
str
{
ps
.
i
,
ps
.
e
};
// Dispatch to parser.
detail
::
config_value_consumer
f
;
parser
::
read_config_value
(
ps
,
f
);
if
(
ps
.
code
<=
pec
::
trailing_character
)
x
=
std
::
move
(
f
.
result
);
}
PARSE_IMPL
(
ipv4_address
,
ipv4_address
)
PARSE_IMPL
(
ipv4_address
,
ipv4_address
)
void
parse
(
string_parser_state
&
ps
,
ipv4_subnet
&
x
)
{
void
parse
(
string_parser_state
&
ps
,
ipv4_subnet
&
x
)
{
...
...
libcaf_core/test/config_option_set.cpp
View file @
7f414346
...
@@ -18,15 +18,15 @@
...
@@ -18,15 +18,15 @@
#define CAF_SUITE config_option_set
#define CAF_SUITE config_option_set
#include "caf/config_option_set.hpp"
#include "core-test.hpp"
#include "inspector-tests.hpp"
#include <map>
#include <map>
#include <string>
#include <string>
#include <vector>
#include <vector>
#include "caf/config.hpp"
#include "core-test.hpp"
#include "caf/config_option_set.hpp"
#include "caf/detail/move_if_not_ptr.hpp"
#include "caf/detail/move_if_not_ptr.hpp"
#include "caf/settings.hpp"
#include "caf/settings.hpp"
...
@@ -236,4 +236,14 @@ CAF_TEST(CLI arguments override defaults) {
...
@@ -236,4 +236,14 @@ CAF_TEST(CLI arguments override defaults) {
}
}
}
}
CAF_TEST
(
CLI
arguments
may
use
custom
types
)
{
settings
cfg
;
opts
.
add
<
foobar
>
(
"global"
,
"foobar,f"
,
"test option"
);
CAF_CHECK_EQUAL
(
read
<
foobar
>
(
cfg
,
{
"-f{foo=
\"
hello
\"
,bar=
\"
world
\"
}"
}),
none
);
CAF_MESSAGE
(
"CFG: "
<<
cfg
);
auto
fb
=
get_if
<
foobar
>
(
&
cfg
,
"foobar"
);
if
(
CAF_CHECK
(
fb
))
CAF_CHECK_EQUAL
(
*
fb
,
foobar
(
"hello"
,
"world"
));
}
CAF_TEST_FIXTURE_SCOPE_END
()
CAF_TEST_FIXTURE_SCOPE_END
()
libcaf_core/test/config_value.cpp
View file @
7f414346
...
@@ -489,8 +489,17 @@ CAF_TEST(config values pick up user defined inspect overloads) {
...
@@ -489,8 +489,17 @@ CAF_TEST(config values pick up user defined inspect overloads) {
CAF_MESSAGE
(
"read 'line' via get_if and verify the object"
);
CAF_MESSAGE
(
"read 'line' via get_if and verify the object"
);
{
{
auto
l
=
get_if
<
line
>
(
&
x
);
auto
l
=
get_if
<
line
>
(
&
x
);
CAF_CHECK_NOT_EQUAL
(
l
,
none
);
if
(
CAF_CHECK_NOT_EQUAL
(
l
,
none
))
if
(
l
)
CAF_CHECK_EQUAL
(
*
l
,
(
line
{{
1
,
2
,
3
},
{
10
,
20
,
30
}}));
CAF_CHECK_EQUAL
(
*
l
,
(
line
{{
1
,
2
,
3
},
{
10
,
20
,
30
}}));
}
}
CAF_MESSAGE
(
"parse config value directly from string input"
);
{
auto
val
=
config_value
::
parse
(
"{p1{x=1,y=2,z=3},p2{x=10,y=20,z=30}}"
);
CAF_CHECK
(
val
);
if
(
val
)
{
auto
l
=
get_if
<
line
>
(
std
::
addressof
(
*
val
));
if
(
CAF_CHECK_NOT_EQUAL
(
l
,
none
))
CAF_CHECK_EQUAL
(
*
l
,
(
line
{{
1
,
2
,
3
},
{
10
,
20
,
30
}}));
}
}
}
}
libcaf_core/test/inspector-tests.hpp
View file @
7f414346
...
@@ -108,7 +108,7 @@ public:
...
@@ -108,7 +108,7 @@ public:
// nop
// nop
}
}
const
std
::
string
&
foo
()
{
const
std
::
string
&
foo
()
const
{
return
foo_
;
return
foo_
;
}
}
...
@@ -116,7 +116,7 @@ public:
...
@@ -116,7 +116,7 @@ public:
foo_
=
std
::
move
(
value
);
foo_
=
std
::
move
(
value
);
}
}
const
std
::
string
&
bar
()
{
const
std
::
string
&
bar
()
const
{
return
bar_
;
return
bar_
;
}
}
...
@@ -129,6 +129,10 @@ private:
...
@@ -129,6 +129,10 @@ private:
std
::
string
bar_
;
std
::
string
bar_
;
};
};
[[
maybe_unused
]]
bool
operator
==
(
const
foobar
&
x
,
const
foobar
&
y
)
{
return
std
::
tie
(
x
.
foo
(),
x
.
bar
())
==
std
::
tie
(
y
.
foo
(),
y
.
bar
());
}
template
<
class
Inspector
>
template
<
class
Inspector
>
bool
inspect
(
Inspector
&
f
,
foobar
&
x
)
{
bool
inspect
(
Inspector
&
f
,
foobar
&
x
)
{
auto
get_foo
=
[
&
x
]()
->
decltype
(
auto
)
{
return
x
.
foo
();
};
auto
get_foo
=
[
&
x
]()
->
decltype
(
auto
)
{
return
x
.
foo
();
};
...
...
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