1 /* -*- mode: C++; indent-tabs-mode: nil; -*-
3 * This file is a part of LEMON, a generic C++ optimization library.
5 * Copyright (C) 2003-2010
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/core.h>
30 #include <lemon/assert.h>
34 ///\brief A tool to parse command line arguments.
38 ///Exception used by ArgParser
40 ///Exception used by ArgParser.
42 class ArgParserException : public Exception {
44 /// Reasons for failure
46 /// Reasons for failure.
49 HELP, ///< <tt>--help</tt> option was given.
50 UNKNOWN_OPT, ///< Unknown option was given.
51 INVALID_OPT ///< Invalid combination of options.
59 ArgParserException(Reason r) throw() : _reason(r) {}
61 virtual ~ArgParserException() throw() {}
62 ///A short description of the exception
63 virtual const char* what() const throw() {
67 return "lemon::ArgParseException: ask for help";
70 return "lemon::ArgParseException: unknown option";
73 return "lemon::ArgParseException: invalid combination of options";
78 ///Return the reason for the failure
79 Reason reason() const {return _reason; }
83 ///Command line arguments parser
86 ///Command line arguments parser.
88 ///For a complete example see the \ref arg_parser_demo.cc demo file.
91 static void _showHelp(void *p);
95 const char * const *_argv;
97 enum OptType { UNKNOWN=0, BOOL=1, STRING=2, DOUBLE=3, INTEGER=4, FUNC=5 };
105 std::string *string_p;
120 ParData() : mandatory(false), type(UNKNOWN), set(false), ingroup(false),
121 has_syn(false), syn(false), self_delete(false) {}
124 typedef std::map<std::string,ParData> Opts;
130 typedef std::list<std::string> Opts;
134 GroupData() :only_one(false), mandatory(false) {}
137 typedef std::map<std::string,GroupData> Groups;
144 OtherArg(std::string n, std::string h) :name(n), help(h) {}
148 std::vector<OtherArg> _others_help;
149 std::vector<std::string> _file_args;
150 std::string _command_name;
154 //Bind a function to an option.
156 //\param name The name of the option. The leading '-' must be omitted.
157 //\param help A help string.
158 //\retval func The function to be called when the option is given. It
159 // must be of type "void f(void *)"
160 //\param data Data to be passed to \c func
161 ArgParser &funcOption(const std::string &name,
162 const std::string &help,
163 void (*func)(void *),void *data);
165 bool _exit_on_problems;
167 void _terminate(ArgParserException::Reason reason) const;
172 ArgParser(int argc, const char * const *argv);
181 ///Add a new integer type option
183 ///Add a new integer type option.
184 ///\param name The name of the option. The leading '-' must be omitted.
185 ///\param help A help string.
186 ///\param value A default value for the option.
187 ///\param obl Indicate if the option is mandatory.
188 ArgParser &intOption(const std::string &name,
189 const std::string &help,
190 int value=0, bool obl=false);
192 ///Add a new floating point type option
194 ///Add a new floating point type option.
195 ///\param name The name of the option. The leading '-' must be omitted.
196 ///\param help A help string.
197 ///\param value A default value for the option.
198 ///\param obl Indicate if the option is mandatory.
199 ArgParser &doubleOption(const std::string &name,
200 const std::string &help,
201 double value=0, bool obl=false);
203 ///Add a new bool type option
205 ///Add a new bool type option.
206 ///\param name The name of the option. The leading '-' must be omitted.
207 ///\param help A help string.
208 ///\param value A default value for the option.
209 ///\param obl Indicate if the option is mandatory.
210 ///\note A mandatory bool obtion is of very little use.
211 ArgParser &boolOption(const std::string &name,
212 const std::string &help,
213 bool value=false, bool obl=false);
215 ///Add a new string type option
217 ///Add a new string type option.
218 ///\param name The name of the option. The leading '-' must be omitted.
219 ///\param help A help string.
220 ///\param value A default value for the option.
221 ///\param obl Indicate if the option is mandatory.
222 ArgParser &stringOption(const std::string &name,
223 const std::string &help,
224 std::string value="", bool obl=false);
226 ///Give help string for non-parsed arguments.
228 ///With this function you can give help string for non-parsed arguments.
229 ///The parameter \c name will be printed in the short usage line, while
230 ///\c help gives a more detailed description.
231 ArgParser &other(const std::string &name,
232 const std::string &help="");
236 ///\name Options with External Storage
237 ///Using this functions, the value of the option will be directly written
238 ///into a variable once the option appears in the command line.
242 ///Add a new integer type option with a storage reference
244 ///Add a new integer type option with a storage reference.
245 ///\param name The name of the option. The leading '-' must be omitted.
246 ///\param help A help string.
247 ///\param obl Indicate if the option is mandatory.
248 ///\retval ref The value of the argument will be written to this variable.
249 ArgParser &refOption(const std::string &name,
250 const std::string &help,
251 int &ref, bool obl=false);
253 ///Add a new floating type option with a storage reference
255 ///Add a new floating type option with a storage reference.
256 ///\param name The name of the option. The leading '-' must be omitted.
257 ///\param help A help string.
258 ///\param obl Indicate if the option is mandatory.
259 ///\retval ref The value of the argument will be written to this variable.
260 ArgParser &refOption(const std::string &name,
261 const std::string &help,
262 double &ref, bool obl=false);
264 ///Add a new bool type option with a storage reference
266 ///Add a new bool type option with a storage reference.
267 ///\param name The name of the option. The leading '-' must be omitted.
268 ///\param help A help string.
269 ///\param obl Indicate if the option is mandatory.
270 ///\retval ref The value of the argument will be written to this variable.
271 ///\note A mandatory bool obtion is of very little use.
272 ArgParser &refOption(const std::string &name,
273 const std::string &help,
274 bool &ref, bool obl=false);
276 ///Add a new string type option with a storage reference
278 ///Add a new string type option with a storage reference.
279 ///\param name The name of the option. The leading '-' must be omitted.
280 ///\param help A help string.
281 ///\param obl Indicate if the option is mandatory.
282 ///\retval ref The value of the argument will be written to this variable.
283 ArgParser &refOption(const std::string &name,
284 const std::string &help,
285 std::string &ref, bool obl=false);
289 ///\name Option Groups and Synonyms
294 ///Bundle some options into a group
296 /// You can group some option by calling this function repeatedly for each
297 /// option to be grouped with the same groupname.
298 ///\param group The group name.
299 ///\param opt The option name.
300 ArgParser &optionGroup(const std::string &group,
301 const std::string &opt);
303 ///Make the members of a group exclusive
305 ///If you call this function for a group, than at most one of them can be
306 ///given at the same time.
307 ArgParser &onlyOneGroup(const std::string &group);
309 ///Make a group mandatory
311 ///Using this function, at least one of the members of \c group
313 ArgParser &mandatoryGroup(const std::string &group);
315 ///Create synonym to an option
317 ///With this function you can create a synonym \c syn of the
319 ArgParser &synonym(const std::string &syn,
320 const std::string &opt);
325 void show(std::ostream &os,Opts::const_iterator i) const;
326 void show(std::ostream &os,Groups::const_iterator i) const;
327 void showHelp(Opts::const_iterator i) const;
328 void showHelp(std::vector<OtherArg>::const_iterator i) const;
330 void unknownOpt(std::string arg) const;
332 void requiresValue(std::string arg, OptType t) const;
333 void checkMandatories() const;
335 void shortHelp() const;
336 void showHelp() const;
339 ///Start the parsing process
342 /// Synonym for parse()
348 ///Give back the command name (the 0th argument)
349 const std::string &commandName() const { return _command_name; }
351 ///Check if an opion has been given to the command.
352 bool given(std::string op) const
354 Opts::const_iterator i = _opts.find(op);
355 return i!=_opts.end()?i->second.set:false;
359 ///Magic type for operator[]
361 ///This is the type of the return value of ArgParser::operator[]().
362 ///It automatically converts to \c int, \c double, \c bool or
363 ///\c std::string if the type of the option matches, which is checked
364 ///with an \ref LEMON_ASSERT "assertion" (i.e. it performs runtime
368 const ArgParser &_parser;
372 RefType(const ArgParser &p,const std::string &n) :_parser(p),_name(n) {}
376 Opts::const_iterator i = _parser._opts.find(_name);
377 LEMON_ASSERT(i!=_parser._opts.end(),
378 std::string()+"Unkown option: '"+_name+"'");
379 LEMON_ASSERT(i->second.type==ArgParser::BOOL,
380 std::string()+"'"+_name+"' is a bool option");
381 return *(i->second.bool_p);
384 operator std::string()
386 Opts::const_iterator i = _parser._opts.find(_name);
387 LEMON_ASSERT(i!=_parser._opts.end(),
388 std::string()+"Unkown option: '"+_name+"'");
389 LEMON_ASSERT(i->second.type==ArgParser::STRING,
390 std::string()+"'"+_name+"' is a string option");
391 return *(i->second.string_p);
396 Opts::const_iterator i = _parser._opts.find(_name);
397 LEMON_ASSERT(i!=_parser._opts.end(),
398 std::string()+"Unkown option: '"+_name+"'");
399 LEMON_ASSERT(i->second.type==ArgParser::DOUBLE ||
400 i->second.type==ArgParser::INTEGER,
401 std::string()+"'"+_name+"' is a floating point option");
402 return i->second.type==ArgParser::DOUBLE ?
403 *(i->second.double_p) : *(i->second.int_p);
408 Opts::const_iterator i = _parser._opts.find(_name);
409 LEMON_ASSERT(i!=_parser._opts.end(),
410 std::string()+"Unkown option: '"+_name+"'");
411 LEMON_ASSERT(i->second.type==ArgParser::INTEGER,
412 std::string()+"'"+_name+"' is an integer option");
413 return *(i->second.int_p);
418 ///Give back the value of an option
420 ///Give back the value of an option.
422 RefType operator[](const std::string &n) const
424 return RefType(*this, n);
427 ///Give back the non-option type arguments.
429 ///Give back a reference to a vector consisting of the program arguments
430 ///not starting with a '-' character.
431 const std::vector<std::string> &files() const { return _file_args; }
433 ///Throw instead of exit in case of problems
434 void throwOnProblems()
436 _exit_on_problems=false;
441 #endif // LEMON_ARG_PARSER_H