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 ///Command line arguments parser
40 ///Command line arguments parser.
42 ///For a complete example see the \ref arg_parser_demo.cc demo file.
45 static void _showHelp(void *p);
49 const char * const *_argv;
51 enum OptType { UNKNOWN=0, BOOL=1, STRING=2, DOUBLE=3, INTEGER=4, FUNC=5 };
59 std::string *string_p;
74 ParData() : mandatory(false), type(UNKNOWN), set(false), ingroup(false),
75 has_syn(false), syn(false), self_delete(false) {}
78 typedef std::map<std::string,ParData> Opts;
84 typedef std::list<std::string> Opts;
88 GroupData() :only_one(false), mandatory(false) {}
91 typedef std::map<std::string,GroupData> Groups;
98 OtherArg(std::string n, std::string h) :name(n), help(h) {}
102 std::vector<OtherArg> _others_help;
103 std::vector<std::string> _file_args;
104 std::string _command_name;
108 //Bind a function to an option.
110 //\param name The name of the option. The leading '-' must be omitted.
111 //\param help A help string.
112 //\retval func The function to be called when the option is given. It
113 // must be of type "void f(void *)"
114 //\param data Data to be passed to \c func
115 ArgParser &funcOption(const std::string &name,
116 const std::string &help,
117 void (*func)(void *),void *data);
122 ArgParser(int argc, const char * const *argv);
131 ///Add a new integer type option
133 ///Add a new integer type option.
134 ///\param name The name of the option. The leading '-' must be omitted.
135 ///\param help A help string.
136 ///\param value A default value for the option.
137 ///\param obl Indicate if the option is mandatory.
138 ArgParser &intOption(const std::string &name,
139 const std::string &help,
140 int value=0, bool obl=false);
142 ///Add a new floating point type option
144 ///Add a new floating point type option.
145 ///\param name The name of the option. The leading '-' must be omitted.
146 ///\param help A help string.
147 ///\param value A default value for the option.
148 ///\param obl Indicate if the option is mandatory.
149 ArgParser &doubleOption(const std::string &name,
150 const std::string &help,
151 double value=0, bool obl=false);
153 ///Add a new bool type option
155 ///Add a new bool type option.
156 ///\param name The name of the option. The leading '-' must be omitted.
157 ///\param help A help string.
158 ///\param value A default value for the option.
159 ///\param obl Indicate if the option is mandatory.
160 ///\note A mandatory bool obtion is of very little use.
161 ArgParser &boolOption(const std::string &name,
162 const std::string &help,
163 bool value=false, bool obl=false);
165 ///Add a new string type option
167 ///Add a new string type option.
168 ///\param name The name of the option. The leading '-' must be omitted.
169 ///\param help A help string.
170 ///\param value A default value for the option.
171 ///\param obl Indicate if the option is mandatory.
172 ArgParser &stringOption(const std::string &name,
173 const std::string &help,
174 std::string value="", bool obl=false);
176 ///Give help string for non-parsed arguments.
178 ///With this function you can give help string for non-parsed arguments.
179 ///The parameter \c name will be printed in the short usage line, while
180 ///\c help gives a more detailed description.
181 ArgParser &other(const std::string &name,
182 const std::string &help="");
186 ///\name Options with External Storage
187 ///Using this functions, the value of the option will be directly written
188 ///into a variable once the option appears in the command line.
192 ///Add a new integer type option with a storage reference
194 ///Add a new integer type option with a storage reference.
195 ///\param name The name of the option. The leading '-' must be omitted.
196 ///\param help A help string.
197 ///\param obl Indicate if the option is mandatory.
198 ///\retval ref The value of the argument will be written to this variable.
199 ArgParser &refOption(const std::string &name,
200 const std::string &help,
201 int &ref, bool obl=false);
203 ///Add a new floating type option with a storage reference
205 ///Add a new floating type option with a storage reference.
206 ///\param name The name of the option. The leading '-' must be omitted.
207 ///\param help A help string.
208 ///\param obl Indicate if the option is mandatory.
209 ///\retval ref The value of the argument will be written to this variable.
210 ArgParser &refOption(const std::string &name,
211 const std::string &help,
212 double &ref, bool obl=false);
214 ///Add a new bool type option with a storage reference
216 ///Add a new bool type option with a storage reference.
217 ///\param name The name of the option. The leading '-' must be omitted.
218 ///\param help A help string.
219 ///\param obl Indicate if the option is mandatory.
220 ///\retval ref The value of the argument will be written to this variable.
221 ///\note A mandatory bool obtion is of very little use.
222 ArgParser &refOption(const std::string &name,
223 const std::string &help,
224 bool &ref, bool obl=false);
226 ///Add a new string type option with a storage reference
228 ///Add a new string type option with a storage reference.
229 ///\param name The name of the option. The leading '-' must be omitted.
230 ///\param help A help string.
231 ///\param obl Indicate if the option is mandatory.
232 ///\retval ref The value of the argument will be written to this variable.
233 ArgParser &refOption(const std::string &name,
234 const std::string &help,
235 std::string &ref, bool obl=false);
239 ///\name Option Groups and Synonyms
244 ///Bundle some options into a group
246 /// You can group some option by calling this function repeatedly for each
247 /// option to be grouped with the same groupname.
248 ///\param group The group name.
249 ///\param opt The option name.
250 ArgParser &optionGroup(const std::string &group,
251 const std::string &opt);
253 ///Make the members of a group exclusive
255 ///If you call this function for a group, than at most one of them can be
256 ///given at the same time.
257 ArgParser &onlyOneGroup(const std::string &group);
259 ///Make a group mandatory
261 ///Using this function, at least one of the members of \c group
263 ArgParser &mandatoryGroup(const std::string &group);
265 ///Create synonym to an option
267 ///With this function you can create a synonym \c syn of the
269 ArgParser &synonym(const std::string &syn,
270 const std::string &opt);
275 void show(std::ostream &os,Opts::const_iterator i) const;
276 void show(std::ostream &os,Groups::const_iterator i) const;
277 void showHelp(Opts::const_iterator i) const;
278 void showHelp(std::vector<OtherArg>::const_iterator i) const;
280 void unknownOpt(std::string arg) const;
282 void requiresValue(std::string arg, OptType t) const;
283 void checkMandatories() const;
285 void shortHelp() const;
286 void showHelp() const;
289 ///Start the parsing process
292 /// Synonym for parse()
298 ///Give back the command name (the 0th argument)
299 const std::string &commandName() const { return _command_name; }
301 ///Check if an opion has been given to the command.
302 bool given(std::string op) const
304 Opts::const_iterator i = _opts.find(op);
305 return i!=_opts.end()?i->second.set:false;
309 ///Magic type for operator[]
311 ///This is the type of the return value of ArgParser::operator[]().
312 ///It automatically converts to \c int, \c double, \c bool or
313 ///\c std::string if the type of the option matches, which is checked
314 ///with an \ref LEMON_ASSERT "assertion" (i.e. it performs runtime
318 const ArgParser &_parser;
322 RefType(const ArgParser &p,const std::string &n) :_parser(p),_name(n) {}
326 Opts::const_iterator i = _parser._opts.find(_name);
327 LEMON_ASSERT(i!=_parser._opts.end(),
328 std::string()+"Unkown option: '"+_name+"'");
329 LEMON_ASSERT(i->second.type==ArgParser::BOOL,
330 std::string()+"'"+_name+"' is a bool option");
331 return *(i->second.bool_p);
334 operator std::string()
336 Opts::const_iterator i = _parser._opts.find(_name);
337 LEMON_ASSERT(i!=_parser._opts.end(),
338 std::string()+"Unkown option: '"+_name+"'");
339 LEMON_ASSERT(i->second.type==ArgParser::STRING,
340 std::string()+"'"+_name+"' is a string option");
341 return *(i->second.string_p);
346 Opts::const_iterator i = _parser._opts.find(_name);
347 LEMON_ASSERT(i!=_parser._opts.end(),
348 std::string()+"Unkown option: '"+_name+"'");
349 LEMON_ASSERT(i->second.type==ArgParser::DOUBLE ||
350 i->second.type==ArgParser::INTEGER,
351 std::string()+"'"+_name+"' is a floating point option");
352 return i->second.type==ArgParser::DOUBLE ?
353 *(i->second.double_p) : *(i->second.int_p);
358 Opts::const_iterator i = _parser._opts.find(_name);
359 LEMON_ASSERT(i!=_parser._opts.end(),
360 std::string()+"Unkown option: '"+_name+"'");
361 LEMON_ASSERT(i->second.type==ArgParser::INTEGER,
362 std::string()+"'"+_name+"' is an integer option");
363 return *(i->second.int_p);
368 ///Give back the value of an option
370 ///Give back the value of an option.
372 RefType operator[](const std::string &n) const
374 return RefType(*this, n);
377 ///Give back the non-option type arguments.
379 ///Give back a reference to a vector consisting of the program arguments
380 ///not starting with a '-' character.
381 const std::vector<std::string> &files() const { return _file_args; }
386 #endif // LEMON_ARG_PARSER_H