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 ";