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
1d4dcede
Commit
1d4dcede
authored
Jul 03, 2020
by
Dominik Charousset
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Remove .ini remnants completely
parent
13b5d670
Changes
9
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
23 additions
and
1268 deletions
+23
-1268
CHANGELOG.md
CHANGELOG.md
+5
-8
libcaf_core/CMakeLists.txt
libcaf_core/CMakeLists.txt
+0
-3
libcaf_core/caf/actor_system_config.hpp
libcaf_core/caf/actor_system_config.hpp
+5
-10
libcaf_core/caf/detail/ini_consumer.hpp
libcaf_core/caf/detail/ini_consumer.hpp
+0
-214
libcaf_core/caf/detail/parser/read_ini.hpp
libcaf_core/caf/detail/parser/read_ini.hpp
+0
-346
libcaf_core/src/actor_system_config.cpp
libcaf_core/src/actor_system_config.cpp
+13
-47
libcaf_core/src/detail/ini_consumer.cpp
libcaf_core/src/detail/ini_consumer.cpp
+0
-198
libcaf_core/test/detail/ini_consumer.cpp
libcaf_core/test/detail/ini_consumer.cpp
+0
-118
libcaf_core/test/detail/parser/read_ini.cpp
libcaf_core/test/detail/parser/read_ini.cpp
+0
-324
No files found.
CHANGELOG.md
View file @
1d4dcede
...
...
@@ -54,14 +54,6 @@ is based on [Keep a Changelog](https://keepachangelog.com).
-
The
`to_string`
output for
`error`
now renders the error code enum by default.
This renders the member functions
`actor_system::render`
and
`actor_system_config::render`
obsolete.
-
The configuration format of CAF has come a long way since first starting to
allow user-defined configuration via
`.ini`
files. Rather than sticking with
the weird hybrid that evolved over the years, we are going to get rid of the
last pieces of INI syntax and go with the much cleaner, scoped syntax. CAF is
still picking up
`caf-application.ini`
with this release and uses the
deprecated INI parser when given any other file name that ends in
`.ini`
.
However, the next version of CAF is only going to recognize the new format.
The new default file name is
`caf-application.conf`
.
### Changed
...
...
@@ -148,6 +140,11 @@ is based on [Keep a Changelog](https://keepachangelog.com).
-
All member functions of
`scheduled_actor`
for adding stream managers (such as
`make_source`
) were removed in favor their free-function equivalent, e.g.,
`attach_stream_source`
-
The configuration format of CAF has come a long way since first starting to
allow user-defined configuration via
`.ini`
files. Rather than sticking with
the weird hybrid that evolved over the years, we finally get rid of the last
pieces of INI syntax and go with the much cleaner, scoped syntax. The new
default file name for configuration files is
`caf-application.conf`
.
### Fixed
...
...
libcaf_core/CMakeLists.txt
View file @
1d4dcede
...
...
@@ -84,7 +84,6 @@ add_library(libcaf_core_obj OBJECT ${CAF_CORE_HEADERS}
src/detail/get_process_id.cpp
src/detail/get_root_uuid.cpp
src/detail/glob_match.cpp
src/detail/ini_consumer.cpp
src/detail/invoke_result_visitor.cpp
src/detail/message_builder_element.cpp
src/detail/message_data.cpp
...
...
@@ -237,14 +236,12 @@ caf_add_test_suites(caf-core-test
detail.bounds_checker
detail.config_consumer
detail.ieee_754
detail.ini_consumer
detail.limited_vector
detail.meta_object
detail.parse
detail.parser.read_bool
detail.parser.read_config
detail.parser.read_floating_point
detail.parser.read_ini
detail.parser.read_number
detail.parser.read_number_or_timespan
detail.parser.read_signed_integer
...
...
libcaf_core/caf/actor_system_config.hpp
View file @
1d4dcede
...
...
@@ -99,7 +99,7 @@ public:
/// values.
virtual
settings
dump_content
()
const
;
/// Sets a config by using its
INI
name `config_name` to `config_value`.
/// Sets a config by using its name `config_name` to `config_value`.
template
<
class
T
>
actor_system_config
&
set
(
string_view
name
,
T
&&
value
)
{
return
set_impl
(
name
,
config_value
{
std
::
forward
<
T
>
(
value
)});
...
...
@@ -113,16 +113,15 @@ public:
/// Parses `args` as tuple of strings containing CLI options and tries to open
/// `config_file_cstr` as config file. The parsers tries to open
/// `caf-application.conf` or `caf-application.ini` (deprecated) if
/// `config_file_cstr` is `nullptr`.
/// `caf-application.conf` if `config_file_cstr` is `nullptr`.
error
parse
(
string_list
args
,
const
char
*
config_file_cstr
=
nullptr
);
/// Parses the CLI options `{argc, argv}` and `config` as configuration file.
error
parse
(
int
argc
,
char
**
argv
,
std
::
istream
&
config
);
/// Parses the CLI options `{argc, argv}` and tries to open `config_file_cstr`
/// as config file. The parsers tries to open `caf-application.conf`
or
/// `c
af-application.ini` (deprecated) if `c
onfig_file_cstr` is `nullptr`.
/// as config file. The parsers tries to open `caf-application.conf`
if
/// `config_file_cstr` is `nullptr`.
error
parse
(
int
argc
,
char
**
argv
,
const
char
*
config_file_cstr
=
nullptr
);
/// Allows other nodes to spawn actors created by `fun`
...
...
@@ -247,7 +246,7 @@ public:
// -- parsing parameters -----------------------------------------------------
/// Configures the file path for the
INI file, `caf-application.ini
` per
/// Configures the file path for the
config file, `caf-application.conf
` per
/// default.
std
::
string
config_file_path
;
...
...
@@ -324,10 +323,6 @@ protected:
config_option_set
custom_options_
;
private:
// TODO: deprecated. Remove with CAF 0.19.
static
error
parse_ini
(
std
::
istream
&
source
,
const
config_option_set
&
opts
,
settings
&
result
);
actor_system_config
&
set_impl
(
string_view
name
,
config_value
value
);
error
extract_config_file_path
(
string_list
&
args
);
...
...
libcaf_core/caf/detail/ini_consumer.hpp
deleted
100644 → 0
View file @
13b5d670
/******************************************************************************
* ____ _ _____ *
* / ___| / \ | ___| 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 "caf/config_option_set.hpp"
#include "caf/config_value.hpp"
#include "caf/detail/core_export.hpp"
#include "caf/dictionary.hpp"
#include "caf/settings.hpp"
namespace
caf
::
detail
{
class
ini_consumer
;
class
ini_list_consumer
;
class
ini_map_consumer
;
class
CAF_CORE_EXPORT
abstract_ini_consumer
{
public:
// -- constructors, destructors, and assignment operators --------------------
explicit
abstract_ini_consumer
(
abstract_ini_consumer
*
parent
=
nullptr
);
abstract_ini_consumer
(
const
abstract_ini_consumer
&
)
=
delete
;
abstract_ini_consumer
&
operator
=
(
const
abstract_ini_consumer
&
)
=
delete
;
virtual
~
abstract_ini_consumer
();
// -- properties -------------------------------------------------------------
virtual
void
value_impl
(
config_value
&&
x
)
=
0
;
template
<
class
T
>
void
value
(
T
&&
x
)
{
value_impl
(
config_value
{
std
::
forward
<
T
>
(
x
)});
}
abstract_ini_consumer
*
parent
()
{
return
parent_
;
}
ini_map_consumer
begin_map
();
ini_list_consumer
begin_list
();
protected:
// -- member variables -------------------------------------------------------
abstract_ini_consumer
*
parent_
;
};
class
CAF_CORE_EXPORT
ini_map_consumer
:
public
abstract_ini_consumer
{
public:
// -- member types -----------------------------------------------------------
using
super
=
abstract_ini_consumer
;
using
map_type
=
config_value
::
dictionary
;
using
iterator
=
map_type
::
iterator
;
// -- constructors, destructors, and assignment operators --------------------
ini_map_consumer
(
abstract_ini_consumer
*
ptr
);
ini_map_consumer
(
ini_map_consumer
&&
other
);
~
ini_map_consumer
()
override
;
// -- properties -------------------------------------------------------------
void
end_map
();
void
key
(
std
::
string
name
);
void
value_impl
(
config_value
&&
x
)
override
;
private:
// -- member variables -------------------------------------------------------
map_type
xs_
;
iterator
i_
;
};
class
CAF_CORE_EXPORT
ini_list_consumer
:
public
abstract_ini_consumer
{
public:
// -- member types -----------------------------------------------------------
using
super
=
abstract_ini_consumer
;
// -- constructors, destructors, and assignment operators --------------------
ini_list_consumer
(
abstract_ini_consumer
*
ptr
);
ini_list_consumer
(
ini_list_consumer
&&
other
);
// -- properties -------------------------------------------------------------
void
end_list
();
void
value_impl
(
config_value
&&
x
)
override
;
private:
// -- member variables -------------------------------------------------------
config_value
::
list
xs_
;
};
/// Consumes a single value from an INI parser.
class
CAF_CORE_EXPORT
ini_value_consumer
:
public
abstract_ini_consumer
{
public:
// -- member types -----------------------------------------------------------
using
super
=
abstract_ini_consumer
;
// -- constructors, destructors, and assignment operators --------------------
explicit
ini_value_consumer
(
abstract_ini_consumer
*
parent
=
nullptr
);
// -- properties -------------------------------------------------------------
void
value_impl
(
config_value
&&
x
)
override
;
// -- member variables -------------------------------------------------------
config_value
result
;
};
/// Consumes a config category.
class
CAF_CORE_EXPORT
ini_category_consumer
:
public
abstract_ini_consumer
{
public:
// -- member types -----------------------------------------------------------
using
super
=
abstract_ini_consumer
;
// -- constructors, destructors, and assignment operators --------------------
ini_category_consumer
(
ini_consumer
*
parent
,
std
::
string
category
);
ini_category_consumer
(
ini_category_consumer
&&
);
// -- properties -------------------------------------------------------------
void
end_map
();
void
key
(
std
::
string
name
);
void
value_impl
(
config_value
&&
x
)
override
;
private:
// -- properties -------------------------------------------------------------
ini_consumer
*
dparent
();
// -- member variables -------------------------------------------------------
std
::
string
category_
;
config_value
::
dictionary
xs_
;
std
::
string
current_key
;
};
/// Consumes a series of dictionaries forming a application configuration.
class
CAF_CORE_EXPORT
ini_consumer
:
public
abstract_ini_consumer
{
public:
// -- friends ----------------------------------------------------------------
friend
class
ini_category_consumer
;
// -- member types -----------------------------------------------------------
using
super
=
abstract_ini_consumer
;
using
config_map
=
dictionary
<
config_value
::
dictionary
>
;
// -- constructors, destructors, and assignment operators --------------------
ini_consumer
(
const
config_option_set
&
options
,
settings
&
cfg
);
// -- properties -------------------------------------------------------------
ini_category_consumer
begin_map
();
void
key
(
std
::
string
name
);
void
value_impl
(
config_value
&&
x
)
override
;
private:
// -- member variables -------------------------------------------------------
const
config_option_set
&
options_
;
settings
&
cfg_
;
std
::
string
current_key_
;
std
::
vector
<
error
>
warnings_
;
};
}
// namespace caf::detail
libcaf_core/caf/detail/parser/read_ini.hpp
deleted
100644 → 0
View file @
13b5d670
This diff is collapsed.
Click to expand it.
libcaf_core/src/actor_system_config.cpp
View file @
1d4dcede
...
...
@@ -30,7 +30,6 @@
#include "caf/detail/config_consumer.hpp"
#include "caf/detail/gcd.hpp"
#include "caf/detail/parser/read_config.hpp"
#include "caf/detail/parser/read_ini.hpp"
#include "caf/detail/parser/read_string.hpp"
#include "caf/message_builder.hpp"
#include "caf/pec.hpp"
...
...
@@ -50,7 +49,7 @@ actor_system_config::~actor_system_config() {
}
// in this config class, we have (1) hard-coded defaults that are overridden
// by (2)
INI-
file contents that are in turn overridden by (3) CLI arguments
// by (2)
config
file contents that are in turn overridden by (3) CLI arguments
actor_system_config
::
actor_system_config
()
:
cli_helptext_printed
(
false
),
...
...
@@ -61,14 +60,14 @@ actor_system_config::actor_system_config()
stream_desired_batch_complexity
=
defaults
::
stream
::
desired_batch_complexity
;
stream_max_batch_delay
=
defaults
::
stream
::
max_batch_delay
;
stream_credit_round_interval
=
defaults
::
stream
::
credit_round_interval
;
// fill our options vector for creating
INI
and CLI parsers
// fill our options vector for creating
config file
and CLI parsers
using
std
::
string
;
opt_group
{
custom_options_
,
"global"
}
.
add
<
bool
>
(
"help,h?"
,
"print help text to STDERR and exit"
)
.
add
<
bool
>
(
"long-help"
,
"print long help text to STDERR and exit"
)
.
add
<
bool
>
(
"dump-config"
,
"print configuration to STDERR and exit"
)
.
add
<
string
>
(
config_file_path
,
"config-file"
,
"set config file (default: caf-application.
ini
)"
);
"set config file (default: caf-application.
conf
)"
);
opt_group
{
custom_options_
,
"stream"
}
.
add
<
timespan
>
(
stream_desired_batch_complexity
,
"desired-batch-complexity"
,
"processing time per batch"
)
...
...
@@ -211,31 +210,31 @@ settings actor_system_config::dump_content() const {
}
error
actor_system_config
::
parse
(
int
argc
,
char
**
argv
,
const
char
*
ini
_file_cstr
)
{
const
char
*
config
_file_cstr
)
{
string_list
args
;
if
(
argc
>
1
)
args
.
assign
(
argv
+
1
,
argv
+
argc
);
return
parse
(
std
::
move
(
args
),
ini
_file_cstr
);
return
parse
(
std
::
move
(
args
),
config
_file_cstr
);
}
error
actor_system_config
::
parse
(
int
argc
,
char
**
argv
,
std
::
istream
&
ini
)
{
error
actor_system_config
::
parse
(
int
argc
,
char
**
argv
,
std
::
istream
&
conf
)
{
string_list
args
;
if
(
argc
>
1
)
args
.
assign
(
argv
+
1
,
argv
+
argc
);
return
parse
(
std
::
move
(
args
),
ini
);
return
parse
(
std
::
move
(
args
),
conf
);
}
namespace
{
struct
config_iter
{
std
::
istream
*
ini
;
std
::
istream
*
conf
;
char
ch
;
explicit
config_iter
(
std
::
istream
*
istr
)
:
ini
(
istr
)
{
ini
->
get
(
ch
);
explicit
config_iter
(
std
::
istream
*
istr
)
:
conf
(
istr
)
{
conf
->
get
(
ch
);
}
config_iter
()
:
ini
(
nullptr
),
ch
(
'\0'
)
{
config_iter
()
:
conf
(
nullptr
),
ch
(
'\0'
)
{
// nop
}
...
...
@@ -248,7 +247,7 @@ struct config_iter {
}
inline
config_iter
&
operator
++
()
{
ini
->
get
(
ch
);
conf
->
get
(
ch
);
return
*
this
;
}
};
...
...
@@ -256,7 +255,7 @@ struct config_iter {
struct
config_sentinel
{};
bool
operator
!=
(
config_iter
iter
,
config_sentinel
)
{
return
!
iter
.
ini
->
fail
();
return
!
iter
.
conf
->
fail
();
}
struct
indentation
{
...
...
@@ -348,18 +347,6 @@ error actor_system_config::parse(string_list args,
return
err
;
if
(
config_file_path
==
"$DEFAULT"
)
{
std
::
ifstream
conf
{
"caf-application.conf"
};
// TODO: The .ini parser is deprecated. Remove with CAF 0.19.
if
(
!
conf
.
is_open
())
{
conf
.
open
(
"caf-application.ini"
);
if
(
conf
.
is_open
())
{
// Consume the ini file here, because the parse() overload that takes
// an istream assumes the new config format.
if
(
auto
err
=
parse_ini
(
conf
,
custom_options_
,
content
))
return
err
;
std
::
ifstream
dummy
;
return
parse
(
std
::
move
(
args
),
dummy
);
}
}
return
parse
(
std
::
move
(
args
),
conf
);
}
std
::
ifstream
conf
{
config_file_path
};
...
...
@@ -418,14 +405,6 @@ actor_system_config::parse_config_file(const char* filename,
std
::
ifstream
f
{
filename
};
if
(
!
f
.
is_open
())
return
make_error
(
sec
::
cannot_open_file
,
filename
);
// TODO: The .ini parser is deprecated. Remove this block with CAF 0.19.
string_view
fname
{
filename
,
strlen
(
filename
)};
if
(
ends_with
(
fname
,
".ini"
))
{
settings
result
;
if
(
auto
err
=
parse_ini
(
f
,
opts
,
result
))
return
err
;
return
result
;
}
return
parse_config
(
f
,
opts
);
}
...
...
@@ -456,19 +435,6 @@ error actor_system_config::parse_config(std::istream& source,
return
none
;
}
error
actor_system_config
::
parse_ini
(
std
::
istream
&
source
,
const
config_option_set
&
opts
,
settings
&
result
)
{
if
(
!
source
)
return
make_error
(
sec
::
runtime_error
,
"source stream invalid"
);
detail
::
config_consumer
consumer
{
opts
,
result
};
parser_state
<
config_iter
,
config_sentinel
>
res
{
config_iter
{
&
source
}};
detail
::
parser
::
read_ini
(
res
,
consumer
);
if
(
res
.
i
!=
res
.
e
)
return
make_error
(
res
.
code
,
res
.
line
,
res
.
column
);
return
none
;
}
error
actor_system_config
::
extract_config_file_path
(
string_list
&
args
)
{
auto
ptr
=
custom_options_
.
qualified_name_lookup
(
"global.config-file"
);
CAF_ASSERT
(
ptr
!=
nullptr
);
...
...
libcaf_core/src/detail/ini_consumer.cpp
deleted
100644 → 0
View file @
13b5d670
/******************************************************************************
* ____ _ _____ *
* / ___| / \ | ___| 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/ini_consumer.hpp"
#include "caf/pec.hpp"
namespace
caf
::
detail
{
// -- abstract_ini_consumer ----------------------------------------------------
abstract_ini_consumer
::
abstract_ini_consumer
(
abstract_ini_consumer
*
parent
)
:
parent_
(
parent
)
{
// nop
}
abstract_ini_consumer
::~
abstract_ini_consumer
()
{
// nop
}
ini_map_consumer
abstract_ini_consumer
::
begin_map
()
{
return
{
this
};
}
ini_list_consumer
abstract_ini_consumer
::
begin_list
()
{
return
{
this
};
}
// -- map_consumer -------------------------------------------------------------
ini_map_consumer
::
ini_map_consumer
(
abstract_ini_consumer
*
parent
)
:
super
(
parent
),
i_
(
xs_
.
end
())
{
CAF_ASSERT
(
parent
!=
nullptr
);
}
ini_map_consumer
::
ini_map_consumer
(
ini_map_consumer
&&
other
)
:
super
(
other
.
parent
())
{
}
ini_map_consumer
::~
ini_map_consumer
()
{
// nop
}
void
ini_map_consumer
::
end_map
()
{
parent_
->
value_impl
(
config_value
{
std
::
move
(
xs_
)});
}
void
ini_map_consumer
::
key
(
std
::
string
name
)
{
i_
=
xs_
.
emplace
(
std
::
move
(
name
),
config_value
{}).
first
;
}
void
ini_map_consumer
::
value_impl
(
config_value
&&
x
)
{
CAF_ASSERT
(
i_
!=
xs_
.
end
());
i_
->
second
=
std
::
move
(
x
);
}
// -- ini_list_consumer --------------------------------------------------------
ini_list_consumer
::
ini_list_consumer
(
abstract_ini_consumer
*
parent
)
:
super
(
parent
)
{
CAF_ASSERT
(
parent
!=
nullptr
);
}
ini_list_consumer
::
ini_list_consumer
(
ini_list_consumer
&&
other
)
:
super
(
other
.
parent
()),
xs_
(
std
::
move
(
other
.
xs_
))
{
// nop
}
void
ini_list_consumer
::
end_list
()
{
parent_
->
value_impl
(
config_value
{
std
::
move
(
xs_
)});
}
void
ini_list_consumer
::
value_impl
(
config_value
&&
x
)
{
xs_
.
emplace_back
(
std
::
move
(
x
));
}
// -- ini_value_consumer -------------------------------------------------------
ini_value_consumer
::
ini_value_consumer
(
abstract_ini_consumer
*
parent
)
:
super
(
parent
)
{
// nop
}
void
ini_value_consumer
::
value_impl
(
config_value
&&
x
)
{
result
=
std
::
move
(
x
);
}
// -- ini_category_consumer ----------------------------------------------------
ini_category_consumer
::
ini_category_consumer
(
ini_consumer
*
parent
,
std
::
string
category
)
:
super
(
parent
),
category_
(
std
::
move
(
category
))
{
CAF_ASSERT
(
parent_
!=
nullptr
);
}
ini_category_consumer
::
ini_category_consumer
(
ini_category_consumer
&&
other
)
:
super
(
other
.
parent
()),
category_
(
std
::
move
(
other
.
category_
)),
xs_
(
std
::
move
(
other
.
xs_
)),
current_key
(
std
::
move
(
other
.
current_key
))
{
CAF_ASSERT
(
parent_
!=
nullptr
);
}
void
ini_category_consumer
::
end_map
()
{
parent_
->
value_impl
(
config_value
{
std
::
move
(
xs_
)});
}
void
ini_category_consumer
::
key
(
std
::
string
name
)
{
current_key
=
std
::
move
(
name
);
}
void
ini_category_consumer
::
value_impl
(
config_value
&&
x
)
{
// See whether there's an config_option associated to this category and key.
auto
opt
=
dparent
()
->
options_
.
qualified_name_lookup
(
category_
,
current_key
);
if
(
opt
==
nullptr
)
{
// Simply store in config if no option was found.
xs_
.
emplace
(
std
::
move
(
current_key
),
std
::
move
(
x
));
}
else
{
// Perform a type check to see whether this is a valid input.
if
(
opt
->
check
(
x
)
==
none
)
{
opt
->
store
(
x
);
xs_
.
emplace
(
std
::
move
(
current_key
),
std
::
move
(
x
));
}
else
{
dparent
()
->
warnings_
.
emplace_back
(
make_error
(
pec
::
type_mismatch
));
}
}
}
ini_consumer
*
ini_category_consumer
::
dparent
()
{
// Safe, because our constructor only accepts ini_consumer parents.
return
static_cast
<
ini_consumer
*>
(
parent
());
}
// -- ini_consumer -------------------------------------------------------------
ini_consumer
::
ini_consumer
(
const
config_option_set
&
options
,
settings
&
cfg
)
:
options_
(
options
),
cfg_
(
cfg
),
current_key_
(
"global"
)
{
// nop
}
ini_category_consumer
ini_consumer
::
begin_map
()
{
return
{
this
,
current_key_
};
}
void
ini_consumer
::
key
(
std
::
string
name
)
{
current_key_
=
std
::
move
(
name
);
}
void
ini_consumer
::
value_impl
(
config_value
&&
x
)
{
using
dict_type
=
config_value
::
dictionary
;
auto
dict
=
get_if
<
dict_type
>
(
&
x
);
if
(
dict
==
nullptr
)
{
warnings_
.
emplace_back
(
make_error
(
pec
::
type_mismatch
,
"expected a dictionary at top level"
));
return
;
}
if
(
current_key_
!=
"global"
)
{
auto
&
dst
=
cfg_
.
emplace
(
current_key_
,
dict_type
{}).
first
->
second
;
if
(
dict
!=
nullptr
&&
!
dict
->
empty
()
&&
holds_alternative
<
dict_type
>
(
dst
))
{
auto
&
dst_dict
=
get
<
dict_type
>
(
dst
);
// We need to "merge" values into the destination, because it can already
// contain any number of unrelated entries.
for
(
auto
&
entry
:
*
dict
)
dst_dict
.
insert_or_assign
(
entry
.
first
,
std
::
move
(
entry
.
second
));
}
}
else
{
std
::
string
prev_key
;
swap
(
current_key_
,
prev_key
);
for
(
auto
&
entry
:
*
dict
)
{
if
(
holds_alternative
<
dict_type
>
(
entry
.
second
))
{
// Recurse into top-level maps.
current_key_
=
std
::
move
(
entry
.
first
);
value_impl
(
std
::
move
(
entry
.
second
));
}
else
{
cfg_
.
insert_or_assign
(
entry
.
first
,
std
::
move
(
entry
.
second
));
}
}
swap
(
prev_key
,
current_key_
);
}
}
}
// namespace caf::detail
libcaf_core/test/detail/ini_consumer.cpp
deleted
100644 → 0
View file @
13b5d670
/******************************************************************************
* ____ _ _____ *
* / ___| / \ | ___| 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. *
******************************************************************************/
#define CAF_SUITE detail.ini_consumer
#include "caf/detail/ini_consumer.hpp"
#include "caf/test/dsl.hpp"
#include "caf/detail/parser/read_ini.hpp"
using
std
::
string
;
using
namespace
caf
;
// List-of-strings.
using
ls
=
std
::
vector
<
std
::
string
>
;
namespace
{
constexpr
const
string_view
test_ini
=
R"(
is_server=true
port=4242
nodes=["sun", "venus", ]
[logger]
file-name = "foobar.ini" ; our file name
[scheduler] ; more settings
timing = 2us ; using microsecond resolution
)"
;
constexpr
const
string_view
test_ini2
=
R"(
is_server = true
logger = {
file-name = "foobar.ini"
}
port = 4242
scheduler = {
timing = 2us,
}
nodes = ["sun", "venus"]
)"
;
struct
fixture
{
config_option_set
options
;
settings
config
;
fixture
()
{
options
.
add
<
bool
>
(
"global"
,
"is_server"
,
"enables server mode"
)
.
add
<
uint16_t
>
(
"global"
,
"port"
,
"sets local or remote port"
)
.
add
<
ls
>
(
"global"
,
"nodes"
,
"list of remote nodes"
)
.
add
<
string
>
(
"logger"
,
"file-name"
,
"log output file"
)
.
add
<
int
>
(
"scheduler"
,
"padding"
,
"some integer"
)
.
add
<
timespan
>
(
"scheduler"
,
"timing"
,
"some timespan"
);
}
};
}
// namespace
CAF_TEST_FIXTURE_SCOPE
(
ini_consumer_tests
,
fixture
)
CAF_TEST
(
ini_value_consumer
)
{
string_view
str
=
R"("hello world")"
;
detail
::
ini_value_consumer
consumer
;
string_parser_state
res
{
str
.
begin
(),
str
.
end
()};
detail
::
parser
::
read_ini_value
(
res
,
consumer
);
CAF_CHECK_EQUAL
(
res
.
code
,
pec
::
success
);
CAF_CHECK_EQUAL
(
get
<
string
>
(
consumer
.
result
),
"hello world"
);
}
CAF_TEST
(
ini_consumer
)
{
string_view
str
=
test_ini
;
detail
::
ini_consumer
consumer
{
options
,
config
};
string_parser_state
res
{
str
.
begin
(),
str
.
end
()};
detail
::
parser
::
read_ini
(
res
,
consumer
);
CAF_CHECK_EQUAL
(
res
.
code
,
pec
::
success
);
CAF_CHECK_EQUAL
(
get
<
bool
>
(
config
,
"is_server"
),
true
);
CAF_CHECK_EQUAL
(
get
<
uint16_t
>
(
config
,
"port"
),
4242u
);
CAF_CHECK_EQUAL
(
get
<
ls
>
(
config
,
"nodes"
),
ls
({
"sun"
,
"venus"
}));
CAF_CHECK_EQUAL
(
get
<
string
>
(
config
,
"logger.file-name"
),
"foobar.ini"
);
CAF_MESSAGE
(
config
);
CAF_CHECK_EQUAL
(
get
<
timespan
>
(
config
,
"scheduler.timing"
),
timespan
(
2000
));
}
CAF_TEST
(
simplified
syntax
)
{
CAF_MESSAGE
(
"read test_ini"
);
{
detail
::
ini_consumer
consumer
{
options
,
config
};
string_parser_state
res
{
test_ini
.
begin
(),
test_ini
.
end
()};
detail
::
parser
::
read_ini
(
res
,
consumer
);
CAF_CHECK_EQUAL
(
res
.
code
,
pec
::
success
);
}
settings
config2
;
CAF_MESSAGE
(
"read test_ini2"
);
{
detail
::
ini_consumer
consumer
{
options
,
config2
};
string_parser_state
res
{
test_ini2
.
begin
(),
test_ini2
.
end
()};
detail
::
parser
::
read_ini
(
res
,
consumer
);
CAF_CHECK_EQUAL
(
res
.
code
,
pec
::
success
);
}
CAF_CHECK_EQUAL
(
config
,
config2
);
}
CAF_TEST_FIXTURE_SCOPE_END
()
libcaf_core/test/detail/parser/read_ini.cpp
deleted
100644 → 0
View file @
13b5d670
/******************************************************************************
* ____ _ _____ *
* / ___| / \ | ___| 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. *
******************************************************************************/
#define CAF_SUITE detail.parser.read_ini
#include "caf/detail/parser/read_ini.hpp"
#include "caf/test/dsl.hpp"
#include <string>
#include <vector>
#include "caf/config_value.hpp"
#include "caf/parser_state.hpp"
#include "caf/pec.hpp"
#include "caf/string_view.hpp"
using
namespace
caf
;
namespace
{
using
log_type
=
std
::
vector
<
std
::
string
>
;
struct
test_consumer
{
log_type
log
;
test_consumer
()
=
default
;
test_consumer
(
const
test_consumer
&
)
=
delete
;
test_consumer
&
operator
=
(
const
test_consumer
&
)
=
delete
;
test_consumer
&
begin_map
()
{
log
.
emplace_back
(
"{"
);
return
*
this
;
}
void
end_map
()
{
log
.
emplace_back
(
"}"
);
}
test_consumer
&
begin_list
()
{
log
.
emplace_back
(
"["
);
return
*
this
;
}
void
end_list
()
{
log
.
emplace_back
(
"]"
);
}
void
key
(
std
::
string
name
)
{
add_entry
(
"key: "
,
std
::
move
(
name
));
}
template
<
class
T
>
void
value
(
T
x
)
{
config_value
cv
{
std
::
move
(
x
)};
std
::
string
entry
=
"value ("
;
entry
+=
cv
.
type_name
();
entry
+=
"): "
;
entry
+=
to_string
(
cv
);
log
.
emplace_back
(
std
::
move
(
entry
));
}
void
add_entry
(
const
char
*
prefix
,
std
::
string
str
)
{
str
.
insert
(
0
,
prefix
);
log
.
emplace_back
(
std
::
move
(
str
));
}
};
struct
fixture
{
expected
<
log_type
>
parse
(
string_view
str
,
bool
expect_success
=
true
)
{
test_consumer
f
;
string_parser_state
res
{
str
.
begin
(),
str
.
end
()};
detail
::
parser
::
read_ini
(
res
,
f
);
if
((
res
.
code
==
pec
::
success
)
!=
expect_success
)
{
CAF_MESSAGE
(
"unexpected parser result state: "
<<
res
.
code
);
CAF_MESSAGE
(
"input remainder: "
<<
std
::
string
(
res
.
i
,
res
.
e
));
}
return
std
::
move
(
f
.
log
);
}
};
template
<
class
...
Ts
>
log_type
make_log
(
Ts
&&
...
xs
)
{
return
log_type
{
std
::
forward
<
Ts
>
(
xs
)...};
}
// Tests basic functionality.
constexpr
const
string_view
ini0
=
R"(
[1group]
1value=321
[_foo]
_bar=11
[logger]
padding= 10
file-name = "foobar.ini" ; our file name
[scheduler] ; more settings
timing = 2us ; using microsecond resolution
x_ =.123
some-bool=true
some-other-bool=false
some-list=[
; here we have some list entries
123,
1..3,
23 ; twenty-three!
,2..4..2,
"abc", ; some comment and a trailing comma
]
some-map{
; here we have some list entries
entry1=123,
entry2=23 ; twenty-three! btw, comma is not mandatory
entry3= "abc" , ; some comment and a trailing comma
}
[middleman]
preconnect=[<
tcp://localhost:8080
>,<udp://remotehost?trust=false>]
)"
;
// clang-format off
const
auto
ini0_log
=
make_log
(
"key: 1group"
,
"{"
,
"key: 1value"
,
"value (integer): 321"
,
"}"
,
"key: _foo"
,
"{"
,
"key: _bar"
,
"value (integer): 11"
,
"}"
,
"key: logger"
,
"{"
,
"key: padding"
,
"value (integer): 10"
,
"key: file-name"
,
"value (string):
\"
foobar.ini
\"
"
,
"}"
,
"key: scheduler"
,
"{"
,
"key: timing"
,
"value (timespan): 2us"
,
"key: x_"
,
"value (real): "
+
deep_to_string
(
.123
),
"key: some-bool"
,
"value (boolean): true"
,
"key: some-other-bool"
,
"value (boolean): false"
,
"key: some-list"
,
"["
,
"value (integer): 123"
,
"value (integer): 1"
,
"value (integer): 2"
,
"value (integer): 3"
,
"value (integer): 23"
,
"value (integer): 2"
,
"value (integer): 4"
,
"value (string):
\"
abc
\"
"
,
"]"
,
"key: some-map"
,
"{"
,
"key: entry1"
,
"value (integer): 123"
,
"key: entry2"
,
"value (integer): 23"
,
"key: entry3"
,
"value (string):
\"
abc
\"
"
,
"}"
,
"}"
,
"key: middleman"
,
"{"
,
"key: preconnect"
,
"["
,
"value (uri): tcp://localhost:8080"
,
"value (uri): udp://remotehost?trust=false"
,
"]"
,
"}"
);
// clang-format on
// Tests nested parameters.
constexpr
const
string_view
ini1
=
R"(
foo {
bar = {
value1 = 1
}
value2 = 2
}
[bar.foo]
value3 = 3
)"
;
// clang-format off
const
auto
ini1_log
=
make_log
(
"key: global"
,
"{"
,
"key: foo"
,
"{"
,
"key: bar"
,
"{"
,
"key: value1"
,
"value (integer): 1"
,
"}"
,
"key: value2"
,
"value (integer): 2"
,
"}"
,
"}"
,
"key: bar"
,
"{"
,
"key: foo"
,
"{"
,
"key: value3"
,
"value (integer): 3"
,
"}"
,
"}"
);
// clang-format on
constexpr
const
string_view
ini2
=
"#"
;
const
auto
ini2_log
=
make_log
();
constexpr
const
string_view
ini3
=
"; foobar
\n
!"
;
const
auto
ini3_log
=
make_log
();
}
// namespace
CAF_TEST_FIXTURE_SCOPE
(
read_ini_tests
,
fixture
)
CAF_TEST
(
empty
inis
)
{
CAF_CHECK_EQUAL
(
parse
(
";foo"
),
make_log
());
CAF_CHECK_EQUAL
(
parse
(
""
),
make_log
());
CAF_CHECK_EQUAL
(
parse
(
" "
),
make_log
());
CAF_CHECK_EQUAL
(
parse
(
"
\n
"
),
make_log
());
CAF_CHECK_EQUAL
(
parse
(
";hello
\n
;world"
),
make_log
());
}
CAF_TEST
(
section
with
valid
key
-
value
pairs
)
{
CAF_CHECK_EQUAL
(
parse
(
"[foo]"
),
make_log
(
"key: foo"
,
"{"
,
"}"
));
CAF_CHECK_EQUAL
(
parse
(
" [foo]"
),
make_log
(
"key: foo"
,
"{"
,
"}"
));
CAF_CHECK_EQUAL
(
parse
(
" [ foo] "
),
make_log
(
"key: foo"
,
"{"
,
"}"
));
CAF_CHECK_EQUAL
(
parse
(
" [ foo ] "
),
make_log
(
"key: foo"
,
"{"
,
"}"
));
CAF_CHECK_EQUAL
(
parse
(
"
\n
[a-b];foo
\n
;bar"
),
make_log
(
"key: a-b"
,
"{"
,
"}"
));
CAF_CHECK_EQUAL
(
parse
(
ini0
),
ini0_log
);
CAF_CHECK_EQUAL
(
parse
(
ini1
),
ini1_log
);
}
CAF_TEST
(
invalid
inis
)
{
CAF_CHECK_EQUAL
(
parse
(
ini2
),
ini2_log
);
CAF_CHECK_EQUAL
(
parse
(
ini3
),
ini3_log
);
}
CAF_TEST
(
integer
keys
are
legal
in
INI
syntax
)
{
static
constexpr
string_view
ini
=
R"__(
[foo.bar]
1 = 10
2 = 20
)__"
;
// clang-format off
auto
log
=
make_log
(
"key: foo"
,
"{"
,
"key: bar"
,
"{"
,
"key: 1"
,
"value (integer): 10"
,
"key: 2"
,
"value (integer): 20"
,
"}"
,
"}"
);
// clang-format on
CAF_CHECK_EQUAL
(
parse
(
ini
),
log
);
}
CAF_TEST
(
integer
keys
are
legal
in
config
syntax
)
{
static
constexpr
string_view
ini
=
R"__(
foo {
bar {
1 = 10
2 = 20
}
}
)__"
;
// clang-format off
auto
log
=
make_log
(
"key: global"
,
"{"
,
"key: foo"
,
"{"
,
"key: bar"
,
"{"
,
"key: 1"
,
"value (integer): 10"
,
"key: 2"
,
"value (integer): 20"
,
"}"
,
"}"
,
"}"
);
// clang-format on
CAF_CHECK_EQUAL
(
parse
(
ini
),
log
);
}
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