X-Git-Url: http://git.tdb.fi/?p=libs%2Fcore.git;a=blobdiff_plain;f=source%2Fcore%2Fgetopt.h;h=f4e318e55d3eec1e8b14a160101e75c7be9e9cbb;hp=70841cbf6b8dc50da4800bfae42ebc78e6d7e122;hb=5305cabf0b20a99a82aff4bcef26f2be0a8fd757;hpb=6f0c4c39133e08c05ffb1f1d53141a7e80ba6351 diff --git a/source/core/getopt.h b/source/core/getopt.h index 70841cb..f4e318e 100644 --- a/source/core/getopt.h +++ b/source/core/getopt.h @@ -44,9 +44,19 @@ A single option may have both alternative forms, but must always have at least a long form. This is to encourage self-documenting options; it's much easier to remember words than letters. -A built-in --help option is provided and will output a list of options and -their associated help texts. An application may override this by providing -its own option with the same name. +Positional arguments are also supported. They are identified by an arbitrary +string, but the identifier is only used in help text and error messages. Any +number of the final arguments may be optional. + +To support applications that take an arbitrary amount of arguments, a single +positional argument list can be specified. Fixed positional arguments are +allowed together with a list, but they can't be optional. An application that +wants to do complex processing on the argument list can declare a list of +string arguments. + +A built-in --help option is provided and will output a list of options, +arguments and their associated help texts. An application may override this by +providing its own option with the same name. */ class GetOpt { @@ -78,6 +88,16 @@ public: virtual unsigned get_seen_count() const = 0; }; + class Argument + { + protected: + Argument() { } + public: + virtual ~Argument() { } + + virtual Argument &set_help(const std::string &) = 0; + }; + private: class Store { @@ -122,6 +142,26 @@ private: void process(const std::string &); }; + class ArgumentImpl: public Argument + { + private: + std::string name; + ArgType type; + std::string help; + Store *store; + + public: + ArgumentImpl(const std::string &, const Store &, ArgType); + virtual ~ArgumentImpl(); + + virtual ArgumentImpl &set_help(const std::string &); + const std::string &get_name() const { return name; } + ArgType get_type() const { return type; } + const std::string &get_help() const { return help; } + bool is_list_store() const { return store->is_list(); } + void process(const std::string &); + }; + template class SimpleStore: public Store { @@ -163,17 +203,20 @@ private: }; typedef std::list OptionList; + typedef std::list ArgumentList; bool help; OptionList opts; - std::vector args; + ArgumentList args; + std::vector args_raw; public: GetOpt(); ~GetOpt(); - /// Returns any non-option arguments encountered during processing. - const std::vector &get_args() const { return args; } + /** Returns any non-option arguments encountered during processing. + Deprecated. */ + const std::vector &get_args() const { return args_raw; } /** Adds an option with both short and long forms. Processing depends on the type of the destination variable and whether an argument is taken or @@ -196,8 +239,22 @@ public: Option &add_option(const std::string &l, T &d, ArgType a) { return add_option(0, l, d, a); } + /** Adds a positional argument. The value will be lexical_cast to the + appropriate type and stored in the destination. */ + template + Argument &add_argument(const std::string &n, T &d, ArgType a = REQUIRED_ARG) + { return add_argument(n, SimpleStore(d), a); } + + /** Adds a positional argument list. If the list is declared as required, + at least one element must be given; an optional list may be empty. Only one + list may be added, and optional fixed arguments can't be used with it. */ + template + Argument &add_argument(const std::string &n, std::list &d, ArgType a = REQUIRED_ARG) + { return add_argument(n, ListStore >(d), a); } + private: OptionImpl &add_option(char, const std::string &, const Store &, ArgType); + ArgumentImpl &add_argument(const std::string &, const Store &, ArgType); OptionImpl &get_option(char); OptionImpl &get_option(const std::string &); @@ -215,11 +272,11 @@ private: unsigned process_short(const char *const *); public: - /** Generates a single line that describes known options. */ + /** Generates a single line that describes known options and arguments. */ std::string generate_usage(const std::string &) const; - /** Generates help for known options in tabular format, one option per - line. The returned string will have a linefeed at the end. */ + /** Generates help for known options and arguments in tabular format, one + item per line. The returned string will have a linefeed at the end. */ std::string generate_help() const; };