From 87ea6254c6447524d6f9387dee3f8ffb05cd833d Mon Sep 17 00:00:00 2001 From: Rainer Kartmann <rainer.kartmann@student.kit.edu> Date: Fri, 5 Apr 2019 16:13:00 +0200 Subject: [PATCH] Extended RuntimeEnvironment Optional caption, access to help flag, printOptions() to use boost::program_options' printing --- VirtualRobot/RuntimeEnvironment.cpp | 114 +++++++++++++++++++++------- VirtualRobot/RuntimeEnvironment.h | 26 ++++++- 2 files changed, 108 insertions(+), 32 deletions(-) diff --git a/VirtualRobot/RuntimeEnvironment.cpp b/VirtualRobot/RuntimeEnvironment.cpp index fa53ce2f8..a9e07a85f 100644 --- a/VirtualRobot/RuntimeEnvironment.cpp +++ b/VirtualRobot/RuntimeEnvironment.cpp @@ -11,13 +11,18 @@ namespace VirtualRobot { + bool RuntimeEnvironment::pathInitialized = false; + + std::string RuntimeEnvironment::caption = "Simox runtime options"; + std::vector< std::pair<std::string, std::string> > RuntimeEnvironment::processKeys; std::vector< std::pair<std::string, std::string> > RuntimeEnvironment::processFlags; - std::vector< std::string > RuntimeEnvironment::unrecognizedOptions; + std::vector< std::string > RuntimeEnvironment::dataPaths; + std::vector< std::string > RuntimeEnvironment::unrecognizedOptions; std::map< std::string, std::string > RuntimeEnvironment::keyValues; std::set< std::string > RuntimeEnvironment::flags; - bool RuntimeEnvironment::pathInitialized = false; + bool RuntimeEnvironment::helpFlag = false; void RuntimeEnvironment::init() { @@ -102,7 +107,7 @@ namespace VirtualRobot } } } - + bool RuntimeEnvironment::getDataFileAbsolute(std::string& fileName) { if (!pathInitialized) @@ -155,19 +160,29 @@ namespace VirtualRobot return false; } - void RuntimeEnvironment::processCommandLine(int argc, char* argv[]) { if (!pathInitialized) { init(); } + + const boost::program_options::options_description description = makeOptionsDescription(); + + const boost::program_options::parsed_options parsed = + boost::program_options::command_line_parser(argc, argv).options(description).allow_unregistered().run(); + processParsedOptions(parsed); + } + + boost::program_options::options_description RuntimeEnvironment::makeOptionsDescription() + { // Declare the supported options. - boost::program_options::options_description desc("Simox runtime options"); + + boost::program_options::options_description desc(caption); desc.add_options() ("help", "Simox command line parser: Set options with '--key value'\n") - ("data-path", boost::program_options::value< std::vector< std::string > >()->composing(), + ("data-path", boost::program_options::value<std::vector<std::string>>()->composing(), "Set data path. Multiple data paths are allowed.") ; @@ -184,15 +199,16 @@ namespace VirtualRobot (item.first.c_str(), item.second.c_str()) ; } - - boost::program_options::parsed_options parsed = - boost::program_options::command_line_parser(argc, argv).options(desc).allow_unregistered().run(); - + return desc; + } + + void RuntimeEnvironment::processParsedOptions(const boost::program_options::parsed_options& parsed) + { boost::program_options::variables_map vm; //boost::program_options::store(boost::program_options::parse_command_line(argc, argv, desc), vm); boost::program_options::store(parsed, vm); boost::program_options::notify(vm); - + // process data-path entries if (vm.count("data-path")) { @@ -234,6 +250,7 @@ namespace VirtualRobot flags.insert(flag.first); } } + helpFlag = vm.count("help") > 0; // collect unrecognized arguments std::vector<std::string> options = boost::program_options::collect_unrecognized( @@ -244,7 +261,7 @@ namespace VirtualRobot unrecognizedOptions.push_back(option); } } - + void RuntimeEnvironment::addKeyValuePair(const std::string& key, const std::string& value) { keyValues[key] = value; @@ -280,6 +297,11 @@ namespace VirtualRobot return dataPaths; } + + void RuntimeEnvironment::setCaption(const std::string& caption) + { + RuntimeEnvironment::caption = caption; + } bool RuntimeEnvironment::addDataPath(const std::string& path, bool quiet) { @@ -305,6 +327,26 @@ namespace VirtualRobot return false; } + static std::size_t getMaxLength(const std::vector<std::pair<std::string, std::string>>& items) + { + std::size_t max = 0; + for (const auto& key : items) + { + max = std::max(max, key.first.size()); + } + return max; + } + + static std::string padding(std::size_t current, std::size_t target, char c = ' ') + { + std::stringstream ss; + while (target --> current) + { + ss << c; + } + return ss.str(); + } + void RuntimeEnvironment::print() { if (!pathInitialized) @@ -320,25 +362,29 @@ namespace VirtualRobot cout << " * " << dataPath << endl; } - if (processKeys.size() > 0) - { - cout << "Known keys:" << endl; - - for (const auto& processKey : processKeys) - { - cout << " * " << processKey.first << endl; - } - } + const std::size_t descriptionOffset = std::max( + getMaxLength(processKeys), getMaxLength(processFlags)) + 4; - if (processFlags.size() > 0) + auto printDescriptions = [&descriptionOffset]( + const std::vector<std::pair<std::string, std::string>>& items, + const std::string& name) { - cout << "Known flags:" << endl; - - for (const auto& processFlag : processFlags) + if (items.size() > 0) { - cout << " * " << processFlag.first << endl; + cout << "Known " << name << ":" << endl; + + for (const auto& item : items) + { + cout << " * " << item.first + << padding(item.first.size(), descriptionOffset) + << item.second << endl; + } } - } + }; + + printDescriptions(processKeys, "keys"); + printDescriptions(processFlags, "flags"); + if (keyValues.size() > 0) { @@ -354,7 +400,7 @@ namespace VirtualRobot cout << "Parsed flags:" << endl; for (const auto& flag : flags) { - cout << " * " << flag; + cout << " * " << flag << endl; } } @@ -368,6 +414,11 @@ namespace VirtualRobot } } } + + void RuntimeEnvironment::printOptions(std::ostream& os) + { + os << makeOptionsDescription() << std::endl; + } void RuntimeEnvironment::considerKey(const std::string& key, const std::string& description) { @@ -388,6 +439,11 @@ namespace VirtualRobot { return flags.find(flag) != flags.end(); } + + bool RuntimeEnvironment::hasHelpFlag() + { + return helpFlag; + } float RuntimeEnvironment::toFloat(const std::string& s) @@ -496,7 +552,7 @@ namespace VirtualRobot void RuntimeEnvironment::cleanup() { - VisualizationFactoryPtr visualizationFactory = VisualizationFactory::first(NULL); + VisualizationFactoryPtr visualizationFactory = VisualizationFactory::first(nullptr); if (visualizationFactory) { diff --git a/VirtualRobot/RuntimeEnvironment.h b/VirtualRobot/RuntimeEnvironment.h index 654408512..a38c2f139 100644 --- a/VirtualRobot/RuntimeEnvironment.h +++ b/VirtualRobot/RuntimeEnvironment.h @@ -24,11 +24,14 @@ #include "VirtualRobot.h" +#include <map> +#include <set> #include <string> #include <vector> -#include <map> + #include <Eigen/Core> + namespace VirtualRobot { /*! @@ -45,6 +48,9 @@ namespace VirtualRobot //! Return vector of all data paths. static std::vector< std::string > getDataPaths(); + /// Set the runtime environment caption. + static void setCaption(const std::string& caption); + /*! * Add a path to global data path vector. * These paths are searched within the getDataFileAbsolute() method. @@ -95,6 +101,8 @@ namespace VirtualRobot /// Indicate whether the given flag was specified. static bool hasFlag(const std::string& flag); + /// Indicate whether the 'help' flag was specified. + static bool hasHelpFlag(); //! Return all key value pairs static std::map<std::string, std::string> getKeyValuePairs(); @@ -131,8 +139,12 @@ namespace VirtualRobot */ static std::string checkParameter(const std::string& key, const std::string& standardValue = ""); - //! Print status + //! Print status. static void print(); + + //! Print the command line options (as printed by boost::program_options) to os. + static void printOptions(std::ostream& os = std::cout); + /*! * \brief Free all resources. @@ -140,14 +152,21 @@ namespace VirtualRobot */ static void cleanup(); + protected: RuntimeEnvironment() {} virtual ~RuntimeEnvironment() {} + static bool pathInitialized; + static void init(); + /// Make the options description based on the added keys and flags. + static boost::program_options::options_description makeOptionsDescription(); + static void processParsedOptions(const boost::program_options::parsed_options& parsed); - + static std::string caption; + /// Pairs of (key, description). If not given, description is empty. static std::vector< std::pair<std::string, std::string> > processKeys; /// Pairs of (flag, description). If not given, description is empty. @@ -158,6 +177,7 @@ namespace VirtualRobot static std::map< std::string, std::string > keyValues; static std::set< std::string > flags; + static bool helpFlag; }; } // namespace -- GitLab