1 /* -*- mode: C++; indent-tabs-mode: nil; -*-
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);
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);
274 void show(std::ostream &os,Opts::iterator i);
275 void show(std::ostream &os,Groups::iterator i);
276 void showHelp(Opts::iterator i);
277 void showHelp(std::vector<OtherArg>::iterator i);
281 void unknownOpt(std::string arg);
283 void requiresValue(std::string arg, OptType t);
284 void checkMandatories();
286 ///Start the parsing process
289 /// Synonym for parse()
295 ///Give back the command name (the 0th argument)
296 const std::string &commandName() { return _command_name; }
298 ///Check if an opion has been given to the command.
299 bool given(std::string op)
301 Opts::iterator i = _opts.find(op);
302 return i!=_opts.end()?i->second.set:false;
306 ///Magic type for operator[]
308 ///This is the type of the return value of ArgParser::operator[]().
309 ///It automatically converts to \c int, \c double, \c bool or
310 ///\c std::string if the type of the option matches, otherwise it
311 ///throws an exception (i.e. it performs runtime type checking).
318 RefType(ArgParser &p,const std::string &n) :_parser(p),_name(n) {}
322 Opts::iterator i = _parser._opts.find(_name);
323 LEMON_ASSERT(i!=_parser._opts.end(),
324 std::string()+"Unkown option: '"+_name+"'");
325 LEMON_ASSERT(i->second.type==ArgParser::BOOL,
326 std::string()+"'"+_name+"' is a bool option");
327 return *(i->second.bool_p);
330 operator std::string()
332 Opts::iterator i = _parser._opts.find(_name);
333 LEMON_ASSERT(i!=_parser._opts.end(),
334 std::string()+"Unkown option: '"+_name+"'");
335 LEMON_ASSERT(i->second.type==ArgParser::STRING,
336 std::string()+"'"+_name+"' is a string option");
337 return *(i->second.string_p);
342 Opts::iterator i = _parser._opts.find(_name);
343 LEMON_ASSERT(i!=_parser._opts.end(),
344 std::string()+"Unkown option: '"+_name+"'");
345 LEMON_ASSERT(i->second.type==ArgParser::DOUBLE ||
346 i->second.type==ArgParser::INTEGER,
347 std::string()+"'"+_name+"' is a floating point option");
348 return i->second.type==ArgParser::DOUBLE ?
349 *(i->second.double_p) : *(i->second.int_p);
354 Opts::iterator i = _parser._opts.find(_name);
355 LEMON_ASSERT(i!=_parser._opts.end(),
356 std::string()+"Unkown option: '"+_name+"'");
357 LEMON_ASSERT(i->second.type==ArgParser::INTEGER,
358 std::string()+"'"+_name+"' is an integer option");
359 return *(i->second.int_p);
364 ///Give back the value of an option
366 ///Give back the value of an option.
368 RefType operator[](const std::string &n)
370 return RefType(*this, n);
373 ///Give back the non-option type arguments.
375 ///Give back a reference to a vector consisting of the program arguments
376 ///not starting with a '-' character.
377 std::vector<std::string> &files() { return _file_args; }
382 #endif // LEMON_ARG_PARSER