35 #include <boost/algorithm/string/predicate.hpp>
36 #include <boost/filesystem/operations.hpp>
37 #include <boost/program_options.hpp>
52 using log4cpp::Priority;
69 const string& parent_project_name,
const string& parent_project_vcs_version,
70 const string& parent_module_version,
const string& parent_module_name,
71 const vector<string>& search_dirs,
const Priority::Value& elements_loglevel)
72 : m_program_ptr(move(program_ptr))
73 , m_parent_project_version(move(parent_project_version))
74 , m_parent_project_name(move(parent_project_name))
75 , m_parent_project_vcs_version(move(parent_project_vcs_version))
76 , m_parent_module_version(move(parent_module_version))
77 , m_parent_module_name(move(parent_module_name))
78 , m_search_dirs(move(search_dirs))
80 , m_elements_loglevel(move(elements_loglevel)) {}
100 conf_name.replace_extension(
"conf");
104 if (default_config_file.empty()) {
105 log.warn() <<
"The " << conf_name <<
" default configuration file cannot be found in:";
107 log.warn() <<
" " << loc;
109 if (not module_name.
empty()) {
110 conf_name =
Path::Item{module_name} / conf_name;
111 log.warn() <<
"Trying " << conf_name <<
".";
116 if (default_config_file.empty()) {
117 log.debug() <<
"Couldn't find " << conf_name <<
" default configuration file.";
119 log.debug() <<
"Found " << conf_name <<
" default configuration file at " << default_config_file;
122 return default_config_file;
129 return full_path.filename();
136 return full_path.parent_path();
139 template <
class charT>
141 const boost::program_options::basic_parsed_options<charT>& cmd_parsed_options) {
143 for (
const auto& o : cmd_parsed_options.options) {
144 if (o.string_key ==
"config-file") {
145 if (o.value.size() != 1) {
146 cerr <<
"Wrong usage of the --config-file option" << endl;
150 if (not boost::filesystem::exists(conf_file)) {
151 cerr <<
"The " << conf_file <<
" configuration file doesn't exist!" << endl;
167 using boost::program_options::collect_unrecognized;
168 using boost::program_options::command_line_parser;
169 using boost::program_options::include_positional;
170 using boost::program_options::notify;
171 using boost::program_options::parse_config_file;
172 using boost::program_options::store;
173 using boost::program_options::value;
178 string default_log_level =
"INFO";
185 cmd_only_generic_options.add_options()(
"version",
"Print version string")(
"help",
"Produce help message")(
186 "config-file", value<Path::Item>()->default_value(default_config_file),
"Name of a configuration file");
190 cmd_and_file_generic_options.add_options()(
"log-level", value<string>()->default_value(default_log_level),
191 "Log level: FATAL, ERROR, WARN, INFO (default), DEBUG")(
192 "log-file", value<Path::Item>(),
"Name of a log file");
197 for (
auto o : cmd_only_generic_options.options()) {
198 all_generic_options.add(o);
200 for (
auto o : cmd_and_file_generic_options.options()) {
201 all_generic_options.add(o);
206 auto specific_options =
m_program_ptr->defineSpecificProgramOptions();
207 auto program_arguments =
m_program_ptr->defineProgramArguments();
209 all_specific_options.add(specific_options).add(program_arguments.first);
213 all_cmd_and_file_options.add(cmd_and_file_generic_options).add(all_specific_options);
217 help_options.add(all_generic_options).add(all_specific_options);
220 auto cmd_parsed_options =
221 command_line_parser(argc, argv).options(cmd_only_generic_options).allow_unregistered().run();
225 store(cmd_parsed_options, var_map);
228 if (var_map.count(
"help") > 0) {
229 cout << help_options << endl;
234 if (var_map.count(
"version") > 0) {
241 auto config_file = var_map.at(
"config-file").as<
Path::Item>();
245 auto leftover_cmd_options = collect_unrecognized(cmd_parsed_options.options, include_positional);
249 auto parsed_cmdline_options = command_line_parser(leftover_cmd_options)
250 .options(all_cmd_and_file_options)
251 .positional(program_arguments.second)
254 store(parsed_cmdline_options, var_map);
257 if (not config_file.empty() and boost::filesystem::exists(config_file)) {
260 auto parsed_cfgfile_options = parse_config_file(ifs, all_cmd_and_file_options);
261 store(parsed_cfgfile_options, var_map);
266 if (boost::starts_with(
e.what(),
"unrecognised option") or
267 boost::starts_with(
e.what(),
"too many positional options")) {
313 stringstream log_message{};
318 if (v.second.value().type() ==
typeid(
string)) {
319 log_message << v.first <<
" = " << v.second.as<
string>();
321 }
else if (v.second.value().type() ==
typeid(double)) {
322 log_message << v.first <<
" = " << v.second.as<
double>();
324 }
else if (v.second.value().type() ==
typeid(int64_t)) {
325 log_message << v.first <<
" = " << v.second.as<int64_t>();
327 }
else if (v.second.value().type() ==
typeid(int)) {
328 log_message << v.first <<
" = " << v.second.as<
int>();
330 }
else if (v.second.value().type() ==
typeid(bool)) {
331 log_message << v.first <<
" = " << v.second.as<
bool>();
333 }
else if (v.second.value().type() ==
typeid(
Path::Item)) {
334 log_message << v.first <<
" = " << v.second.as<
Path::Item>();
336 }
else if (v.second.value().type() ==
typeid(
vector<int>)) {
338 stringstream vecContent{};
339 for (
const auto& i : intVec) {
340 vecContent <<
" " << i;
342 log_message << v.first <<
" = {" << vecContent.str() <<
" }";
346 stringstream vecContent{};
347 for (
const auto& i : intVec) {
348 vecContent <<
" " << i;
350 log_message << v.first <<
" = {" << vecContent.str() <<
" }";
354 stringstream vecContent{};
355 for (
const auto& i : intVec) {
356 vecContent <<
" " << i;
358 log_message << v.first <<
" = {" << vecContent.str() <<
" }";
361 log_message <<
"Option " << v.first <<
" of type " << v.second.value().type().name()
362 <<
" not supported in logging !" << endl;
374 log.debug() <<
"##########################################################";
376 log.debug() <<
"# Environment of the Run";
377 log.debug() <<
"# ---------------------------";
381 log.debug() << v.second <<
": " <<
m_env[v.second];
395 return boost::filesystem::complete(s);
401 if (local_search_paths[0] != this_parent_path) {
402 auto b = local_search_paths.
begin();
403 local_search_paths.
insert(b, this_parent_path);
410 if (
m_env[v.second].exists()) {
429 auto exit_code =
e.exitCode();
430 log.fatal() <<
"# Elements Exception : " <<
e.what();
435 string logging_level;
459 log.debug() <<
"# Exit Code: " << int(c);
491 log.fatal() <<
"Crash detected";
492 log.fatal() <<
"This is the back trace:";
494 log.fatal() << level;
502 log.fatal() <<
"# Elements Exception : " << exc1.
what();
509 log.fatal() <<
"# Standard Exception : " << exc2.
what();
513 log.fatal() <<
"# An exception of unknown type occurred, "
514 <<
"i.e., an exception not deriving from std::exception ";