3 * This file is a part of LEMON, a generic C++ optimization library
5 * Copyright (C) 2003-2008
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
20 #define LEMON_ARG_PARSER
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);
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 **argv);
126 ///Add a new integer type option
128 ///\param name The name of the option. The leading '-' must be omitted.
129 ///\param help A help string.
130 ///\param value A default value for the option.
131 ///\param obl Indicate if the option is mandatory.
132 ArgParser &intOption(const std::string &name,
133 const std::string &help,
134 int value=0, bool obl=false);
136 ///Add a new floating point type option
138 ///\param name The name of the option. The leading '-' must be omitted.
139 ///\param help A help string.
140 ///\param value A default value for the option.
141 ///\param obl Indicate if the option is mandatory.
142 ArgParser &doubleOption(const std::string &name,
143 const std::string &help,
144 double value=0, bool obl=false);
146 ///Add a new bool type option
148 ///\param name The name of the option. The leading '-' must be omitted.
149 ///\param help A help string.
150 ///\param value A default value for the option.
151 ///\param obl Indicate if the option is mandatory.
152 ///\note A mandatory bool obtion is of very little use.
153 ArgParser &boolOption(const std::string &name,
154 const std::string &help,
155 bool value=false, bool obl=false);
157 ///Add a new string type option
159 ///\param name The name of the option. The leading '-' must be omitted.
160 ///\param help A help string.
161 ///\param value A default value for the option.
162 ///\param obl Indicate if the option is mandatory.
163 ArgParser &stringOption(const std::string &name,
164 const std::string &help,
165 std::string value="", bool obl=false);
167 ///\name Options with external storage
168 ///Using this functions, the value of the option will be directly written
169 ///into a variable once the option appears in the command line.
173 ///Add a new integer type option with a storage reference
175 ///\param name The name of the option. The leading '-' must be omitted.
176 ///\param help A help string.
177 ///\param obl Indicate if the option is mandatory.
178 ///\retval ref The value of the argument will be written to this variable.
179 ArgParser &refOption(const std::string &name,
180 const std::string &help,
181 int &ref, bool obl=false);
183 ///Add a new floating type option with a storage reference
185 ///\param name The name of the option. The leading '-' must be omitted.
186 ///\param help A help string.
187 ///\param obl Indicate if the option is mandatory.
188 ///\retval ref The value of the argument will be written to this variable.
189 ArgParser &refOption(const std::string &name,
190 const std::string &help,
191 double &ref, bool obl=false);
193 ///Add a new bool 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 ///\note A mandatory bool obtion is of very little use.
200 ArgParser &refOption(const std::string &name,
201 const std::string &help,
202 bool &ref, bool obl=false);
204 ///Add a new string 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 std::string &ref, bool obl=false);
216 ///\name Option Groups and Synonyms
221 ///Boundle some options into a group
223 /// You can group some option by calling this function repeatedly for each
224 /// option to be grouped with the same groupname.
225 ///\param group The group name.
226 ///\param opt The option name.
227 ArgParser &optionGroup(const std::string &group,
228 const std::string &opt);
230 ///Make the members of a group exclusive
232 ///If you call this function for a group, than at most one of them can be
233 ///given at the same time
234 ArgParser &onlyOneGroup(const std::string &group);
236 ///Make a group mandatory
238 ///Using this function, at least one of the members of \c group
240 ArgParser &mandatoryGroup(const std::string &group);
242 ///Create synonym to an option
244 ///With this function you can create a synonym \c syn of the
246 ArgParser &synonym(const std::string &syn,
247 const std::string &opt);
251 ///Give help string for non-parsed arguments.
253 ///With this function you can give help string for non-parsed arguments.
254 ///The parameter \c name will be printed in the short usage line, while
255 ///\c help gives a more detailed description.
256 ArgParser &other(const std::string &name,
257 const std::string &help="");
259 ///Give back the non-option type arguments.
261 ///Give back a reference to a vector consisting of the program arguments
262 ///not starting with a '-' character.
263 std::vector<std::string> &files() { return _file_args; }
265 ///Give back the command name (the 0th argument)
266 const std::string &commandName() { return _command_name; }
268 void show(std::ostream &os,Opts::iterator i);
269 void show(std::ostream &os,Groups::iterator i);
270 void showHelp(Opts::iterator i);
271 void showHelp(std::vector<OtherArg>::iterator i);
275 void unknownOpt(std::string arg);
277 void requiresValue(std::string arg, OptType t);
278 void checkMandatories();
280 ///Start the parsing process
283 /// Synonym for parse()
289 ///Check if an opion has been given to the command.
290 bool given(std::string op)
292 Opts::iterator i = _opts.find(op);
293 return i!=_opts.end()?i->second.set:false;
297 ///Magic type for operator[]
299 ///This is the type of the return value of ArgParser::operator[]().
300 ///It automatically converts to \c int, \c double, \c bool or
301 ///\c std::string if the type of the option matches, otherwise it
302 ///throws an exception (i.e. it performs runtime type checking).
309 RefType(ArgParser &p,const std::string &n) :_parser(p),_name(n) {}
313 Opts::iterator i = _parser._opts.find(_name);
314 LEMON_ASSERT(i!=_parser._opts.end(),
315 std::string()+"Unkown option: '"+_name+"'");
316 LEMON_ASSERT(i->second.type==ArgParser::BOOL,
317 std::string()+"'"+_name+"' is a bool option");
318 return *(i->second.bool_p);
321 operator std::string()
323 Opts::iterator i = _parser._opts.find(_name);
324 LEMON_ASSERT(i!=_parser._opts.end(),
325 std::string()+"Unkown option: '"+_name+"'");
326 LEMON_ASSERT(i->second.type==ArgParser::STRING,
327 std::string()+"'"+_name+"' is a string option");
328 return *(i->second.string_p);
333 Opts::iterator i = _parser._opts.find(_name);
334 LEMON_ASSERT(i!=_parser._opts.end(),
335 std::string()+"Unkown option: '"+_name+"'");
336 LEMON_ASSERT(i->second.type==ArgParser::DOUBLE ||
337 i->second.type==ArgParser::INTEGER,
338 std::string()+"'"+_name+"' is a floating point option");
339 return i->second.type==ArgParser::DOUBLE ?
340 *(i->second.double_p) : *(i->second.int_p);
345 Opts::iterator i = _parser._opts.find(_name);
346 LEMON_ASSERT(i!=_parser._opts.end(),
347 std::string()+"Unkown option: '"+_name+"'");
348 LEMON_ASSERT(i->second.type==ArgParser::INTEGER,
349 std::string()+"'"+_name+"' is an integer option");
350 return *(i->second.int_p);
355 ///Give back the value of an option
357 ///Give back the value of an option.
359 RefType operator[](const std::string &n)
361 return RefType(*this, n);
369 #endif // LEMON_MAIN_PARAMS