You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

181 lines
5.0 KiB

/*
* 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,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")
;
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