Browse Source
Changed Settings class to be singleton
Changed Settings class to be singleton
Changed a lot in the class structure of Settings: * Settings is now a Singleton. Obtain a new instance by Settings::instance(). * options_description objects are now static, thus a help message can be printed even if the constructor of Settings failes * As Settings has static members, a .cpp file became necessary, hence cmake should probably be run... * Help messages can be printed with new help and helpConfigfile routinestempestpy_adaptions
gereon
12 years ago
3 changed files with 248 additions and 107 deletions
@ -0,0 +1,179 @@ |
|||
/*
|
|||
* settings.cpp |
|||
* |
|||
* Created on: 22.11.2012 |
|||
* Author: Gereon Kremer |
|||
*/ |
|||
|
|||
#include "src/utility/settings.h"
|
|||
|
|||
//#include <iostream>
|
|||
//#include <boost/program_options.hpp>
|
|||
//#include "src/exceptions/InvalidSettings.h"
|
|||
|
|||
namespace mrmc { |
|||
namespace settings { |
|||
|
|||
namespace bpo = boost::program_options; |
|||
|
|||
bpo::options_description mrmc::settings::Settings::configfile("Config Options"); |
|||
bpo::options_description mrmc::settings::Settings::generic("Generic Options"); |
|||
bpo::options_description mrmc::settings::Settings::commandline("Commandline Options"); |
|||
bpo::positional_options_description mrmc::settings::Settings::positional; |
|||
|
|||
bpo::options_description mrmc::settings::Settings::cli; |
|||
bpo::options_description mrmc::settings::Settings::conf; |
|||
|
|||
mrmc::settings::Settings* mrmc::settings::Settings::inst = NULL; |
|||
|
|||
/*!
|
|||
* The constructor fills the option descriptions, parses the |
|||
* command line and the config file and puts the option values to |
|||
* our option mapping. |
|||
* |
|||
* If a configfile is set in the commandline, we load this one. |
|||
* Otherwise, if filename is not NULL, we load this one. Otherwise, |
|||
* we load no config file. |
|||
* |
|||
* @param argc should be argc passed to main function |
|||
* @param argv should be argv passed to main function |
|||
* @param filename either NULL or name of config file |
|||
*/ |
|||
Settings::Settings(const int argc, const char* argv[], const char* filename) |
|||
{ |
|||
try |
|||
{ |
|||
/*
|
|||
* load command line |
|||
*/ |
|||
bpo::store(bpo::command_line_parser(argc, argv).options(this->cli).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(), this->conf), this->vm, true); |
|||
} |
|||
else if (filename != NULL) |
|||
{ |
|||
bpo::store(bpo::parse_config_file<char>(filename, this->conf), this->vm, true); |
|||
} |
|||
bpo::notify(this->vm); |
|||
} |
|||
/*
|
|||
* catch errors... |
|||
*/ |
|||
catch (bpo::reading_file e) |
|||
{ |
|||
std::cout << "Could not read config file " << filename << std::endl; |
|||
} |
|||
catch (bpo::required_option e) |
|||
{ |
|||
if (! (this->vm.count("help") || this->vm.count("help-config"))) |
|||
{ |
|||
std::cout << e.what() << std::endl; |
|||
throw mrmc::exceptions::InvalidSettings(); |
|||
} |
|||
} |
|||
catch (bpo::error e) |
|||
{ |
|||
std::cout << "Some error occurred: " << e.what() << std::endl; |
|||
} |
|||
} |
|||
|
|||
/*!
|
|||
* Creates a new instance if necessary. When the instance is actually |
|||
* created for the first time, the internal options_description objects are |
|||
* initialized. |
|||
* |
|||
* If this function was already called and another instance is |
|||
* already present, the existing instance will be returned. In this |
|||
* case, better use the routine mrmc::settings::instance(). |
|||
* |
|||
* The constructor fills the option descriptions, parses the |
|||
* command line and the config file and puts the option values to |
|||
* our option mapping. |
|||
* |
|||
* If a configfile is set in the commandline, we load this one. |
|||
* Otherwise, if filename is not NULL, we load this one. Otherwise, |
|||
* we load no config file. |
|||
* |
|||
* @param argc should be argc passed to main function |
|||
* @param argv should be argv passed to main function |
|||
* @param filename either NULL or name of config file |
|||
* @return instance of Settings |
|||
*/ |
|||
Settings* Settings::instance(const int argc, const char* argv[], const char* filename) |
|||
{ |
|||
if (Settings::inst == NULL) { |
|||
/*
|
|||
* fill option descriptions |
|||
*/ |
|||
Settings::commandline.add_options() |
|||
("help", "produce help message") |
|||
("help-config", "produce help message about config file") |
|||
("configfile", bpo::value<std::string>(), "name of config file") |
|||
; |
|||
Settings::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") |
|||
; |
|||
Settings::configfile.add_options() |
|||
; |
|||
|
|||
/*
|
|||
* construct option descriptions for commandline and config file |
|||
*/ |
|||
Settings::cli.add(Settings::commandline).add(generic); |
|||
Settings::conf.add(Settings::configfile).add(generic); |
|||
|
|||
/*
|
|||
* Take care of positional arguments |
|||
*/ |
|||
Settings::positional.add("trafile", 1); |
|||
Settings::positional.add("labfile", 1); |
|||
|
|||
/*
|
|||
* Actually create new instance |
|||
*/ |
|||
Settings::inst = new Settings(argc, argv, filename); |
|||
} |
|||
return Settings::inst; |
|||
} |
|||
|
|||
/*!
|
|||
* Print a short general usage information consisting of the positional |
|||
* options and the list of available command line options. |
|||
* |
|||
* Use it like this: |
|||
* @code std::cout << mrmc::settings::help; @endcode |
|||
*/ |
|||
std::ostream& help(std::ostream& os) |
|||
{ |
|||
os << "Usage: <binary> [options] <transition file> <label file>" << std::endl; |
|||
os << Settings::cli << std::endl;; |
|||
return os; |
|||
} |
|||
|
|||
/*!
|
|||
* Print a list of available options for the config file. |
|||
* |
|||
* Use it like this: |
|||
* @code std::cout << mrmc::settings::helpConfigfile; @endcode |
|||
*/ |
|||
std::ostream& helpConfigfile(std::ostream& os) |
|||
{ |
|||
os << Settings::conf << std::endl;; |
|||
return os; |
|||
} |
|||
|
|||
/*!
|
|||
* @return current instance. |
|||
*/ |
|||
Settings* instance() |
|||
{ |
|||
return Settings::inst; |
|||
} |
|||
|
|||
} // namespace settings
|
|||
} // namespace mrmc
|
Write
Preview
Loading…
Cancel
Save
Reference in new issue