From 58ff007654ac2c5e0ea11dda0382d74630899fe6 Mon Sep 17 00:00:00 2001 From: PBerger Date: Sat, 7 Sep 2013 16:03:04 +0200 Subject: [PATCH] Fixed the Settings structure Fixed the standard settings to comply with the infrastructure Former-commit-id: 9ab888c2df98df0c6247940d86d93846c378b6ce --- src/settings/Argument.h | 12 +++++------ src/settings/ArgumentBuilder.h | 4 ++-- src/settings/Option.h | 7 +++---- src/settings/Settings.cpp | 22 ++++++++++++++++++-- src/settings/Settings.h | 20 +++++++----------- src/storm.cpp | 10 +++++++-- src/utility/StormOptions.cpp | 6 +++--- test/functional/storm-functional-tests.cpp | 10 +++++++-- test/performance/storm-performance-tests.cpp | 8 ++++++- 9 files changed, 65 insertions(+), 34 deletions(-) diff --git a/src/settings/Argument.h b/src/settings/Argument.h index 07ec9bc73..141ea5de1 100644 --- a/src/settings/Argument.h +++ b/src/settings/Argument.h @@ -156,9 +156,9 @@ namespace storm { virtual std::string getValueAsString() const override { switch (this->argumentType) { case ArgumentType::String: - return ArgumentTypeInferation::inferToString(ArgumentType::String, this->argumentValue); + return ArgumentTypeInferation::inferToString(ArgumentType::String, this->getArgumentValue()); case ArgumentType::Boolean: { - bool iValue = ArgumentTypeInferation::inferToBoolean(ArgumentType::Boolean, this->argumentValue); + bool iValue = ArgumentTypeInferation::inferToBoolean(ArgumentType::Boolean, this->getArgumentValue()); if (iValue) { return "true"; } else { @@ -175,7 +175,7 @@ namespace storm { virtual int_fast64_t getValueAsInteger() const override { switch (this->argumentType) { case ArgumentType::Integer: - return ArgumentTypeInferation::inferToInteger(ArgumentType::Integer, this->argumentValue); + return ArgumentTypeInferation::inferToInteger(ArgumentType::Integer, this->getArgumentValue()); default: throw storm::exceptions::IllegalFunctionCallException() << "Error: getValueAsInteger() was called on Argument \"" << getArgumentName() << "\" of Type \"" << ArgumentTypeHelper::toString(getArgumentType()) << "\"!"; @@ -185,7 +185,7 @@ namespace storm { virtual uint_fast64_t getValueAsUnsignedInteger() const override { switch (this->argumentType) { case ArgumentType::UnsignedInteger: - return ArgumentTypeInferation::inferToUnsignedInteger(ArgumentType::UnsignedInteger, this->argumentValue); + return ArgumentTypeInferation::inferToUnsignedInteger(ArgumentType::UnsignedInteger, this->getArgumentValue()); default: throw storm::exceptions::IllegalFunctionCallException() << "Error: getValueAsUnsignedInteger() was called on Argument \"" << getArgumentName() << "\" of Type \"" << ArgumentTypeHelper::toString(getArgumentType()) << "\"!"; @@ -195,7 +195,7 @@ namespace storm { virtual double getValueAsDouble() const override { switch (this->argumentType) { case ArgumentType::Double: - return ArgumentTypeInferation::inferToDouble(ArgumentType::Double, this->argumentValue); + return ArgumentTypeInferation::inferToDouble(ArgumentType::Double, this->getArgumentValue()); default: throw storm::exceptions::IllegalFunctionCallException() << "Error: getValueAsDouble() was called on Argument \"" << getArgumentName() << "\" of Type \"" << ArgumentTypeHelper::toString(getArgumentType()) << "\"!"; @@ -205,7 +205,7 @@ namespace storm { virtual bool getValueAsBoolean() const override { switch (this->argumentType) { case ArgumentType::Boolean: - return ArgumentTypeInferation::inferToBoolean(ArgumentType::Boolean, this->argumentValue); + return ArgumentTypeInferation::inferToBoolean(ArgumentType::Boolean, this->getArgumentValue()); default: throw storm::exceptions::IllegalFunctionCallException() << "Error: getValueAsBoolean() was called on Argument \"" << getArgumentName() << "\" of Type \"" << ArgumentTypeHelper::toString(getArgumentType()) << "\"!"; diff --git a/src/settings/ArgumentBuilder.h b/src/settings/ArgumentBuilder.h index 754aadd5e..166b4b969 100644 --- a/src/settings/ArgumentBuilder.h +++ b/src/settings/ArgumentBuilder.h @@ -94,12 +94,12 @@ namespace storm { #define MACROsetDefaultValue(funcName, funcType) ArgumentBuilder& PPCAT(setDefaultValue, funcName) (funcType const& defaultValue) { \ if (this->argumentType != ArgumentType::funcName) { \ - throw storm::exceptions::IllegalFunctionCallException() << "Error: You tried adding a default Value for a \"" << ArgumentTypeHelper::toString(ArgumentType::String) << "\" Argument, but this Argument is configured to be of Type \"" << ArgumentTypeHelper::toString(this->argumentType) << "\"."; \ + throw storm::exceptions::IllegalFunctionCallException() << "Error: You tried adding a default Value for a \"" << ArgumentTypeHelper::toString(ArgumentType::String) << "\" Argument, but the Argument \"" << this->argumentName << "\" is configured to be of Type \"" << ArgumentTypeHelper::toString(this->argumentType) << "\"."; \ } \ PPCAT(this->defaultValue_, funcName) = defaultValue; \ std::string errorMessageTarget = ""; \ if (!this->validateDefaultForEach(errorMessageTarget)) { \ - throw storm::exceptions::IllegalArgumentValueException() << "Error: You tried adding a default Value for an Argument, but a Validation Function rejected it:\r\n" << errorMessageTarget; \ + throw storm::exceptions::IllegalArgumentValueException() << "Error: You tried adding a default Value for the Argument \"" << this->argumentName << "\", but a Validation Function rejected it:\r\n" << errorMessageTarget; \ } \ this->hasDefaultValue = true; \ return *this; \ diff --git a/src/settings/Option.h b/src/settings/Option.h index 20ae74f87..a652ba62b 100644 --- a/src/settings/Option.h +++ b/src/settings/Option.h @@ -230,11 +230,10 @@ namespace storm { std::unordered_set argumentNameSet; for (auto i = arguments.begin(); i != arguments.end(); ++i) { bool isCurrentArgumentOptional = i->get()->getIsOptional(); - // If this Option is optional, all arguments must have default values - if (!this->isRequired && !i->get()->getHasDefaultValue()) { + //if (!this->isRequired && !i->get()->getHasDefaultValue()) { // LOG - throw storm::exceptions::IllegalArgumentException() << "Error: The Argument Vector specified for Option \"" << getLongName() << "\" is invalid!\nIt contains an argument without a default value, but the containing option is optional and therefor requires all arguments to provide default values."; - } + // throw storm::exceptions::IllegalArgumentException() << "Error: The Argument Vector specified for Option \"" << getLongName() << "\" is invalid!\nIt contains an argument without a default value, but the containing option is optional and therefor requires all arguments to provide default values."; + //} if (!isCurrentArgumentOptional && lastEntryWasOptional) { // LOG diff --git a/src/settings/Settings.cpp b/src/settings/Settings.cpp index b244eb1e2..126addaf2 100644 --- a/src/settings/Settings.cpp +++ b/src/settings/Settings.cpp @@ -170,7 +170,9 @@ void storm::settings::Settings::parseCommandLine(int const argc, char const * co } else { // Set defaults on optional values for (auto i = 0; i < it->second.get()->getArgumentCount(); ++i) { - it->second.get()->getArgument(i).setFromDefaultValue(); + if (it->second.get()->getArgument(i).getHasDefaultValue()) { + it->second.get()->getArgument(i).setFromDefaultValue(); + } } } } @@ -179,7 +181,23 @@ void storm::settings::Settings::parseCommandLine(int const argc, char const * co bool storm::settings::Settings::registerNewModule(ModuleRegistrationFunction_t registrationFunction) { Settings* myInstance = Settings::getInstance(); - return registrationFunction(myInstance); + bool result = false; + try { + result = registrationFunction(myInstance); + } catch (storm::exceptions::IllegalArgumentException e) { + std::cout << "Internal Error while setting up available Options!" << std::endl << "IllegalArgumentException: " << e.what() << "." << std::endl; + std::cout << std::endl << myInstance->getHelpText(); + return false; + } catch (storm::exceptions::IllegalArgumentValueException e) { + std::cout << "Internal Error while setting up available Options!" << std::endl << "IllegalArgumentValueException: " << e.what() << "." << std::endl; + std::cout << std::endl << myInstance->getHelpText(); + return false; + } catch (storm::exceptions::IllegalFunctionCallException e) { + std::cout << "Internal Error while setting up available Options!" << std::endl << "IllegalFunctionCallException: " << e.what() << "." << std::endl; + std::cout << std::endl << myInstance->getHelpText(); + return false; + } + return result; } storm::settings::Settings* storm::settings::Settings::getInstance() { diff --git a/src/settings/Settings.h b/src/settings/Settings.h index c90183e20..ced1d9fd0 100644 --- a/src/settings/Settings.h +++ b/src/settings/Settings.h @@ -46,20 +46,16 @@ namespace settings { class Destroyer; /*! - * @brief Wrapper around boost::program_options to handle configuration options. + * @brief Settings class with command line parser and type validation * - * This class uses boost::program_options to read options from the - * commandline and additionally load options from a file. * * It is meant to be used as a singleton. Call - * @code storm::settings::newInstance(argc, argv, filename) @endcode - * to initialize it and obtain an instance for the first time. - * Afterwards, use - * @code storm::settings::instance() @endcode + * @code storm::settings::Settings::getInstance() @endcode + * to initialize it and obtain an instance. * * This class can be customized by other parts of the software using * option modules. An option module can be anything that implements the - * interface specified by registerModule(). + * interface specified by registerModule() and does a static initialization call to this function. */ class Settings { public: @@ -221,7 +217,7 @@ namespace settings { Option& getByLongName(std::string const& longName) const { auto longNameIterator = this->options.find(storm::utility::StringHelper::stringToLower(longName)); if (longNameIterator == this->options.end()) { - throw storm::exceptions::IllegalArgumentException() << "This Accumulator does not contain an Option named \"" << longName << "\"!"; + throw storm::exceptions::IllegalArgumentException() << "This program does not contain an Option named \"" << longName << "\"!"; } return *longNameIterator->second.get(); } @@ -234,7 +230,7 @@ namespace settings { Option* getPtrByLongName(std::string const& longName) const { auto longNameIterator = this->options.find(storm::utility::StringHelper::stringToLower(longName)); if (longNameIterator == this->options.end()) { - throw storm::exceptions::IllegalArgumentException() << "This Accumulator does not contain an Option named \"" << longName << "\"!"; + throw storm::exceptions::IllegalArgumentException() << "This program does not contain an Option named \"" << longName << "\"!"; } return longNameIterator->second.get(); } @@ -246,7 +242,7 @@ namespace settings { Option& getByShortName(std::string const& shortName) const { auto shortNameIterator = this->shortNames.find(storm::utility::StringHelper::stringToLower(shortName)); if (shortNameIterator == this->shortNames.end()) { - throw storm::exceptions::IllegalArgumentException() << "This Accumulator does not contain an Option with ShortName \"" << shortName << "\"!"; + throw storm::exceptions::IllegalArgumentException() << "This program does not contain an Option with ShortName \"" << shortName << "\"!"; } return *(this->options.find(shortNameIterator->second)->second.get()); } @@ -258,7 +254,7 @@ namespace settings { Option* getPtrByShortName(std::string const& shortName) const { auto shortNameIterator = this->shortNames.find(storm::utility::StringHelper::stringToLower(shortName)); if (shortNameIterator == this->shortNames.end()) { - throw storm::exceptions::IllegalArgumentException() << "This Accumulator does not contain an Option with ShortName \"" << shortName << "\"!"; + throw storm::exceptions::IllegalArgumentException() << "This program does not contain an Option with ShortName \"" << shortName << "\"!"; } return this->options.find(shortNameIterator->second)->second.get(); } diff --git a/src/storm.cpp b/src/storm.cpp index f93ce240e..3ec2bba2a 100644 --- a/src/storm.cpp +++ b/src/storm.cpp @@ -281,8 +281,14 @@ int main(const int argc, const char* argv[]) { if (s->isSet("explicit")) { std::string const chosenTransitionSystemFile = s->getOptionByLongName("explicit").getArgument(0).getValueAsString(); std::string const chosenLabelingFile = s->getOptionByLongName("explicit").getArgument(1).getValueAsString(); - std::string const chosenStateRewardsFile = s->getOptionByLongName("stateRewards").getArgument(0).getValueAsString(); - std::string const chosenTransitionRewardsFile = s->getOptionByLongName("transitionRewards").getArgument(0).getValueAsString(); + std::string chosenStateRewardsFile = ""; + if (s->isSet("stateRewards")) { + chosenStateRewardsFile = s->getOptionByLongName("stateRewards").getArgument(0).getValueAsString(); + } + std::string chosenTransitionRewardsFile = ""; + if (s->isSet("transitionRewards")) { + chosenTransitionRewardsFile = s->getOptionByLongName("transitionRewards").getArgument(0).getValueAsString(); + } storm::parser::AutoParser parser(chosenTransitionSystemFile, chosenLabelingFile, chosenStateRewardsFile, chosenTransitionRewardsFile); diff --git a/src/utility/StormOptions.cpp b/src/utility/StormOptions.cpp index bb9006c1c..5b00e138d 100644 --- a/src/utility/StormOptions.cpp +++ b/src/utility/StormOptions.cpp @@ -12,14 +12,14 @@ bool storm::utility::StormOptions::optionsRegistered = storm::settings::Settings settings->addOption(storm::settings::OptionBuilder("StoRM Main", "prctl", "", "Evaluates the PRCTL Formulas given in the File").addArgument(storm::settings::ArgumentBuilder::createStringArgument("prctlFileName", "The path and name of the File to read PRCTL Formulas from").addValidationFunctionString(storm::settings::ArgumentValidators::existingReadableFileValidator()).build()).build()); settings->addOption(storm::settings::OptionBuilder("StoRM Main", "csl", "", "Evaluates the CSL Formulas given in the File").addArgument(storm::settings::ArgumentBuilder::createStringArgument("cslFileName", "The path and name of the File to read CSL Formulas from").addValidationFunctionString(storm::settings::ArgumentValidators::existingReadableFileValidator()).build()).build()); settings->addOption(storm::settings::OptionBuilder("StoRM Main", "ltl", "", "Evaluates the LTL Formulas given in the File").addArgument(storm::settings::ArgumentBuilder::createStringArgument("ltlFileName", "The path and name of the File to read LTL Formulas from").addValidationFunctionString(storm::settings::ArgumentValidators::existingReadableFileValidator()).build()).build()); - settings->addOption(storm::settings::OptionBuilder("StoRM Main", "transitionRewards", "", "If specified, the model will have these transition rewards").addArgument(storm::settings::ArgumentBuilder::createStringArgument("transitionRewardsFileName", "The path and name of the File to read the Transition Rewards from").addValidationFunctionString(storm::settings::ArgumentValidators::existingReadableFileValidator()).setDefaultValueString("").setIsOptional(true).build()).build()); - settings->addOption(storm::settings::OptionBuilder("StoRM Main", "stateRewards", "", "If specified, the model will have these state rewards").addArgument(storm::settings::ArgumentBuilder::createStringArgument("stateRewardsFileName", "The path and name of the File to read the State Rewards from").addValidationFunctionString(storm::settings::ArgumentValidators::existingReadableFileValidator()).setDefaultValueString("").setIsOptional(true).build()).build()); + settings->addOption(storm::settings::OptionBuilder("StoRM Main", "transitionRewards", "", "If specified, the model will have these transition rewards").addArgument(storm::settings::ArgumentBuilder::createStringArgument("transitionRewardsFileName", "The path and name of the File to read the Transition Rewards from").addValidationFunctionString(storm::settings::ArgumentValidators::existingReadableFileValidator()).build()).build()); + settings->addOption(storm::settings::OptionBuilder("StoRM Main", "stateRewards", "", "If specified, the model will have these state rewards").addArgument(storm::settings::ArgumentBuilder::createStringArgument("stateRewardsFileName", "The path and name of the File to read the State Rewards from").addValidationFunctionString(storm::settings::ArgumentValidators::existingReadableFileValidator()).build()).build()); settings->addOption(storm::settings::OptionBuilder("StoRM Main", "fixDeadlocks", "", "Insert Self-Loops for States with no outgoing transitions").build()); std::vector matrixLibrarys; matrixLibrarys.push_back("gmm++"); matrixLibrarys.push_back("native"); settings->addOption(storm::settings::OptionBuilder("StoRM Main", "matrixLibrary", "m", "Which matrix library is to be used in numerical solving").addArgument(storm::settings::ArgumentBuilder::createStringArgument("matrixLibraryName", "Name of a buildin Library").addValidationFunctionString(storm::settings::ArgumentValidators::stringInListValidator(matrixLibrarys)).setDefaultValueString("gmm++").build()).build()); - settings->addOption(storm::settings::OptionBuilder("StoRM Main", "useHeurisiticPresolve", "", "Sets whether heuristic methods should be applied to get better initial values for value iteration").build()); + settings->addOption(storm::settings::OptionBuilder("StoRM Main", "useHeuristicPresolve", "", "Sets whether heuristic methods should be applied to get better initial values for value iteration").build()); return true; }); \ No newline at end of file diff --git a/test/functional/storm-functional-tests.cpp b/test/functional/storm-functional-tests.cpp index 3b76dde31..5d77d5a81 100644 --- a/test/functional/storm-functional-tests.cpp +++ b/test/functional/storm-functional-tests.cpp @@ -34,8 +34,14 @@ void setUpLogging() { * Creates an empty settings object as the standard instance of the Settings class. */ void createEmptyOptions() { - const char* newArgv[] = {"storm-performance-tests"}; - storm::settings::Settings::parse(1, newArgv); + const char* newArgv[] = {"storm-functional-tests"}; + storm::settings::Settings* s = storm::settings::Settings::getInstance(); + try { + storm::settings::Settings::parse(1, newArgv); + } catch (storm::exceptions::OptionParserException& e) { + std::cout << "Could not recover from settings error: " << e.what() << "." << std::endl; + std::cout << std::endl << s->getHelpText(); + } } int main(int argc, char* argv[]) { diff --git a/test/performance/storm-performance-tests.cpp b/test/performance/storm-performance-tests.cpp index 0c143061c..dc5152855 100644 --- a/test/performance/storm-performance-tests.cpp +++ b/test/performance/storm-performance-tests.cpp @@ -35,7 +35,13 @@ void setUpLogging() { */ void createEmptyOptions() { const char* newArgv[] = {"storm-performance-tests", "--maxIterations", "20000"}; - storm::settings::Settings::parse(3, newArgv); + storm::settings::Settings* s = storm::settings::Settings::getInstance(); + try { + storm::settings::Settings::parse(3, newArgv); + } catch (storm::exceptions::OptionParserException& e) { + std::cout << "Could not recover from settings error: " << e.what() << "." << std::endl; + std::cout << std::endl << s->getHelpText(); + } } int main(int argc, char* argv[]) {