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