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/assert.h>
33 ///\brief A tool to parse command line arguments.
37 ///Exception used by ArgParser
39 ///Exception used by ArgParser.
41 class ArgParserException : public Exception {
43 /// Reasons for failure
45 /// Reasons for failure.
48 HELP, ///< <tt>--help</tt> option was given.
49 UNKNOWN_OPT, ///< Unknown option was given.
50 INVALID_OPT ///< Invalid combination of options.
58 ArgParserException(Reason r) throw() : _reason(r) {}
60 virtual ~ArgParserException() throw() {}
61 ///A short description of the exception
62 virtual const char* what() const throw() {
66 return "lemon::ArgParseException: ask for help";
69 return "lemon::ArgParseException: unknown option";
72 return "lemon::ArgParseException: invalid combination of options";
77 ///Return the reason for the failure
78 Reason reason() const {return _reason; }
82 ///Command line arguments parser
85 ///Command line arguments parser.
87 ///For a complete example see the \ref arg_parser_demo.cc demo file.
90 static void _showHelp(void *p);
94 const char * const *_argv;
96 enum OptType { UNKNOWN=0, BOOL=1, STRING=2, DOUBLE=3, INTEGER=4, FUNC=5 };
104 std::string *string_p;
119 ParData() : mandatory(false), type(UNKNOWN), set(false), ingroup(false),
120 has_syn(false), syn(false), self_delete(false) {}
123 typedef std::map<std::string,ParData> Opts;
129 typedef std::list<std::string> Opts;
133 GroupData() :only_one(false), mandatory(false) {}
136 typedef std::map<std::string,GroupData> Groups;
143 OtherArg(std::string n, std::string h) :name(n), help(h) {}
147 std::vector<OtherArg> _others_help;
148 std::vector<std::string> _file_args;
149 std::string _command_name;
153 //Bind a function to an option.
155 //\param name The name of the option. The leading '-' must be omitted.
156 //\param help A help string.
157 //\retval func The function to be called when the option is given. It
158 // must be of type "void f(void *)"
159 //\param data Data to be passed to \c func
160 ArgParser &funcOption(const std::string &name,
161 const std::string &help,
162 void (*func)(void *),void *data);
164 bool _exit_on_problems;
166 void _terminate(ArgParserException::Reason reason) const;
171 ArgParser(int argc, const char * const *argv);
180 ///Add a new integer type option
182 ///Add a new integer type option.
183 ///\param name The name of the option. The leading '-' must be omitted.
184 ///\param help A help string.
185 ///\param value A default value for the option.
186 ///\param obl Indicate if the option is mandatory.
187 ArgParser &intOption(const std::string &name,
188 const std::string &help,
189 int value=0, bool obl=false);
191 ///Add a new floating point type option
193 ///Add a new floating point type option.
194 ///\param name The name of the option. The leading '-' must be omitted.
195 ///\param help A help string.
196 ///\param value A default value for the option.
197 ///\param obl Indicate if the option is mandatory.
198 ArgParser &doubleOption(const std::string &name,
199 const std::string &help,
200 double value=0, bool obl=false);
202 ///Add a new bool type option
204 ///Add a new bool type option.
205 ///\param name The name of the option. The leading '-' must be omitted.
206 ///\param help A help string.
207 ///\param value A default value for the option.
208 ///\param obl Indicate if the option is mandatory.
209 ///\note A mandatory bool obtion is of very little use.
210 ArgParser &boolOption(const std::string &name,
211 const std::string &help,
212 bool value=false, bool obl=false);
214 ///Add a new string type option
216 ///Add a new string type option.
217 ///\param name The name of the option. The leading '-' must be omitted.
218 ///\param help A help string.
219 ///\param value A default value for the option.
220 ///\param obl Indicate if the option is mandatory.
221 ArgParser &stringOption(const std::string &name,
222 const std::string &help,
223 std::string value="", bool obl=false);
225 ///Give help string for non-parsed arguments.
227 ///With this function you can give help string for non-parsed arguments.
228 ///The parameter \c name will be printed in the short usage line, while
229 ///\c help gives a more detailed description.
230 ArgParser &other(const std::string &name,
231 const std::string &help="");
235 ///\name Options with External Storage
236 ///Using this functions, the value of the option will be directly written
237 ///into a variable once the option appears in the command line.
241 ///Add a new integer type option with a storage reference
243 ///Add a new integer type option with a storage reference.
244 ///\param name The name of the option. The leading '-' must be omitted.
245 ///\param help A help string.
246 ///\param obl Indicate if the option is mandatory.
247 ///\retval ref The value of the argument will be written to this variable.
248 ArgParser &refOption(const std::string &name,
249 const std::string &help,
250 int &ref, bool obl=false);
252 ///Add a new floating type option with a storage reference
254 ///Add a new floating type option with a storage reference.
255 ///\param name The name of the option. The leading '-' must be omitted.
256 ///\param help A help string.
257 ///\param obl Indicate if the option is mandatory.
258 ///\retval ref The value of the argument will be written to this variable.
259 ArgParser &refOption(const std::string &name,
260 const std::string &help,
261 double &ref, bool obl=false);
263 ///Add a new bool type option with a storage reference
265 ///Add a new bool type option with a storage reference.
266 ///\param name The name of the option. The leading '-' must be omitted.
267 ///\param help A help string.
268 ///\param obl Indicate if the option is mandatory.
269 ///\retval ref The value of the argument will be written to this variable.
270 ///\note A mandatory bool obtion is of very little use.
271 ArgParser &refOption(const std::string &name,
272 const std::string &help,
273 bool &ref, bool obl=false);
275 ///Add a new string type option with a storage reference
277 ///Add a new string type option with a storage reference.
278 ///\param name The name of the option. The leading '-' must be omitted.
279 ///\param help A help string.
280 ///\param obl Indicate if the option is mandatory.
281 ///\retval ref The value of the argument will be written to this variable.
282 ArgParser &refOption(const std::string &name,
283 const std::string &help,
284 std::string &ref, bool obl=false);
288 ///\name Option Groups and Synonyms
293 ///Bundle some options into a group
295 /// You can group some option by calling this function repeatedly for each
296 /// option to be grouped with the same groupname.
297 ///\param group The group name.
298 ///\param opt The option name.
299 ArgParser &optionGroup(const std::string &group,
300 const std::string &opt);
302 ///Make the members of a group exclusive
304 ///If you call this function for a group, than at most one of them can be
305 ///given at the same time.
306 ArgParser &onlyOneGroup(const std::string &group);
308 ///Make a group mandatory
310 ///Using this function, at least one of the members of \c group
312 ArgParser &mandatoryGroup(const std::string &group);
314 ///Create synonym to an option
316 ///With this function you can create a synonym \c syn of the
318 ArgParser &synonym(const std::string &syn,
319 const std::string &opt);
324 void show(std::ostream &os,Opts::const_iterator i) const;
325 void show(std::ostream &os,Groups::const_iterator i) const;
326 void showHelp(Opts::const_iterator i) const;
327 void showHelp(std::vector<OtherArg>::const_iterator i) const;
329 void unknownOpt(std::string arg) const;
331 void requiresValue(std::string arg, OptType t) const;
332 void checkMandatories() const;
334 void shortHelp() const;
335 void showHelp() const;
338 ///Start the parsing process
341 /// Synonym for parse()
347 ///Give back the command name (the 0th argument)
348 const std::string &commandName() const { return _command_name; }
350 ///Check if an opion has been given to the command.
351 bool given(std::string op) const
353 Opts::const_iterator i = _opts.find(op);
354 return i!=_opts.end()?i->second.set:false;
358 ///Magic type for operator[]
360 ///This is the type of the return value of ArgParser::operator[]().
361 ///It automatically converts to \c int, \c double, \c bool or
362 ///\c std::string if the type of the option matches, which is checked
363 ///with an \ref LEMON_ASSERT "assertion" (i.e. it performs runtime
367 const ArgParser &_parser;
371 RefType(const ArgParser &p,const std::string &n) :_parser(p),_name(n) {}
375 Opts::const_iterator i = _parser._opts.find(_name);
376 LEMON_ASSERT(i!=_parser._opts.end(),
377 std::string()+"Unkown option: '"+_name+"'");
378 LEMON_ASSERT(i->second.type==ArgParser::BOOL,
379 std::string()+"'"+_name+"' is a bool option");
380 return *(i->second.bool_p);
383 operator std::string()
385 Opts::const_iterator i = _parser._opts.find(_name);
386 LEMON_ASSERT(i!=_parser._opts.end(),
387 std::string()+"Unkown option: '"+_name+"'");
388 LEMON_ASSERT(i->second.type==ArgParser::STRING,
389 std::string()+"'"+_name+"' is a string option");
390 return *(i->second.string_p);
395 Opts::const_iterator i = _parser._opts.find(_name);
396 LEMON_ASSERT(i!=_parser._opts.end(),
397 std::string()+"Unkown option: '"+_name+"'");
398 LEMON_ASSERT(i->second.type==ArgParser::DOUBLE ||
399 i->second.type==ArgParser::INTEGER,
400 std::string()+"'"+_name+"' is a floating point option");
401 return i->second.type==ArgParser::DOUBLE ?
402 *(i->second.double_p) : *(i->second.int_p);
407 Opts::const_iterator i = _parser._opts.find(_name);
408 LEMON_ASSERT(i!=_parser._opts.end(),
409 std::string()+"Unkown option: '"+_name+"'");
410 LEMON_ASSERT(i->second.type==ArgParser::INTEGER,
411 std::string()+"'"+_name+"' is an integer option");
412 return *(i->second.int_p);
417 ///Give back the value of an option
419 ///Give back the value of an option.
421 RefType operator[](const std::string &n) const
423 return RefType(*this, n);
426 ///Give back the non-option type arguments.
428 ///Give back a reference to a vector consisting of the program arguments
429 ///not starting with a '-' character.
430 const std::vector<std::string> &files() const { return _file_args; }
432 ///Throw instead of exit in case of problems
433 void throwOnProblems()
435 _exit_on_problems=false;
440 #endif // LEMON_ARG_PARSER_H