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/error.h>
33 ///\brief A tools to parse command line arguments.
35 ///\author Alpar Juttner
39 ///Command line arguments parser
42 ///Command line arguments parser
46 static void _showHelp(void *p);
52 enum OptType { UNKNOWN=0, BOOL=1, STRING=2, DOUBLE=3, INTEGER=4, FUNC=5 };
60 std::string *string_p;
75 ParData() : mandatory(false), type(UNKNOWN), set(false), ingroup(false),
76 has_syn(false), syn(false), self_delete(false) {}
79 typedef std::map<std::string,ParData> Opts;
85 typedef std::list<std::string> Opts;
89 GroupData() :only_one(false), mandatory(false) {}
92 typedef std::map<std::string,GroupData> Groups;
99 OtherArg(std::string n, std::string h) :name(n), help(h) {}
103 std::vector<OtherArg> _others_help;
104 std::vector<std::string> _file_args;
105 std::string _command_name;
109 //Bind a function to an option.
111 //\param name The name of the option. The leading '-' must be omitted.
112 //\param help A help string.
113 //\retval func The function to be called when the option is given. It
114 // must be of type "void f(void *)"
115 //\param data Data to be passed to \c func
116 ArgParser &funcOption(const std::string &name,
117 const std::string &help,
118 void (*func)(void *),void *data);
123 ArgParser(int argc, const char **argv);
127 ///Add a new integer type option
129 ///\param name The name of the option. The leading '-' must be omitted.
130 ///\param help A help string.
131 ///\retval value The value of the argument will be written to this variable.
132 ///\param obl Indicate if the option is mandatory.
133 ArgParser &intOption(const std::string &name,
134 const std::string &help,
135 int value=0, bool obl=false);
137 ///Add a new floating point type option
139 ///\param name The name of the option. The leading '-' must be omitted.
140 ///\param help A help string.
141 ///\retval value The value of the argument will be written to this variable.
142 ///\param obl Indicate if the option is mandatory.
143 ArgParser &doubleOption(const std::string &name,
144 const std::string &help,
145 double value=0, bool obl=false);
147 ///Add a new bool type option
149 ///\param name The name of the option. The leading '-' must be omitted.
150 ///\param help A help string.
151 ///\retval value The value of the argument will be written to this variable.
152 ///\param obl Indicate if the option is mandatory.
153 ////\note A mandatory bool obtion is of very little use.)
154 ArgParser &boolOption(const std::string &name,
155 const std::string &help,
156 bool value=false, bool obl=false);
158 ///Add a new string type option
160 ///\param name The name of the option. The leading '-' must be omitted.
161 ///\param help A help string.
162 ///\retval value The value of the argument will be written to this variable.
163 ///\param obl Indicate if the option is mandatory.
164 ArgParser &stringOption(const std::string &name,
165 const std::string &help,
166 std::string value="", bool obl=false);
168 ///\name Options with an external strorage.
169 ///Using this functions, the value of the option will be directly written
170 ///into a variable once the option appears in the command line.
174 ///Add a new integer type option with a storage reference
176 ///\param name The name of the option. The leading '-' must be omitted.
177 ///\param help A help string.
178 ///\retval ref The value of the argument will be written to this variable.
179 ///\param obl Indicate if the option is mandatory.
180 ArgParser &refOption(const std::string &name,
181 const std::string &help,
182 int &ref, bool obl=false);
184 ///Add a new floating type option with a storage reference
186 ///\param name The name of the option. The leading '-' must be omitted.
187 ///\param help A help string.
188 ///\retval ref The value of the argument will be written to this variable.
189 ///\param obl Indicate if the option is mandatory.
190 ArgParser &refOption(const std::string &name,
191 const std::string &help,
192 double &ref, bool obl=false);
194 ///Add a new bool type option with a storage reference
196 ///\param name The name of the option. The leading '-' must be omitted.
197 ///\param help A help string.
198 ///\retval ref The value of the argument will be written to this variable.
199 ///\param obl Indicate if the option is mandatory.
200 ////\note A mandatory bool obtion is of very little use.)
201 ArgParser &refOption(const std::string &name,
202 const std::string &help,
203 bool &ref, bool obl=false);
205 ///Add a new string type option with a storage reference
207 ///\param name The name of the option. The leading '-' must be omitted.
208 ///\param help A help string.
209 ///\retval ref The value of the argument will be written to this variable.
210 ///\param obl Indicate if the option is mandatory.
211 ArgParser &refOption(const std::string &name,
212 const std::string &help,
213 std::string &ref, bool obl=false);
217 ///\name Option Groups and Synonyms
222 ///Boundle some options into a group
224 /// You can group some option by calling this function repeatedly for each
225 /// option to be grupped with the same groupname.
226 ///\param group The group name
227 ///\param opt The option name
228 ArgParser &optionGroup(const std::string &group,
229 const std::string &opt);
231 ///Make the members of a group exclusive
233 ///If you call this function for a group, than at most one of them can be
234 ///given at the same time
235 ArgParser &onlyOneGroup(const std::string &group);
237 ///Make a group mandatory
239 ///Using this function, at least one of the members of \c group
241 ArgParser &mandatoryGroup(const std::string &group);
243 ///Create synonym to an option
245 ///With this function you can create a sysnonym called \c sys of the
247 ArgParser &synonym(const std::string &syn,
248 const std::string &opt);
252 ///Give help string for non-parsed arguments.
254 ///With this function you can give help string for non-parsed arguments.
255 ///the parameter \c name will be printed in the short usage line, while
256 ///\c help gives a more detailed description.
257 ArgParser &other(const std::string &name,
258 const std::string &help="");
260 ///Non option type arguments.
262 ///Gives back a reference to a vector consisting of the program arguments
263 ///not starting with a '-' character.
264 std::vector<std::string> &files() { return _file_args; }
266 ///Give back the command name (the 0th argument)
267 const std::string &commandName() { return _command_name; }
269 void show(std::ostream &os,Opts::iterator i);
270 void show(std::ostream &os,Groups::iterator i);
271 void showHelp(Opts::iterator i);
272 void showHelp(std::vector<OtherArg>::iterator i);
276 void unknownOpt(std::string arg);
278 void requiresValue(std::string arg, OptType t);
279 void checkMandatories();
281 ///Start the parsing process
284 /// Synonym for parse()
290 ///Check if an opion has been given to the command.
291 bool given(std::string op)
293 Opts::iterator i = _opts.find(op);
294 return i!=_opts.end()?i->second.set:false;
298 ///Magic type for operator[]
300 ///This is the type of the return value of ArgParser::operator[]().
301 ///It automatically converts to int, double, bool or std::string if
302 ///the type of the option matches, otherwise it throws an exception.
303 ///(i.e. it performs runtime type checking).
310 RefType(ArgParser &p,const std::string &n) :_parser(p),_name(n) {}
314 Opts::iterator i = _parser._opts.find(_name);
315 LEMON_ASSERT(i==_parser._opts.end(),
316 std::string()+"Unkown option: '"+_name+"'");
317 LEMON_ASSERT(i->second.type!=ArgParser::BOOL,
318 std::string()+"'"+_name+"' is a bool option");
319 return *(i->second.bool_p);
322 operator std::string()
324 Opts::iterator i = _parser._opts.find(_name);
325 LEMON_ASSERT(i==_parser._opts.end(),
326 std::string()+"Unkown option: '"+_name+"'");
327 LEMON_ASSERT(i->second.type!=ArgParser::STRING,
328 std::string()+"'"+_name+"' is a string option");
329 return *(i->second.string_p);
334 Opts::iterator i = _parser._opts.find(_name);
335 LEMON_ASSERT(i==_parser._opts.end(),
336 std::string()+"Unkown option: '"+_name+"'");
337 LEMON_ASSERT(i->second.type!=ArgParser::DOUBLE &&
338 i->second.type!=ArgParser::INTEGER,
339 std::string()+"'"+_name+"' is a floating point option");
340 return i->second.type==ArgParser::DOUBLE ?
341 *(i->second.double_p) : *(i->second.int_p);
346 Opts::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::INTEGER,
350 std::string()+"'"+_name+"' is an integer option");
351 return *(i->second.int_p);
356 ///Give back the value of an option
358 ///Give back the value of an option
360 RefType operator[](const std::string &n)
362 return RefType(*this, n);
370 #endif // LEMON_MAIN_PARAMS