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;
110 ArgParser(int argc, const char **argv);
114 ///Add a new integer type option
116 ///\param name The name of the option. The leading '-' must be omitted.
117 ///\param help A help string.
118 ///\retval value The value of the argument will be written to this variable.
119 ///\param obl Indicate if the option is mandatory.
120 ArgParser &intOption(const std::string &name,
121 const std::string &help,
122 int value=0, bool obl=false);
124 ///Add a new floating type option
126 ///\param name The name of the option. The leading '-' must be omitted.
127 ///\param help A help string.
128 ///\retval value The value of the argument will be written to this variable.
129 ///\param obl Indicate if the option is mandatory.
130 ArgParser &doubleOption(const std::string &name,
131 const std::string &help,
132 double value=0, bool obl=false);
134 ///Add a new bool type option
136 ///\param name The name of the option. The leading '-' must be omitted.
137 ///\param help A help string.
138 ///\retval value The value of the argument will be written to this variable.
139 ///\param obl Indicate if the option is mandatory.
140 ////\note A mandatory bool obtion is of very little use.)
141 ArgParser &boolOption(const std::string &name,
142 const std::string &help,
143 bool value=false, bool obl=false);
145 ///Add a new string type option
147 ///\param name The name of the option. The leading '-' must be omitted.
148 ///\param help A help string.
149 ///\retval value The value of the argument will be written to this variable.
150 ///\param obl Indicate if the option is mandatory.
151 ArgParser &stringOption(const std::string &name,
152 const std::string &help,
153 std::string value="", bool obl=false);
155 ///Bind a function to an option.
157 ///\param name The name of the option. The leading '-' must be omitted.
158 ///\param help A help string.
159 ///\retval func The function to be called when the option is given. It
160 /// must be of type "void f(void *)"
161 ///\param data Data to be passed to \c func
162 ArgParser &funcOption(const std::string &name,
163 const std::string &help,
164 void (*func)(void *),void *data);
166 ///\name Options with an external strorage.
167 ///Using this functions, the value of the option will be directly written
168 ///into a variable once the option appears in the command line.
172 ///Add a new integer type option with a storage reference
174 ///\param name The name of the option. The leading '-' must be omitted.
175 ///\param help A help string.
176 ///\retval ref The value of the argument will be written to this variable.
177 ///\param obl Indicate if the option is mandatory.
178 ArgParser &refOption(const std::string &name,
179 const std::string &help,
180 int &ref, bool obl=false);
182 ///Add a new floating type option with a storage reference
184 ///\param name The name of the option. The leading '-' must be omitted.
185 ///\param help A help string.
186 ///\retval ref The value of the argument will be written to this variable.
187 ///\param obl Indicate if the option is mandatory.
188 ArgParser &refOption(const std::string &name,
189 const std::string &help,
190 double &ref, bool obl=false);
192 ///Add a new bool type option with a storage reference
194 ///\param name The name of the option. The leading '-' must be omitted.
195 ///\param help A help string.
196 ///\retval ref The value of the argument will be written to this variable.
197 ///\param obl Indicate if the option is mandatory.
198 ////\note A mandatory bool obtion is of very little use.)
199 ArgParser &refOption(const std::string &name,
200 const std::string &help,
201 bool &ref, bool obl=false);
203 ///Add a new string type option with a storage reference
205 ///\param name The name of the option. The leading '-' must be omitted.
206 ///\param help A help string.
207 ///\retval ref The value of the argument will be written to this variable.
208 ///\param obl Indicate if the option is mandatory.
209 ArgParser &refOption(const std::string &name,
210 const std::string &help,
211 std::string &ref, bool obl=false);
215 ///\name Option Groups and Synonyms
220 ///Boundle some options into a group
222 /// You can group some option by calling this function repeatedly for each
223 /// option to be grupped with the same groupname.
224 ///\param group The group name
225 ///\param opt The option name
226 ArgParser &optionGroup(const std::string &group,
227 const std::string &opt);
229 ///Make the members of a group exclusive
231 ///If you call this function for a group, than at most one of them can be
232 ///given at the same time
233 ArgParser &onlyOneGroup(const std::string &group);
235 ///Make a group mandatory
237 ///Using this function, at least one of the members of \c group
239 ArgParser &mandatoryGroup(const std::string &group);
241 ///Create synonym to an option
243 ///With this function you can create a sysnonym called \c sys of the
245 ArgParser &synonym(const std::string &syn,
246 const std::string &opt);
250 ///Give help string for non-parsed arguments.
252 ///With this function you can give help string for non-parsed arguments.
253 ///the parameter \c name will be printed in the short usage line, while
254 ///\c help gives a more detailed description.
255 ArgParser &other(const std::string &name,
256 const std::string &help="");
258 ///Non option type arguments.
260 ///Gives back a reference to a vector consisting of the program arguments
261 ///not starting with a '-' character.
262 std::vector<std::string> &files() { return _file_args; }
264 ///Give back the command name (the 0th argument)
265 const std::string &commandName() { return _command_name; }
267 void show(std::ostream &os,Opts::iterator i);
268 void show(std::ostream &os,Groups::iterator i);
269 void showHelp(Opts::iterator i);
270 void showHelp(std::vector<OtherArg>::iterator i);
274 void unknownOpt(std::string arg);
276 void requiresValue(std::string arg, OptType t);
277 void checkMandatories();
279 ///Start the parsing process
282 /// Synonym for parse()
288 ///Check if an opion has been given to the command.
289 bool given(std::string op)
291 Opts::iterator i = _opts.find(op);
292 return i!=_opts.end()?i->second.set:false;
296 ///Magic type for operator[]
298 ///This is the type of the return value of ArgParser::operator[]().
299 ///It automatically converts to int, double, bool or std::string, if it
300 ///match the type of the option, otherwise it throws an exception.
301 ///(i.e. it performs runtime type checking).
308 RefType(ArgParser &p,const std::string &n) :_parser(p),_name(n) {}
312 Opts::iterator i = _parser._opts.find(_name);
313 LEMON_ASSERT(i==_parser._opts.end(),
314 std::string()+"Unkown option: '"+_name+"'");
315 LEMON_ASSERT(i->second.type!=ArgParser::BOOL,
316 std::string()+"'"+_name+"' is a bool option");
317 return *(i->second.bool_p);
320 operator std::string()
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::STRING,
326 std::string()+"'"+_name+"' is a string option");
327 return *(i->second.string_p);
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::DOUBLE &&
336 i->second.type!=ArgParser::INTEGER,
337 std::string()+"'"+_name+"' is a floating point option");
338 return i->second.type==ArgParser::DOUBLE ?
339 *(i->second.double_p) : *(i->second.int_p);
344 Opts::iterator i = _parser._opts.find(_name);
345 LEMON_ASSERT(i==_parser._opts.end(),
346 std::string()+"Unkown option: '"+_name+"'");
347 LEMON_ASSERT(i->second.type!=ArgParser::INTEGER,
348 std::string()+"'"+_name+"' is an integer option");
349 return *(i->second.int_p);
354 ///Give back the value of an option
356 ///Give back the value of an option
358 RefType operator[](const std::string &n)
360 return RefType(*this, n);
368 #endif // LEMON_MAIN_PARAMS