X-Git-Url: http://git.tdb.fi/?p=libs%2Fcore.git;a=blobdiff_plain;f=source%2Fcore%2Fgetopt.h;h=405864bb27bfdda1668537a35630550465963482;hp=f4e318e55d3eec1e8b14a160101e75c7be9e9cbb;hb=44da9fc9afb6b7e49c1558c5572213a1e6f401e8;hpb=5305cabf0b20a99a82aff4bcef26f2be0a8fd757 diff --git a/source/core/getopt.h b/source/core/getopt.h index f4e318e..405864b 100644 --- a/source/core/getopt.h +++ b/source/core/getopt.h @@ -6,6 +6,7 @@ #include #include #include +#include "noncopyable.h" namespace Msp { @@ -33,12 +34,12 @@ the string "-abc" could be interpreted as having the options 'a', 'b' and 'c'. If the option takes an argument and there are unused characters in the argv element, then those characters are interpreted as the argument. Otherwise the next element is taken as the argument. An optional argument must be given in -the same element. +the same element if it is given. Long options begin with a double dash and are identified by an arbitrary string. An argument can be specified either in the same argv element, separated by an equals sign, or in the next element. As with short options, -an optional argument must be in the same element. +an optional argument, if given, must be in the same element. 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 @@ -58,7 +59,7 @@ 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 +class GetOpt: private NonCopyable { public: enum ArgType @@ -202,31 +203,31 @@ private: { data.push_back(lexical_cast(a)); } }; - typedef std::list OptionList; - typedef std::list ArgumentList; - bool help; - OptionList opts; - ArgumentList args; + std::vector opts; + std::vector args; std::vector args_raw; public: GetOpt(); ~GetOpt(); - /** 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 - not. With an argument, the value is lexical_cast to appropriate type and - stored in the destination. Without an argument, a bool will be set to true - and an unsigned will be incremented; any other type will be ignored. */ + not. With an argument, the value is lexical_cast to the appropriate type + and stored in the destination. Without an argument, a bool will be set to + true and an unsigned will be incremented; any other type will be ignored. */ template Option &add_option(char s, const std::string &l, T &d, ArgType a = NO_ARG) { return add_option(s, l, SimpleStore(d), a); } + /** Adds an option with both short and long forms. The option may be + specified multiple times, and the argument from each occurrence is stored in + the list. The argument type must be REQUIRED_ARG. */ + template + Option &add_option(char s, const std::string &l, std::vector &d, ArgType a = REQUIRED_ARG) + { return add_option(s, l, ListStore >(d), a); } + /** Adds an option with both short and long forms. The option may be specified multiple times, and the argument from each occurrence is stored in the list. The argument type must be REQUIRED_ARG. */ @@ -245,6 +246,13 @@ public: 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::vector &d, ArgType a = REQUIRED_ARG) + { return add_argument(n, ListStore >(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. */ @@ -272,8 +280,10 @@ private: unsigned process_short(const char *const *); public: - /** Generates a single line that describes known options and arguments. */ - std::string generate_usage(const std::string &) const; + /** Generates a single line that describes known options and arguments. If + compact is true, the options list is replaced with a placeholder. This + provides cleaner output if full help text is printed. */ + std::string generate_usage(const std::string &, bool compact = false) const; /** Generates help for known options and arguments in tabular format, one item per line. The returned string will have a linefeed at the end. */ @@ -289,6 +299,9 @@ template<> inline void GetOpt::SimpleStore::store() template<> inline void GetOpt::SimpleStore::store(const std::string &a) { data = a; } +template<> inline void GetOpt::ListStore >::store(const std::string &a) +{ data.push_back(a); } + template<> inline void GetOpt::ListStore >::store(const std::string &a) { data.push_back(a); }