1 /* -*- mode: C++; indent-tabs-mode: nil; -*-
3 * This file is a part of LEMON, a generic C++ optimization library.
5 * Copyright (C) 2003-2009
6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 * (Egervary Research Group on Combinatorial Optimization, EGRES).
9 * Permission to use, modify and distribute this software is granted
10 * provided that this copyright notice appears in all copies. For
11 * precise terms see the accompanying LICENSE file.
13 * This software is provided "AS IS" with no warranty of any kind,
14 * express or implied, and with no claim as to its suitability for any
19 #ifndef LEMON_ARG_PARSER_H
20 #define LEMON_ARG_PARSER_H
29 #include <lemon/assert.h>
33 ///\brief A tool to parse command line arguments.
37 ///Exception used by ArgParser
38 class ArgParserException : public Exception {
41 HELP, /// <tt>--help</tt> option was given
42 UNKNOWN_OPT, /// Unknown option was given
43 INVALID_OPT /// Invalid combination of options
51 ArgParserException(Reason r) throw() : _reason(r) {}
53 virtual ~ArgParserException() throw() {}
54 ///A short description of the exception
55 virtual const char* what() const throw() {
59 return "lemon::ArgParseException: ask for help";
62 return "lemon::ArgParseException: unknown option";
65 return "lemon::ArgParseException: invalid combination of options";
70 ///Return the reason for the failure
71 Reason reason() const {return _reason; }
75 ///Command line arguments parser
78 ///Command line arguments parser.
80 ///For a complete example see the \ref arg_parser_demo.cc demo file.
83 static void _showHelp(void *p);
87 const char * const *_argv;
89 enum OptType { UNKNOWN=0, BOOL=1, STRING=2, DOUBLE=3, INTEGER=4, FUNC=5 };
97 std::string *string_p;
112 ParData() : mandatory(false), type(UNKNOWN), set(false), ingroup(false),
113 has_syn(false), syn(false), self_delete(false) {}
116 typedef std::map<std::string,ParData> Opts;
122 typedef std::list<std::string> Opts;
126 GroupData() :only_one(false), mandatory(false) {}
129 typedef std::map<std::string,GroupData> Groups;
136 OtherArg(std::string n, std::string h) :name(n), help(h) {}
140 std::vector<OtherArg> _others_help;
141 std::vector<std::string> _file_args;
142 std::string _command_name;
146 //Bind a function to an option.
148 //\param name The name of the option. The leading '-' must be omitted.
149 //\param help A help string.
150 //\retval func The function to be called when the option is given. It
151 // must be of type "void f(void *)"
152 //\param data Data to be passed to \c func
153 ArgParser &funcOption(const std::string &name,
154 const std::string &help,
155 void (*func)(void *),void *data);
157 bool _exit_on_problems;
159 void _terminate(ArgParserException::Reason reason) const;
164 ArgParser(int argc, const char * const *argv);
173 ///Add a new integer type option
175 ///Add a new integer type option.
176 ///\param name The name of the option. The leading '-' must be omitted.
177 ///\param help A help string.
178 ///\param value A default value for the option.
179 ///\param obl Indicate if the option is mandatory.
180 ArgParser &intOption(const std::string &name,
181 const std::string &help,
182 int value=0, bool obl=false);
184 ///Add a new floating point type option
186 ///Add a new floating point type option.
187 ///\param name The name of the option. The leading '-' must be omitted.
188 ///\param help A help string.
189 ///\param value A default value for the option.
190 ///\param obl Indicate if the option is mandatory.
191 ArgParser &doubleOption(const std::string &name,
192 const std::string &help,
193 double value=0, bool obl=false);
195 ///Add a new bool type option
197 ///Add a new bool type option.
198 ///\param name The name of the option. The leading '-' must be omitted.
199 ///\param help A help string.
200 ///\param value A default value for the option.
201 ///\param obl Indicate if the option is mandatory.
202 ///\note A mandatory bool obtion is of very little use.
203 ArgParser &boolOption(const std::string &name,
204 const std::string &help,
205 bool value=false, bool obl=false);
207 ///Add a new string type option
209 ///Add a new string type option.
210 ///\param name The name of the option. The leading '-' must be omitted.
211 ///\param help A help string.
212 ///\param value A default value for the option.
213 ///\param obl Indicate if the option is mandatory.
214 ArgParser &stringOption(const std::string &name,
215 const std::string &help,
216 std::string value="", bool obl=false);
218 ///Give help string for non-parsed arguments.
220 ///With this function you can give help string for non-parsed arguments.
221 ///The parameter \c name will be printed in the short usage line, while
222 ///\c help gives a more detailed description.
223 ArgParser &other(const std::string &name,
224 const std::string &help="");
228 ///\name Options with External Storage
229 ///Using this functions, the value of the option will be directly written
230 ///into a variable once the option appears in the command line.
234 ///Add a new integer type option with a storage reference
236 ///Add a new integer type option with a storage reference.
237 ///\param name The name of the option. The leading '-' must be omitted.
238 ///\param help A help string.
239 ///\param obl Indicate if the option is mandatory.
240 ///\retval ref The value of the argument will be written to this variable.
241 ArgParser &refOption(const std::string &name,
242 const std::string &help,
243 int &ref, bool obl=false);
245 ///Add a new floating type option with a storage reference
247 ///Add a new floating type option with a storage reference.
248 ///\param name The name of the option. The leading '-' must be omitted.
249 ///\param help A help string.
250 ///\param obl Indicate if the option is mandatory.
251 ///\retval ref The value of the argument will be written to this variable.
252 ArgParser &refOption(const std::string &name,
253 const std::string &help,
254 double &ref, bool obl=false);
256 ///Add a new bool type option with a storage reference
258 ///Add a new bool type option with a storage reference.
259 ///\param name The name of the option. The leading '-' must be omitted.
260 ///\param help A help string.
261 ///\param obl Indicate if the option is mandatory.
262 ///\retval ref The value of the argument will be written to this variable.
263 ///\note A mandatory bool obtion is of very little use.
264 ArgParser &refOption(const std::string &name,
265 const std::string &help,
266 bool &ref, bool obl=false);
268 ///Add a new string type option with a storage reference
270 ///Add a new string type option with a storage reference.
271 ///\param name The name of the option. The leading '-' must be omitted.
272 ///\param help A help string.
273 ///\param obl Indicate if the option is mandatory.
274 ///\retval ref The value of the argument will be written to this variable.
275 ArgParser &refOption(const std::string &name,
276 const std::string &help,
277 std::string &ref, bool obl=false);
281 ///\name Option Groups and Synonyms
286 ///Bundle some options into a group
288 /// You can group some option by calling this function repeatedly for each
289 /// option to be grouped with the same groupname.
290 ///\param group The group name.
291 ///\param opt The option name.
292 ArgParser &optionGroup(const std::string &group,
293 const std::string &opt);
295 ///Make the members of a group exclusive
297 ///If you call this function for a group, than at most one of them can be
298 ///given at the same time.
299 ArgParser &onlyOneGroup(const std::string &group);
301 ///Make a group mandatory
303 ///Using this function, at least one of the members of \c group
305 ArgParser &mandatoryGroup(const std::string &group);
307 ///Create synonym to an option
309 ///With this function you can create a synonym \c syn of the
311 ArgParser &synonym(const std::string &syn,
312 const std::string &opt);
317 void show(std::ostream &os,Opts::const_iterator i) const;
318 void show(std::ostream &os,Groups::const_iterator i) const;
319 void showHelp(Opts::const_iterator i) const;
320 void showHelp(std::vector<OtherArg>::const_iterator i) const;
322 void unknownOpt(std::string arg) const;
324 void requiresValue(std::string arg, OptType t) const;
325 void checkMandatories() const;
327 void shortHelp() const;
328 void showHelp() const;
331 ///Start the parsing process
334 /// Synonym for parse()
340 ///Give back the command name (the 0th argument)
341 const std::string &commandName() const { return _command_name; }
343 ///Check if an opion has been given to the command.
344 bool given(std::string op) const
346 Opts::const_iterator i = _opts.find(op);
347 return i!=_opts.end()?i->second.set:false;
351 ///Magic type for operator[]
353 ///This is the type of the return value of ArgParser::operator[]().
354 ///It automatically converts to \c int, \c double, \c bool or
355 ///\c std::string if the type of the option matches, which is checked
356 ///with an \ref LEMON_ASSERT "assertion" (i.e. it performs runtime
360 const ArgParser &_parser;
364 RefType(const ArgParser &p,const std::string &n) :_parser(p),_name(n) {}
368 Opts::const_iterator i = _parser._opts.find(_name);
369 LEMON_ASSERT(i!=_parser._opts.end(),
370 std::string()+"Unkown option: '"+_name+"'");
371 LEMON_ASSERT(i->second.type==ArgParser::BOOL,
372 std::string()+"'"+_name+"' is a bool option");
373 return *(i->second.bool_p);
376 operator std::string()
378 Opts::const_iterator i = _parser._opts.find(_name);
379 LEMON_ASSERT(i!=_parser._opts.end(),
380 std::string()+"Unkown option: '"+_name+"'");
381 LEMON_ASSERT(i->second.type==ArgParser::STRING,
382 std::string()+"'"+_name+"' is a string option");
383 return *(i->second.string_p);
388 Opts::const_iterator i = _parser._opts.find(_name);
389 LEMON_ASSERT(i!=_parser._opts.end(),
390 std::string()+"Unkown option: '"+_name+"'");
391 LEMON_ASSERT(i->second.type==ArgParser::DOUBLE ||
392 i->second.type==ArgParser::INTEGER,
393 std::string()+"'"+_name+"' is a floating point option");
394 return i->second.type==ArgParser::DOUBLE ?
395 *(i->second.double_p) : *(i->second.int_p);
400 Opts::const_iterator i = _parser._opts.find(_name);
401 LEMON_ASSERT(i!=_parser._opts.end(),
402 std::string()+"Unkown option: '"+_name+"'");
403 LEMON_ASSERT(i->second.type==ArgParser::INTEGER,
404 std::string()+"'"+_name+"' is an integer option");
405 return *(i->second.int_p);
410 ///Give back the value of an option
412 ///Give back the value of an option.
414 RefType operator[](const std::string &n) const
416 return RefType(*this, n);
419 ///Give back the non-option type arguments.
421 ///Give back a reference to a vector consisting of the program arguments
422 ///not starting with a '-' character.
423 const std::vector<std::string> &files() const { return _file_args; }
425 ///Throw instead of exit in case of problems
426 void throwOnProblems()
428 _exit_on_problems=false;
433 #endif // LEMON_ARG_PARSER_H