Commit d0423bac authored by Dominik Charousset's avatar Dominik Charousset

Add public API for reading CAF config files

parent a6bf1cd3
......@@ -331,6 +331,63 @@ public:
static std::string render_pec(uint8_t, atom_value, const message&);
// -- config file parsing ----------------------------------------------------
/// Tries to open `filename` and parses its content as CAF config file.
/// @param filename Relative or absolute path to the config file.
/// @returns A ::settings dictionary with the parsed content of `filename` on
/// success, an ::error otherwise.
static expected<settings> parse_config_file(const char* filename);
/// Tries to open `filename` and parses its content as CAF config file. Also
/// type-checks user-defined parameters in `opts`.
/// @param filename Relative or absolute path to the config file.
/// @param opts User-defined config options for type checking.
/// @returns A ::settings dictionary with the parsed content of `filename` on
/// success, an ::error otherwise.
static expected<settings> parse_config_file(const char* filename,
const config_option_set& opts);
/// Tries to open `filename`, parses its content as CAF config file and
/// stores all entries in `result` (overrides conflicting entries). Also
/// type-checks user-defined parameters in `opts`.
/// @param filename Relative or absolute path to the config file.
/// @param opts User-defined config options for type checking.
/// @param result Storage for parsed entries. Note that `result` will contain
/// partial results if this function returns an error.
/// @returns A default-constructed ::error on success, the error code of the
/// parser otherwise.
static error parse_config_file(const char* filename,
const config_option_set& opts,
settings& result);
/// Parses the content of `source` using CAF's config format.
/// @param source Character sequence in CAF's config format.
/// @returns A ::settings dictionary with the parsed content of `source` on
/// success, an ::error otherwise.
static expected<settings> parse_config(std::istream& source);
/// Parses the content of `source` using CAF's config format. Also
// type-checks user-defined parameters in `opts`.
/// @param source Character sequence in CAF's config format.
/// @param opts User-defined config options for type checking.
/// @returns A ::settings dictionary with the parsed content of `source` on
/// success, an ::error otherwise.
static expected<settings> parse_config(std::istream& source,
const config_option_set& opts);
/// Parses the content of `source` using CAF's config format and stores all
/// entries in `result` (overrides conflicting entries). Also type-checks
/// user-defined parameters in `opts`.
/// @param source Character sequence in CAF's config format.
/// @param opts User-defined config options for type checking.
/// @param result Storage for parsed entries. Note that `result` will contain
/// partial results if this function returns an error.
/// @returns A default-constructed ::error on success, the error code of the
/// parser otherwise.
static error parse_config(std::istream& source, const config_option_set& opts,
settings& result);
protected:
virtual std::string make_help_text(const std::vector<message::cli_arg>&);
......
......@@ -192,7 +192,7 @@ public:
// -- constructors, destructors, and assignment operators --------------------
ini_consumer(config_option_set& options, settings& cfg);
ini_consumer(const config_option_set& options, settings& cfg);
ini_consumer(ini_consumer&&) = default;
......@@ -207,7 +207,7 @@ public:
private:
// -- member variables -------------------------------------------------------
config_option_set& options_;
const config_option_set& options_;
settings& cfg_;
std::string current_key_;
std::vector<error> warnings_;
......
......@@ -342,14 +342,9 @@ void print(const config_value::dictionary& xs, indentation indent) {
error actor_system_config::parse(string_list args, std::istream& ini) {
// Content of the INI file overrides hard-coded defaults.
if (ini.good()) {
detail::ini_consumer consumer{custom_options_, content};
detail::parser::state<ini_iter, ini_sentinel> res;
res.i = ini_iter{&ini};
detail::parser::read_ini(res, consumer);
if (res.i != res.e)
return make_error(res.code, res.line, res.column);
}
if (ini.good())
if (auto err = parse_config(ini, custom_options_, content))
return err;
// CLI options override the content of the INI file.
using std::make_move_iterator;
auto res = custom_options_.parse(content, args);
......@@ -464,6 +459,49 @@ std::string actor_system_config::render_pec(uint8_t x, atom_value,
meta::omittable_if_empty(), xs);
}
expected<settings>
actor_system_config::parse_config_file(const char* filename) {
config_option_set dummy;
return parse_config_file(filename, dummy);
}
expected<settings>
actor_system_config::parse_config_file(const char* filename,
const config_option_set& opts) {
std::ifstream f{filename};
if (!f.is_open())
return make_error(sec::cannot_open_file, filename);
return parse_config(f, opts);
}
expected<settings> actor_system_config::parse_config(std::istream& source) {
config_option_set dummy;
return parse_config(source, dummy);
}
expected<settings>
actor_system_config::parse_config(std::istream& source,
const config_option_set& opts) {
settings result;
if (auto err = parse_config(source, opts, result))
return err;
return result;
}
error actor_system_config::parse_config(std::istream& source,
const config_option_set& opts,
settings& result) {
if (!source)
return make_error(sec::runtime_error, "source stream invalid");
detail::ini_consumer consumer{opts, result};
detail::parser::state<ini_iter, ini_sentinel> res;
res.i = ini_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);
......
......@@ -152,10 +152,8 @@ ini_consumer* ini_category_consumer::dparent() {
// -- ini_consumer -------------------------------------------------------------
ini_consumer::ini_consumer(config_option_set& options, settings& cfg)
: options_(options),
cfg_(cfg),
current_key_("global") {
ini_consumer::ini_consumer(const config_option_set& options, settings& cfg)
: options_(options), cfg_(cfg), current_key_("global") {
// nop
}
......
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