Program Listing for File Configurator.cpp¶
↰ Return to documentation for file (src/Configurator.cpp)
#include "include/Configurator.hpp"
#include <iostream>
namespace Nextsim {
std::vector<std::unique_ptr<std::istream>> Configurator::sources;
int Configurator::m_argc;
char** Configurator::m_argv;
boost::program_options::variables_map Configurator::parse(
const boost::program_options::options_description& opt)
{
boost::program_options::variables_map vm;
// Parse the command file for any overrides
int use_argc;
char** use_argv;
if (m_argc && m_argv) {
use_argc = m_argc;
use_argv = m_argv;
} else {
// Use a fake command line to ensure at least one parse happens in all cases
use_argc = 1;
char name[] = { 'n', 'e', 'x', 't', 's', 'i', 'm', 'd', 'g', '\0' };
char* fake_argv[] = { name, nullptr };
use_argv = fake_argv;
}
auto parsed = boost::program_options::command_line_parser(use_argc, use_argv)
.options(opt)
.style(boost::program_options::command_line_style::
unix_style) // | po::command_line_style::allow_long_disguise)
.allow_unregistered()
.run();
boost::program_options::store(parsed, vm);
// Parse the named streams for configuration
for (auto iter = sources.begin(); iter != sources.end(); ++iter) {
try {
boost::program_options::store(
boost::program_options::parse_config_file(**iter, opt, true), vm);
} catch (std::exception& e) {
// Echo the exception, but carry on
std::cerr << e.what() << std::endl;
}
// Once the stream has been parsed, clear all flags (especially EOF)
// and seek back to the start.
(*iter)->clear();
(*iter)->seekg(0, std::ios_base::beg);
}
return vm;
}
} /* namespace Nextsim */