00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #ifndef COMMANDOPTIONS_HEADER
00022 #define COMMANDOPTIONS_HEADER
00023
00024 #include <vector>
00025 #include <string>
00026 #include <exception>
00027 #include <sstream>
00028
00095 class commandoptions
00096 {
00097 public:
00118
00119
00120 template <typename T>
00121 void register_option(T &par, std::string long_name, char short_name,
00122 std::string des, std::string arg_name)
00123 {
00124 option_table.push_back(option(new updater<T>(par), long_name, short_name, des, arg_name));
00125 }
00126
00147 void register_flag(bool &par, std::string long_name, char short_name, std::string des)
00148 {
00149 flag_table.push_back(flag(par, long_name, short_name, des));
00150 }
00151
00164 template <typename T>
00165 void register_argument(T &par, std::string name, std::string des)
00166 {
00167 argument_table.push_back(argument(new updater<T>(par), name, des));
00168 }
00169
00175 void process_command_line(int argc, const char *argv[]);
00176
00178 ~commandoptions()
00179 {
00180
00181 for (std::vector<updaterbase *>::iterator it = clean_up_table.begin();
00182 it != clean_up_table.end(); ++it)
00183 delete (*it);
00184 }
00185
00186
00187 private:
00188
00189
00193 std::string requirify(std::string s)
00194 {
00195 return '<' + s + '>';
00196 }
00197
00201 std::string optionalify(std::string s)
00202 {
00203 return '[' + s + ']';
00204 }
00205
00209 std::string strip_path(std::string s);
00210
00213 void print_usage(std::string executable);
00216 void print_help(std::string executable);
00217
00218
00219
00220 class updaterbase
00221 {
00222 public:
00223 virtual bool update(std::string s) = 0;
00224 };
00225
00226 template <typename T>
00227 class updater: public updaterbase
00228 {
00229 public:
00230 updater(T &par):
00231 var(par)
00232 {}
00233
00234
00235 virtual bool update(std::string s)
00236 {
00237 std::istringstream is(s);
00238 is >> var;
00239 if (!is)
00240 return false;
00241 else
00242 return true;
00243 }
00244
00245 private:
00246 T &var;
00247 };
00248
00249
00250 struct option
00251 {
00252 updaterbase *par;
00253 std::string long_name, des, arg_name;
00254 char short_name;
00255
00256 option(updaterbase *p, std::string ln, char sn, std::string d, std::string an):
00257 par(p), long_name(ln), des(d), arg_name(an), short_name(sn)
00258 {}
00259 option(const option &o):
00260 par(o.par), long_name(o.long_name), des(o.des), arg_name(o.arg_name), short_name(o.short_name)
00261 {}
00262 };
00263
00264
00265 struct flag
00266 {
00267 bool *par;
00268 std::string long_name, des;
00269 char short_name;
00270
00271 flag(bool &p, std::string ln, char sn, std::string d):
00272 par(&p), long_name(ln), des(d), short_name(sn)
00273 {}
00274 };
00275
00276
00277 struct argument
00278 {
00279 updaterbase *par;
00280 std::string name, des;
00281
00282 argument(updaterbase *p, std::string n, std::string d):
00283 par(p), name(n), des(d)
00284 {}
00285 argument(const argument &a):
00286 par(a.par), name(a.name), des(a.des)
00287 {}
00288 };
00289
00291 std::vector<option> option_table;
00293 std::vector<flag> flag_table;
00295 std::vector<argument> argument_table;
00297 typedef std::vector<option>::iterator option_iterator;
00299 typedef std::vector<flag>::iterator flag_iterator;
00301 typedef std::vector<argument>::iterator argument_iterator;
00302
00303 std::vector<updaterbase *> clean_up_table;
00304 };
00305
00306 template <> class commandoptions::updater<std::string>: public commandoptions::updaterbase
00307 {
00308 public:
00309 updater(std::string &par):
00310 var(par)
00311 {}
00312
00313
00314 virtual bool update(std::string s)
00315 {
00316 var = s;
00317 return true;
00318 }
00319
00320 private:
00321 std::string &var;
00322 };
00323
00325
00326 class commandoptions_error: std::exception
00327 {
00328 public:
00331 commandoptions_error(std::string s) throw(): msg(s)
00332 {}
00334 ~commandoptions_error() throw()
00335 {}
00336
00338 virtual const char *what() const throw()
00339 {
00340 return msg.c_str();
00341 }
00342
00343 private:
00344 std::string msg;
00345 };
00346
00347
00348 #endif // COMMANDOPTIONS_HEADER