X-Git-Url: https://gerrit.akraino.org/r/gitweb?a=blobdiff_plain;f=src%2Ftype3_AndroidCloud%2Fanbox-master%2Fsrc%2Fanbox%2Fcli.h;fp=src%2Ftype3_AndroidCloud%2Fanbox-master%2Fsrc%2Fanbox%2Fcli.h;h=09a06e3b4b3f47e515091a147105e8c2a2e74b5c;hb=e26c1ec581be598521517829adba8c8dd23a768f;hp=0000000000000000000000000000000000000000;hpb=6699c1aea74eeb0eb400e6299079f0c7576f716f;p=iec.git diff --git a/src/type3_AndroidCloud/anbox-master/src/anbox/cli.h b/src/type3_AndroidCloud/anbox-master/src/anbox/cli.h new file mode 100644 index 0000000..09a06e3 --- /dev/null +++ b/src/type3_AndroidCloud/anbox-master/src/anbox/cli.h @@ -0,0 +1,386 @@ +/* + * Copyright (C) 2016 Canonical, Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + * + * Authored by: Thomas Voß + * + */ +#ifndef BIOMETRY_UTIL_CLI_H_ +#define BIOMETRY_UTIL_CLI_H_ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "anbox/do_not_copy_or_move.h" +#include "anbox/optional.h" + +#include + +namespace anbox { +namespace cli { + +template +class SizeConstrainedString { + public: + SizeConstrainedString(const std::string& s) : s{s} { + if (s.size() > max) + throw std::logic_error{"Max size exceeded " + std::to_string(max)}; + } + + const std::string& as_string() const { return s; } + + operator std::string() const { return s; } + + private: + std::string s; +}; + +template +bool operator<(const SizeConstrainedString& lhs, + const SizeConstrainedString& rhs) { + return lhs.as_string() < rhs.as_string(); +} + +template +bool operator==(const SizeConstrainedString& lhs, + const SizeConstrainedString& rhs) { + return lhs.as_string() == rhs.as_string(); +} + +template +std::ostream& operator<<(std::ostream& out, + const SizeConstrainedString& scs) { + return out << std::setw(max) << std::left << scs.as_string(); +} + +// We are imposing size constraints to ensure a consistent CLI layout. +typedef SizeConstrainedString<30> Name; +typedef SizeConstrainedString<60> Usage; +typedef SizeConstrainedString<100> Description; + +/// @brief Flag models an input parameter to a command. +class Flag : public DoNotCopyOrMove { + public: + typedef boost::program_options::value_semantic* Specification; + + // Safe us some typing. + typedef std::shared_ptr Ptr; + + /// @brief name returns the name of the Flag. + const Name& name() const; + /// @brief description returns a human-readable description of the flag. + const Description& description() const; + + /// @brief specify the program option of the flag. + virtual void specify_option(Specification& spec) = 0; + + protected: + /// @brief Flag creates a new instance, initializing name and description + /// from the given values. + Flag(const Name& name, const Description& description); + + private: + Name name_; + Description description_; +}; + +/// @brief TypedFlag implements Flag relying on operator<< and operator>> to +/// read/write values to/from strings. +template +class TypedFlag : public Flag { + public: + typedef std::shared_ptr> Ptr; + + TypedFlag(const Name& name, const Description& description) + : Flag{name, description} {} + + /// @brief value installs the given value in the flag. + TypedFlag& value(const T& value) { + value_ = value; + return *this; + } + + /// @brief value returns the optional value associated with the flag. + const Optional& value() const { return value_; } + + /// @brief Option generated by specify_option tries to unwrap a value + /// of type T from value. + void specify_option(Flag::Specification& spec) override { + spec = boost::program_options::value()->notifier([&](const std::string& s) { + std::stringstream ss{s}; + T value; + ss >> value; + value_ = value; + }); + } + + private: + Optional value_; +}; + +/// @brief TypedReferenceFlag implements Flag, relying on operator<> to +/// convert to/from string representations, +/// updating the given mutable reference to a value of type T. +template +class TypedReferenceFlag : public Flag { + public: + // Safe us some typing. + typedef std::shared_ptr> Ptr; + + /// @brief TypedReferenceFlag initializes a new instance with name, + /// description and value. + TypedReferenceFlag(const Name& name, const Description& description, T& value) + : Flag{name, description}, value_{value} {} + + /// @brief Option generated by specify_option tries to unwrap a value of type T + /// from value, relying on operator>> to read from given string s. + void specify_option(Flag::Specification& spec) override { + spec = boost::program_options::value()->notifier([&](const std::string& s) { + std::stringstream ss{s}; + ss >> value_.get(); + }); + } + + private: + std::reference_wrapper value_; +}; + +/// @brief OptionalTypedReferenceFlag handles Optional references, making +/// sure that a value is always read on notify, even if the Optional wasn't +/// initialized previously. +template +class OptionalTypedReferenceFlag : public Flag { + public: + typedef std::shared_ptr> Ptr; + + OptionalTypedReferenceFlag(const Name& name, const Description& description, + Optional& value) + : Flag{name, description}, value_{value} {} + + /// @brief Option generated by specify_option tries to unwrap a value of + /// type T from value. + void specify_option(Flag::Specification& spec) override { + spec = boost::program_options::value()->notifier([&](const std::string& s) { + std::stringstream ss{s}; + T value; + ss >> value; + value_.get() = value; + }); + } + + private: + std::reference_wrapper> value_; +}; + +/// @brief BoolSwitchFlag implements Flag, updating the given mutable reference +/// to a boolean value. +class BoolSwitchFlag : public Flag { + public: + typedef std::shared_ptr Ptr; + + BoolSwitchFlag(const Name& name, const Description& description, bool& value) + : Flag{name, description}, value_(value) {} + + /// @brief Option generated by specify_option tries to unwrap a boolean + /// value from value. + void specify_option(Flag::Specification& spec) override { + spec = boost::program_options::bool_switch(&value_.get()); + } + + private: + std::reference_wrapper value_; +}; + +/// @brief Command abstracts an individual command available from the daemon. +class Command : public DoNotCopyOrMove { + public: + // Safe us some typing + typedef std::shared_ptr Ptr; + + /// @brief FlagsMissing is thrown if at least one required flag is missing. + struct FlagsMissing : public std::runtime_error { + /// @brief FlagsMissing initializes a new instance. + FlagsMissing(); + }; + + /// @brief FlagsWithWrongValue is thrown if a value passed on the command line + /// is invalid. + struct FlagsWithInvalidValue : public std::runtime_error { + /// @brief FlagsWithInvalidValue initializes a new instance. + FlagsWithInvalidValue(); + }; + + /// @brief Context bundles information passed to Command::run invocations. + struct Context { + std::istream& cin; ///< The std::istream that should be used for reading. + std::ostream& cout; ///< The std::ostream that should be used for writing. + std::vector args; ///< The command line args. + }; + + /// @brief name returns the Name of the command. + virtual Name name() const; + + /// @brief usage returns a short usage string for the command. + virtual Usage usage() const; + + /// @brief description returns a longer string explaining the command. + virtual Description description() const; + + /// @brief hidden returns if the command is hidden from the user or not. + virtual bool hidden() const; + + /// @brief run puts the command to execution. + virtual int run(const Context& context) = 0; + + /// @brief help prints information about a command to out. + virtual void help(std::ostream& out) = 0; + + protected: + /// @brief Command initializes a new instance with the given name, usage and + /// description. + Command(const Name& name, const Usage& usage, const Description& description, bool hidden = false); + + /// @brief name adjusts the name of the command to n. + // virtual void name(const Name& n); + /// @brief usage adjusts the usage string of the comand to u. + // virtual void usage(const Usage& u); + /// @brief description adjusts the description string of the command to d. + // virtual void description(const Description& d); + + private: + Name name_; + Usage usage_; + Description description_; + bool hidden_; +}; + +/// @brief CommandWithSubcommands implements Command, selecting one of a set of +/// actions. +class CommandWithSubcommands : public Command { + public: + typedef std::shared_ptr Ptr; + typedef std::function Action; + + /// @brief CommandWithSubcommands initializes a new instance with the given + /// name, usage and description. + CommandWithSubcommands(const Name& name, const Usage& usage, + const Description& description); + + /// @brief command adds the given command to the set of known commands. + CommandWithSubcommands& command(const Command::Ptr& command); + + /// @brief flag adds the given flag to the set of known flags. + CommandWithSubcommands& flag(const Flag::Ptr& flag); + + // From Command + int run(const Context& context) override; + void help(std::ostream& out) override; + + private: + std::unordered_map commands_; + std::set flags_; +}; + +/// @brief CommandWithFlagsAction implements Command, executing an Action after +/// handling +class CommandWithFlagsAndAction : public Command { + public: + typedef std::shared_ptr Ptr; + typedef std::function Action; + + /// @brief CommandWithFlagsAndAction initializes a new instance with the given + /// name, usage and description. Optionally the command can be marked as hidden. + CommandWithFlagsAndAction(const Name& name, const Usage& usage, + const Description& description, bool hidden = false); + + /// @brief flag adds the given flag to the set of known flags. + CommandWithFlagsAndAction& flag(const Flag::Ptr& flag); + + /// @brief action installs the given action. + CommandWithFlagsAndAction& action(const Action& action); + + // From Command + int run(const Context& context) override; + void help(std::ostream& out) override; + + private: + std::set flags_; + Action action_; +}; + +namespace cmd { +/// @brief HelpFor prints a help message for the given command on execution. +class Help : public Command { + public: + /// @brief HelpFor initializes a new instance with the given reference to a + /// cmd. + explicit Help(Command& cmd); + + // From Command + int run(const Context& context) override; + void help(std::ostream& out) override; + + private: + /// @cond + Command& command; + /// @endcond +}; +} + +/// @brief args returns a vector of strings assembled from argc and argv. +std::vector args(int argc, char** argv); + +/// @brief make_flag returns a flag with the given name and description. +template +typename TypedFlag::Ptr make_flag(const Name& name, + const Description& description) { + return std::make_shared>(name, description); +} + +/// @brief make_flag returns a flag with the given name and description, +/// notifying updates to value. +template +typename TypedReferenceFlag::Ptr make_flag(const Name& name, + const Description& desc, + T& value) { + return std::make_shared>(name, desc, value); +} + +/// @brief make_flag returns a flag with the given name and description, +/// updating the given optional value. +template +typename OptionalTypedReferenceFlag::Ptr make_flag(const Name& name, + const Description& desc, + Optional& value) { + return std::make_shared>(name, desc, value); +} + +/// @brief make_flag returns a flag with the given name and description, +/// updating the given boolean value. +inline BoolSwitchFlag::Ptr make_flag(const Name& name, + const Description &desc, + bool &value) { + return std::make_shared(name, desc, value); +} + +} // namespace cli +} // namespace anbox + +#endif