3 This file is part of libmspcore
4 Copyright © 2006-2009, 2011 Mikko Rasa, Mikkosoft Productions
5 Distributed under the LGPL
8 #ifndef MSP_CORE_GETOPT_H_
9 #define MSP_CORE_GETOPT_H_
19 class usage_error: public std::runtime_error
25 usage_error(const std::string &w, const std::string &h = std::string()): std::runtime_error(w), help_(h) { }
26 ~usage_error() throw() { }
28 const char *help() const throw() { return help_.c_str(); }
52 OptBase(char, const std::string &, ArgType);
54 virtual ~OptBase() { }
56 OptBase &set_help(const std::string &);
57 OptBase &set_help(const std::string &, const std::string &);
58 char get_short() const { return shrt; }
59 const std::string &get_long() const { return lng; }
60 ArgType get_arg_type() const { return arg_type; }
61 const std::string &get_help() const { return help; }
62 const std::string &get_metavar() const { return metavar; }
63 unsigned get_seen_count() const { return seen_count; }
65 void process(const std::string &);
67 virtual void store() = 0;
68 virtual void store(const std::string &) = 0;
73 class Option: public OptBase
76 Option(char s, const std::string &l, T &d, ArgType a): OptBase(s, l, a), data(d) { }
78 virtual void store() { }
80 virtual void store(const std::string &a)
83 std::istringstream ss(a);
86 throw usage_error("Invalid argument for --"+lng);
95 class ListOption: public OptBase
98 ListOption(char s, const std::string &l, T &d, ArgType a): OptBase(s, l, a), data(d)
99 { if(arg_type!=REQUIRED_ARG) throw std::invalid_argument("ListOption arg_type!=REQUIRED"); }
101 virtual void store() { }
103 virtual void store(const std::string &a)
105 typename T::value_type tmp;
106 std::istringstream ss(a);
109 throw usage_error("Invalid argument for --"+lng);
118 std::list<OptBase *> opts;
119 std::vector<std::string> args;
125 const std::vector<std::string> &get_args() const { return args; }
128 OptBase &add_option(char s, const std::string &l, T &d, ArgType a = NO_ARG)
129 { opts.push_back(new Option<T>(s, l, d, a)); return *opts.back(); }
132 OptBase &add_option(char s, const std::string &l, std::list<T> &d, ArgType a = REQUIRED_ARG)
133 { opts.push_back(new ListOption<std::list<T> >(s, l, d, a)); return *opts.back(); }
136 OptBase &add_option(const std::string &l, T &d, ArgType a)
137 { return add_option(0, l, d, a); }
140 OptBase &get_option(char);
141 OptBase &get_option(const std::string &);
144 /** Processes argc/argv style command line arguments. The contents of argv
145 will be unchanged; use get_args to access non-option arguments. */
146 void operator()(unsigned, const char *const *);
149 /** Processes a long option. Returns the number of arguments eaten. */
150 unsigned process_long(const char *const *);
152 /** Processes short options. Returns the number of arguments eaten. */
153 unsigned process_short(const char *const *);
156 /** Generates a single line that describes known options. */
157 std::string generate_usage(const std::string &) const;
159 /** Generates help for known options in tabular format, one option per
160 line. The returned string will have a linefeed at the end. */
161 std::string generate_help() const;
164 template<> inline void GetOpt::Option<bool>::store() { data = true; }
165 template<> inline void GetOpt::Option<unsigned>::store() { ++data; }
167 template<> inline void GetOpt::Option<std::string>::store(const std::string &a)
170 template<> inline void GetOpt::ListOption<std::list<std::string> >::store(const std::string &a)
171 { data.push_back(a); }