/usr/include/hocon/program_options.hpp is in libcpp-hocon-dev 0.1.6-1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 | #pragma once
#include "config.hpp"
#include "config_list.hpp"
#include <boost/format.hpp>
#include <boost/program_options.hpp>
namespace hocon { namespace program_options {
namespace po = boost::program_options;
template<class charT>
po::basic_parsed_options<charT>
parse_hocon(shared_config cfg, const po::options_description& desc, bool allow_unregistered) {
po::parsed_options result(&desc);
std::map<std::string, shared_config> to_do;
to_do.emplace("", cfg);
while (!to_do.empty()) {
auto iter = to_do.begin();
auto prefix = iter->first;
auto cfg = iter->second;
to_do.erase(iter);
for (const auto& entry : cfg->entry_set()) {
po::option opt;
if (prefix.empty()) {
opt.string_key = entry.first;
} else {
opt.string_key = prefix + "." + entry.first;
}
// Skips options that are not registered in the description.
// This is different behavior than the built in program_options
// parsers, which pass the options along somehow. But for now
// it stops an exception from being thrown if there is an unknown
// item in the config file.
if (allow_unregistered && !desc.find_nothrow(opt.string_key, false)) {
continue;
}
if (entry.second->value_type() == config_value::type::LIST) {
// if this is a list, we want to check if any of the entries are
// objects. If so, we need to further expand those sub-trees, with
// list indices being expanded into our key
auto list = std::dynamic_pointer_cast<const config_list>(entry.second);
for (size_t i = 0; i < list->size(); ++i) {
const auto& value = list->get(i);
if (value->value_type() == config_value::type::LIST ||
value->value_type() == config_value::type::OBJECT) {
boost::throw_exception(po::invalid_config_file_syntax(list->transform_to_string(), po::invalid_syntax::unrecognized_line));
} else {
opt.value.push_back(value->transform_to_string());
}
}
} else {
opt.value.push_back(entry.second->transform_to_string());
}
if (!opt.value.empty()) {
result.options.emplace_back(std::move(opt));
}
}
}
// let Boost convert our utf-8 entries to wchars if needed
return po::basic_parsed_options<charT>(result);
}
template<class charT>
po::basic_parsed_options<charT>
parse_file(std::basic_string<charT> file_basename, const po::options_description& desc, bool allow_unregistered=false) {
shared_config cfg = config::parse_file_any_syntax(file_basename)->resolve();
return parse_hocon<charT>(cfg, desc, allow_unregistered);
}
template<class charT>
po::basic_parsed_options<charT>
parse_string(std::basic_string<charT> s, const po::options_description& desc, bool allow_unregistered=false) {
shared_config cfg = config::parse_string(s)->resolve();
return parse_hocon<charT>(cfg, desc, allow_unregistered);
}
}}
|