Browse Source

adding documentation that is visible to doxygen, adding logging

tempestpy_adaptions
gereon 12 years ago
parent
commit
39cd84a469
  1. 24
      src/utility/settings.cpp
  2. 90
      src/utility/settings.h

24
src/utility/settings.cpp

@ -7,6 +7,10 @@
#include "src/utility/settings.h" #include "src/utility/settings.h"
#include "log4cplus/logger.h"
#include "log4cplus/loggingmacros.h"
extern log4cplus::Logger logger;
namespace mrmc { namespace mrmc {
namespace settings { namespace settings {
@ -17,6 +21,7 @@ namespace bpo = boost::program_options;
*/ */
bpo::options_description* mrmc::settings::Settings::cli = nullptr; bpo::options_description* mrmc::settings::Settings::cli = nullptr;
bpo::options_description* mrmc::settings::Settings::conf = nullptr; bpo::options_description* mrmc::settings::Settings::conf = nullptr;
std::string mrmc::settings::Settings::binaryName = "";
mrmc::settings::Settings* mrmc::settings::Settings::inst = nullptr; mrmc::settings::Settings* mrmc::settings::Settings::inst = nullptr;
/*! /*!
@ -35,6 +40,7 @@ mrmc::settings::Settings* mrmc::settings::Settings::inst = nullptr;
Settings::Settings(const int argc, const char* argv[], const char* filename) Settings::Settings(const int argc, const char* argv[], const char* filename)
: configfile("Config Options"), generic("Generic Options"), commandline("Commandline Options") : configfile("Config Options"), generic("Generic Options"), commandline("Commandline Options")
{ {
Settings::binaryName = std::string(argv[0]);
try try
{ {
//! Initially fill description objects and call register callbacks //! Initially fill description objects and call register callbacks
@ -73,29 +79,35 @@ Settings::Settings(const int argc, const char* argv[], const char* filename)
//! Finalize parsed options, check for specified requirements //! Finalize parsed options, check for specified requirements
bpo::notify(this->vm); bpo::notify(this->vm);
LOG4CPLUS_DEBUG(logger, "Finished loading config.");
} }
catch (bpo::reading_file e) catch (bpo::reading_file e)
{ {
std::cerr << "Could not read config file " << filename << std::endl; std::cerr << "Could not read config file " << filename << std::endl;
LOG4CPLUS_ERROR(logger, "Could not read config file");
} }
catch (bpo::required_option e) catch (bpo::required_option e)
{ {
std::cerr << "required option: " << e.what() << std::endl;
std::cerr << "Required option: " << e.what() << std::endl;
LOG4CPLUS_ERROR(logger, "Required option: " << e.what());
throw mrmc::exceptions::InvalidSettings(); throw mrmc::exceptions::InvalidSettings();
} }
catch (bpo::validation_error e) catch (bpo::validation_error e)
{ {
std::cerr << "Validation failed: " << e.what() << std::endl; std::cerr << "Validation failed: " << e.what() << std::endl;
LOG4CPLUS_ERROR(logger, "Validation failed: " << e.what());
throw mrmc::exceptions::InvalidSettings(); throw mrmc::exceptions::InvalidSettings();
} }
catch (bpo::invalid_command_line_syntax e) catch (bpo::invalid_command_line_syntax e)
{ {
std::cerr << "Invalid command line syntax: " << e.what() << std::endl; std::cerr << "Invalid command line syntax: " << e.what() << std::endl;
LOG4CPLUS_ERROR(logger, "Invalid command line syntax: " << e.what());
throw mrmc::exceptions::InvalidSettings(); throw mrmc::exceptions::InvalidSettings();
} }
catch (bpo::error e) catch (bpo::error e)
{ {
std::cerr << e.what() << std::endl; std::cerr << e.what() << std::endl;
LOG4CPLUS_ERROR(logger, "Unknown error: " << e.what());
throw mrmc::exceptions::InvalidSettings(); throw mrmc::exceptions::InvalidSettings();
} }
} }
@ -106,6 +118,7 @@ Settings::Settings(const int argc, const char* argv[], const char* filename)
*/ */
void Settings::initDescriptions() void Settings::initDescriptions()
{ {
LOG4CPLUS_DEBUG(logger, "Initializing descriptions.");
this->commandline.add_options() this->commandline.add_options()
("help,h", "produce help message") ("help,h", "produce help message")
("verbose,v", "be verbose") ("verbose,v", "be verbose")
@ -154,6 +167,7 @@ void Settings::initDescriptions()
*/ */
void Settings::firstRun(const int argc, const char* argv[], const char* filename) void Settings::firstRun(const int argc, const char* argv[], const char* filename)
{ {
LOG4CPLUS_DEBUG(logger, "Performing first run.");
//! parse command line //! 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::cli)).allow_unregistered().run(), this->vm);
@ -197,7 +211,7 @@ void Settings::firstRun(const int argc, const char* argv[], const char* filename
catch (boost::bad_any_cast e) catch (boost::bad_any_cast e)
{ {
std::cerr << "An intermediate callback failed." << std::endl; std::cerr << "An intermediate callback failed." << std::endl;
std::cerr << e.what() << std::endl;
LOG4CPLUS_ERROR(logger, "An intermediate callback failed.\n" << e.what());
} }
} }
} }
@ -211,6 +225,7 @@ void Settings::firstRun(const int argc, const char* argv[], const char* filename
*/ */
void Settings::secondRun(const int argc, const char* argv[], const char* filename) void Settings::secondRun(const int argc, const char* argv[], const char* filename)
{ {
LOG4CPLUS_DEBUG(logger, "Performing second run.");
//! Parse command line //! 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::cli)).positional(this->positional).run(), this->vm);
/* /*
@ -238,6 +253,7 @@ void Settings::secondRun(const int argc, const char* argv[], const char* filenam
if (! (*fptr)(this->vm)) if (! (*fptr)(this->vm))
{ {
std::cerr << "Custom option checker failed." << std::endl; std::cerr << "Custom option checker failed." << std::endl;
LOG4CPLUS_ERROR(logger, "A checker callback returned false.");
throw mrmc::exceptions::InvalidSettings(); throw mrmc::exceptions::InvalidSettings();
} }
} }
@ -253,8 +269,8 @@ void Settings::secondRun(const int argc, const char* argv[], const char* filenam
*/ */
std::ostream& help(std::ostream& os) std::ostream& help(std::ostream& os)
{ {
os << "Usage: <binary> [options] <transition file> <label file>" << std::endl;
os << *(mrmc::settings::Settings::cli) << std::endl;;
os << "Usage: " << mrmc::settings::Settings::binaryName << " [options] <transition file> <label file>" << std::endl;
os << *(mrmc::settings::Settings::cli) << std::endl;
return os; return os;
} }

90
src/utility/settings.h

@ -24,6 +24,12 @@ namespace mrmc {
namespace settings { namespace settings {
namespace bpo = boost::program_options; namespace bpo = boost::program_options;
/*
* Sorry for very long comment at this point (for the class), but all
* methods are private, hence there is no other place to explain the
* inner workings of this class that are necessary to understand the
* callback concept...
*/
/*! /*!
* @brief Simple wrapper around boost::program_options to handle configuration options. * @brief Simple wrapper around boost::program_options to handle configuration options.
* *
@ -31,43 +37,68 @@ namespace settings {
* commandline and additionally load options from a file. * commandline and additionally load options from a file.
* *
* It is meant to be used as a singleton. Call * It is meant to be used as a singleton. Call
* @code mrmc::settings::Settings::instance(argc, argv, filename) @endcode
* @code mrmc::settings::newInstance(argc, argv, filename) @endcode
* to initialize it and obtain an instance for the first time. * to initialize it and obtain an instance for the first time.
* Afterwards, it is possible to use
* Afterwards, use
* @code mrmc::settings::instance() @endcode * @code mrmc::settings::instance() @endcode
*
* This class can be customized by other parts of the software using
* callbacks. There are three types of callbacks: register,
* intermediate and checker.
*
* The (private) constructor will start with filling the internal
* options_description object. There are a few generic options like
* --help or --verbose. Then if calls all register callbacks that may
* add more options.
*
* Then, it will start with a sloppy parsing run, allowing unregistered
* options and ignoring further constraints from the options_description
* objects.
*
* After that, it will call all intermediate callbacks. They can
* inspect the options from the first run and add more options, e.g.
* enable more options for a specific component that has been enabled.
*
* Using the new options_description objects, the constructor performs
* a second run. This time, it will not allow unregistered options and
* will check for required and positional arguments.
*
* Finally, all checker callbacks will be called. They can check the
* final options for more complex requirements. If any of those checker
* callbacks returns false, a InvalidSettings exception will be thrown.
*/ */
class Settings class Settings
{ {
public: public:
/*!
* @brief Get value of a generic option.
*/
template <typename T>
const T& get(const std::string &name) const {
std::cerr << "get(" << name << ")" << std::endl;
if (this->vm.count(name) == 0) throw mrmc::exceptions::InvalidSettings();
return this->vm[name].as<T>();
}
/*!
* @brief Get value of a generic option.
*/
template <typename T>
const T& get(const std::string &name) const {
std::cerr << "get(" << name << ")" << std::endl;
if (this->vm.count(name) == 0) throw mrmc::exceptions::InvalidSettings();
return this->vm[name].as<T>();
}
/*!
* @brief Get value of string option
*/
const std::string& getString(const std::string &name) const {
return this->get<std::string>(name);
}
/*!
* @brief Get value of string option
*/
const std::string& getString(const std::string &name) const {
return this->get<std::string>(name);
}
/*!
* @brief Check if an option is set
*/
const bool isSet(const std::string &name) const {
return this->vm.count(name) > 0;
}
/*!
* @brief Check if an option is set
*/
const bool isSet(const std::string &name) const {
return this->vm.count(name) > 0;
}
friend std::ostream& help(std::ostream& os);
friend std::ostream& helpConfigfile(std::ostream& os);
friend Settings* instance();
friend Settings* newInstance(const int argc, const char* argv[], const char* filename);
friend std::ostream& help(std::ostream& os);
friend std::ostream& helpConfigfile(std::ostream& os);
friend Settings* instance();
friend Settings* newInstance(const int argc, const char* argv[], const char* filename);
private: private:
/*! /*!
@ -121,6 +152,11 @@ namespace settings {
*/ */
bpo::variables_map vm; bpo::variables_map vm;
/*!
* @brief name of binary
*/
static std::string binaryName;
/*! /*!
* @brief actual instance of this class. * @brief actual instance of this class.
*/ */

Loading…
Cancel
Save