ores.cpp.service-app.config_parser_impl
Table of Contents
CLI/file parsing into options. component-service profile.
A service that adds a command-line option of its own supplies it from its
model, in two blocks on its component_overview.org:
<<paste:F98CC722-3E53-4B86-90E7-69EC5D25702E>>— the wholeoptions_descriptionconstruction. Block nameservice_app_config_option_decl. Supplying it replaces the defaultodline, so a service that declares its own options never has the default one built as well.<<paste:691CE3AB-6788-4E1C-8E8A-948CE6534C75>>— assignments from the parsed variables ontooptions r, emitted after the standard ones. Block nameservice_app_config_assignment.
The option's member on the struct is a third block, on the config_options_header archetype.
See the Template variable reference for the complete list of available variables and their semantics.
1. Template
The full template source. Edit here and re-tangle with
compass build --direct tangle_codegen_templates to regenerate
library/templates/cpp_service_config_parser.cpp.mustache.
{{! GENERATED FILE — tangled from projects/ores.codegen/library/templates/cpp_service_app.org. Edit the org source. }}
{{{cpp_license}}}
{{#component}}
#include "{{full_name}}/config/parser.hpp"
#include <ostream>
{{#has_positive_options}}
#include <cmath>
{{/has_positive_options}}
#include <boost/program_options.hpp>
#include <boost/throw_exception.hpp>
#include "{{full_name}}/config/parser_exception.hpp"
#include "ores.service/config/standard_service_options.hpp"
#include "ores.utility/version/version.hpp"
namespace {
const std::string more_information("Try '--help' for more information.");
const std::string product_version("{{full_name}} v" ORES_VERSION);
const std::string build_info(ores::utility::version::build_info());
const std::string usage_error_msg("Usage error: ");
using boost::program_options::options_description;
using {{namespace}}::config::options;
using {{namespace}}::config::parser_exception;
void print_help(const options_description& od, std::ostream& info) {
info << "{{brief}}" << std::endl << std::endl
<< "Usage: {{full_name}} [options]" << std::endl << std::endl
<< od << std::endl;
}
void version(std::ostream& info) {
info << product_version << std::endl
<< "Copyright (C) 2026 Marco Craveiro." << std::endl
<< "License GPLv3: GNU GPL version 3 or later " << "<http://gnu.org/licenses/gpl.html>."
<< std::endl
<< "This is free software: you are free to change and redistribute it."
<< std::endl << "There is NO WARRANTY, to the extent permitted by law."
<< std::endl;
if (!build_info.empty()) {
info << build_info << std::endl;
info << "IMPORTANT: build details are NOT for security purposes."
<< std::endl;
}
}
std::optional<options>
parse_arguments(const std::vector<std::string>& arguments, std::ostream& info) {
using ores::service::config::standard_service_options;
{{#has_service_options}}
options_description own("{{{service_options_group}}}");
own.add_options()
{{#service_options}}
("{{option}}", boost::program_options::value<{{{cpp_type}}}>()->default_value({{{default}}}),
"{{{help}}}")
{{/service_options}}
;
const auto od(standard_service_options::make_options_description("{{full_name}}.log", own));
{{/has_service_options}}
{{^has_service_options}}
{{^has_app_config_decl}}
const auto od(standard_service_options::make_options_description("{{full_name}}.log"));
{{/has_app_config_decl}}
{{/has_service_options}}
<<paste:F98CC722-3E53-4B86-90E7-69EC5D25702E>>
const auto vm(standard_service_options::parse(od, arguments, "{{name_upper}}"));
if (standard_service_options::wants_help(vm)) {
print_help(od, info);
return {};
}
if (standard_service_options::wants_version(vm)) {
version(info);
return {};
}
const auto std_opts(standard_service_options::read_options(vm));
options r;
r.logging = std_opts.logging;
r.nats = std_opts.nats;
r.database = std_opts.database;
{{#service_options}}
r.{{name}} = vm["{{option}}"].as<{{{cpp_type}}}>();
{{#positive}}
if (!std::isfinite(r.{{name}}) || r.{{name}} <= 0)
BOOST_THROW_EXCEPTION(parser_exception("--{{option}} must be a positive number."));
{{/positive}}
{{/service_options}}
<<paste:691CE3AB-6788-4E1C-8E8A-948CE6534C75>>
return r;
}
}
namespace {{namespace}}::config {
std::optional<options>
parser::parse(const std::vector<std::string>& arguments,
std::ostream& info, std::ostream& err) const {
try {
return parse_arguments(arguments, info);
} catch(const parser_exception& e) {
err << usage_error_msg << e.what() << std::endl
<< more_information << std::endl;
BOOST_THROW_EXCEPTION(e);
} catch (const boost::program_options::error& e) {
err << usage_error_msg << e.what() << std::endl
<< more_information << std::endl;
BOOST_THROW_EXCEPTION(parser_exception(e.what()));
}
}
}
{{/component}}
2. See also
- Parent facet: ores.cpp.service-app
- Template variable reference