|
|
@ -19,11 +19,12 @@ namespace bpo = boost::program_options; |
|
|
|
/*
|
|
|
|
* static initializers |
|
|
|
*/ |
|
|
|
std::unique_ptr<bpo::options_description> mrmc::settings::Settings::cli; |
|
|
|
std::unique_ptr<bpo::options_description> mrmc::settings::Settings::conf = nullptr; |
|
|
|
std::unique_ptr<bpo::options_description> mrmc::settings::Settings::desc = nullptr; |
|
|
|
std::string mrmc::settings::Settings::binaryName = ""; |
|
|
|
mrmc::settings::Settings* mrmc::settings::Settings::inst = nullptr; |
|
|
|
|
|
|
|
std::map< std::pair<std::string, std::string>, bpo::options_description* > mrmc::settings::Settings::modules; |
|
|
|
|
|
|
|
/*!
|
|
|
|
* The constructor fills the option descriptions, parses the |
|
|
|
* command line and the config file and puts the option values to |
|
|
@ -38,7 +39,6 @@ mrmc::settings::Settings* mrmc::settings::Settings::inst = nullptr; |
|
|
|
* @param filename either nullptr or name of config file |
|
|
|
*/ |
|
|
|
Settings::Settings(const int argc, const char* argv[], const char* filename) |
|
|
|
: configfile("Config Options"), generic("Generic Options"), commandline("Commandline Options") |
|
|
|
{ |
|
|
|
Settings::binaryName = std::string(argv[0]); |
|
|
|
try |
|
|
@ -49,22 +49,33 @@ Settings::Settings(const int argc, const char* argv[], const char* filename) |
|
|
|
//! Take care of positional arguments
|
|
|
|
Settings::positional.add("trafile", 1); |
|
|
|
Settings::positional.add("labfile", 1); |
|
|
|
|
|
|
|
//! Check module triggers
|
|
|
|
for (auto it : Settings::modules) |
|
|
|
{ |
|
|
|
std::pair< std::string, std::string > trigger = it.first; |
|
|
|
Settings::desc->add_options() |
|
|
|
(trigger.first.c_str(), bpo::value<std::string>(), trigger.second.c_str()) |
|
|
|
; |
|
|
|
} |
|
|
|
|
|
|
|
//! Create and fill collecting options descriptions
|
|
|
|
Settings::cli = std::unique_ptr<bpo::options_description>(new bpo::options_description()); |
|
|
|
Settings::cli->add(Settings::commandline).add(generic); |
|
|
|
Settings::conf = std::unique_ptr<bpo::options_description>(new bpo::options_description()); |
|
|
|
Settings::conf->add(Settings::configfile).add(generic); |
|
|
|
|
|
|
|
//! Perform first parse run and call intermediate callbacks
|
|
|
|
//! Perform first parse run
|
|
|
|
this->firstRun(argc, argv, filename); |
|
|
|
|
|
|
|
//! Rebuild collecting options descriptions
|
|
|
|
Settings::cli = std::unique_ptr<bpo::options_description>(new bpo::options_description()); |
|
|
|
Settings::cli->add(Settings::commandline).add(generic); |
|
|
|
|
|
|
|
Settings::conf = std::unique_ptr<bpo::options_description>(new bpo::options_description()); |
|
|
|
Settings::conf->add(Settings::configfile).add(generic); |
|
|
|
//! Check module triggers
|
|
|
|
for (auto it : Settings::modules) |
|
|
|
{ |
|
|
|
std::pair< std::string, std::string > trigger = it.first; |
|
|
|
if (this->vm.count(trigger.first)) |
|
|
|
{ |
|
|
|
if (this->vm[trigger.first].as<std::string>().compare(trigger.second) == 0) |
|
|
|
{ |
|
|
|
Settings::desc->add(*it.second); |
|
|
|
Settings::modules.erase(trigger); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
//! Stop if help is set
|
|
|
|
if ((this->vm.count("help") > 0) || (this->vm.count("help-config") > 0)) |
|
|
@ -77,7 +88,6 @@ Settings::Settings(const int argc, const char* argv[], const char* filename) |
|
|
|
|
|
|
|
//! Finalize parsed options, check for specified requirements
|
|
|
|
bpo::notify(this->vm); |
|
|
|
mrmc::settings::Callbacks::instance()->disabled = true; |
|
|
|
LOG4CPLUS_DEBUG(logger, "Finished loading config."); |
|
|
|
} |
|
|
|
catch (bpo::reading_file e) |
|
|
@ -118,43 +128,16 @@ Settings::Settings(const int argc, const char* argv[], const char* filename) |
|
|
|
void Settings::initDescriptions() |
|
|
|
{ |
|
|
|
LOG4CPLUS_DEBUG(logger, "Initializing descriptions."); |
|
|
|
this->commandline.add_options() |
|
|
|
Settings::desc = std::unique_ptr<bpo::options_description>(new bpo::options_description("Generic Options")); |
|
|
|
Settings::desc->add_options() |
|
|
|
("help,h", "produce help message") |
|
|
|
("verbose,v", "be verbose") |
|
|
|
("help-config", "produce help message about config file") |
|
|
|
("configfile,c", bpo::value<std::string>(), "name of config file") |
|
|
|
("test-prctl", bpo::value<std::string>(), "name of prctl file") |
|
|
|
; |
|
|
|
this->generic.add_options() |
|
|
|
("trafile", bpo::value<std::string>()->required(), "name of the .tra file") |
|
|
|
("labfile", bpo::value<std::string>()->required(), "name of the .lab file") |
|
|
|
; |
|
|
|
this->configfile.add_options() |
|
|
|
; |
|
|
|
|
|
|
|
/*
|
|
|
|
* Get Callbacks object, then iterate over and call all register callbacks. |
|
|
|
*/ |
|
|
|
Callbacks* cb = mrmc::settings::Callbacks::instance(); |
|
|
|
while (cb->registerList.size() > 0) |
|
|
|
{ |
|
|
|
CallbackType type = cb->registerList.front().first; |
|
|
|
RegisterCallback fptr = cb->registerList.front().second; |
|
|
|
cb->registerList.pop_front(); |
|
|
|
|
|
|
|
switch (type) |
|
|
|
{ |
|
|
|
case CB_CONFIG: |
|
|
|
(*fptr)(this->configfile); |
|
|
|
break; |
|
|
|
case CB_CLI: |
|
|
|
(*fptr)(this->commandline); |
|
|
|
break; |
|
|
|
case CB_GENERIC: |
|
|
|
(*fptr)(this->generic); |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/*!
|
|
|
@ -168,50 +151,18 @@ void Settings::firstRun(const int argc, const char* argv[], const char* filename |
|
|
|
{ |
|
|
|
LOG4CPLUS_DEBUG(logger, "Performing first run."); |
|
|
|
//! parse command line
|
|
|
|
bpo::store(bpo::command_line_parser(argc, argv).options(*(Settings::cli)).allow_unregistered().run(), this->vm); |
|
|
|
bpo::store(bpo::command_line_parser(argc, argv).options(*(Settings::desc)).allow_unregistered().run(), this->vm); |
|
|
|
|
|
|
|
/*
|
|
|
|
* load config file if specified |
|
|
|
*/ |
|
|
|
if (this->vm.count("configfile")) |
|
|
|
{ |
|
|
|
bpo::store(bpo::parse_config_file<char>(this->vm["configfile"].as<std::string>().c_str(), *(Settings::conf)), this->vm, true); |
|
|
|
bpo::store(bpo::parse_config_file<char>(this->vm["configfile"].as<std::string>().c_str(), *(Settings::desc)), this->vm, true); |
|
|
|
} |
|
|
|
else if (filename != NULL) |
|
|
|
{ |
|
|
|
bpo::store(bpo::parse_config_file<char>(filename, *(Settings::conf)), this->vm, true); |
|
|
|
} |
|
|
|
|
|
|
|
/*
|
|
|
|
* Call intermediate callbacks. |
|
|
|
*/ |
|
|
|
Callbacks* cb = mrmc::settings::Callbacks::instance(); |
|
|
|
while (cb->intermediateList.size() > 0) |
|
|
|
{ |
|
|
|
CallbackType type = cb->intermediateList.front().first; |
|
|
|
IntermediateCallback fptr = cb->intermediateList.front().second; |
|
|
|
cb->intermediateList.pop_front(); |
|
|
|
|
|
|
|
try |
|
|
|
{ |
|
|
|
switch (type) |
|
|
|
{ |
|
|
|
case CB_CONFIG: |
|
|
|
(*fptr)(&this->configfile, this->vm); |
|
|
|
break; |
|
|
|
case CB_CLI: |
|
|
|
(*fptr)(&this->commandline, this->vm); |
|
|
|
break; |
|
|
|
case CB_GENERIC: |
|
|
|
(*fptr)(&this->generic, this->vm); |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
catch (boost::bad_any_cast e) |
|
|
|
{ |
|
|
|
std::cerr << "An intermediate callback failed." << std::endl; |
|
|
|
LOG4CPLUS_ERROR(logger, "An intermediate callback failed.\n" << e.what()); |
|
|
|
} |
|
|
|
bpo::store(bpo::parse_config_file<char>(filename, *(Settings::desc)), this->vm, true); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
@ -226,35 +177,17 @@ void Settings::secondRun(const int argc, const char* argv[], const char* filenam |
|
|
|
{ |
|
|
|
LOG4CPLUS_DEBUG(logger, "Performing second run."); |
|
|
|
//! Parse command line
|
|
|
|
bpo::store(bpo::command_line_parser(argc, argv).options(*(Settings::cli)).positional(this->positional).run(), this->vm); |
|
|
|
bpo::store(bpo::command_line_parser(argc, argv).options(*(Settings::desc)).positional(this->positional).run(), this->vm); |
|
|
|
/*
|
|
|
|
* load config file if specified |
|
|
|
*/ |
|
|
|
if (this->vm.count("configfile")) |
|
|
|
{ |
|
|
|
bpo::store(bpo::parse_config_file<char>(this->vm["configfile"].as<std::string>().c_str(), *(Settings::conf)), this->vm, true); |
|
|
|
bpo::store(bpo::parse_config_file<char>(this->vm["configfile"].as<std::string>().c_str(), *(Settings::desc)), this->vm, true); |
|
|
|
} |
|
|
|
else if (filename != NULL) |
|
|
|
{ |
|
|
|
bpo::store(bpo::parse_config_file<char>(filename, *(Settings::conf)), this->vm, true); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Call checker callbacks. |
|
|
|
*/ |
|
|
|
Callbacks* cb = mrmc::settings::Callbacks::instance(); |
|
|
|
while (cb->checkerList.size() > 0) |
|
|
|
{ |
|
|
|
CheckerCallback fptr = cb->checkerList.front(); |
|
|
|
cb->checkerList.pop_front(); |
|
|
|
|
|
|
|
if (! (*fptr)(this->vm)) |
|
|
|
{ |
|
|
|
std::cerr << "Custom option checker failed." << std::endl; |
|
|
|
LOG4CPLUS_ERROR(logger, "A checker callback returned false."); |
|
|
|
throw mrmc::exceptions::InvalidSettings(); |
|
|
|
} |
|
|
|
bpo::store(bpo::parse_config_file<char>(filename, *(Settings::desc)), this->vm, true); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
@ -269,7 +202,13 @@ void Settings::secondRun(const int argc, const char* argv[], const char* filenam |
|
|
|
std::ostream& help(std::ostream& os) |
|
|
|
{ |
|
|
|
os << "Usage: " << mrmc::settings::Settings::binaryName << " [options] <transition file> <label file>" << std::endl; |
|
|
|
os << *(mrmc::settings::Settings::cli) << std::endl; |
|
|
|
os << *(mrmc::settings::Settings::desc) << std::endl; |
|
|
|
for (auto it : Settings::modules) |
|
|
|
{ |
|
|
|
std::pair< std::string, std::string > trigger = it.first; |
|
|
|
os << "If --" << trigger.first << " = " << trigger.second << ":" << std::endl; |
|
|
|
os << *(it.second) << std::endl; |
|
|
|
} |
|
|
|
return os; |
|
|
|
} |
|
|
|
|
|
|
@ -281,7 +220,7 @@ std::ostream& help(std::ostream& os) |
|
|
|
*/ |
|
|
|
std::ostream& helpConfigfile(std::ostream& os) |
|
|
|
{ |
|
|
|
os << *(mrmc::settings::Settings::conf) << std::endl;; |
|
|
|
os << *(mrmc::settings::Settings::desc) << std::endl;; |
|
|
|
return os; |
|
|
|
} |
|
|
|
|
|
|
|