COIN-OR::LEMON - Graph Library

source: lemon-0.x/lemon/arg_parser.h @ 2402:da8eb8f4ea41

Last change on this file since 2402:da8eb8f4ea41 was 2402:da8eb8f4ea41, checked in by Alpar Juttner, 13 years ago

An improved version of ArgParser?: You don't need to give an explicit storage
for each option.
TODO: Documentation must be updated

File size: 9.6 KB
Line 
1/* -*- C++ -*-
2 *
3 * This file is a part of LEMON, a generic C++ optimization library
4 *
5 * Copyright (C) 2003-2007
6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 * (Egervary Research Group on Combinatorial Optimization, EGRES).
8 *
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.
12 *
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
15 * purpose.
16 *
17 */
18
19#ifndef LEMON_ARG_PARSER
20#define LEMON_ARG_PARSER
21
22#include <vector>
23#include <map>
24#include <list>
25#include <string>
26#include <iostream>
27#include <sstream>
28#include <algorithm>
29
30///\ingroup misc
31///\file
32///\brief A tools to parse command line arguments.
33///
34///\author Alpar Juttner
35
36namespace lemon {
37
38  ///Command line arguments parser
39
40  ///\ingroup misc
41  ///Command line arguments parser
42  ///
43  class ArgParser {
44   
45    static void _showHelp(void *p);
46  protected:
47   
48    int _argc;
49    char **_argv;
50   
51    enum OptType { UNKNOWN=0, BOOL=1, STRING=2, DOUBLE=3, INTEGER=4, FUNC=5 };
52   
53    class ParData {
54    public:
55      union {
56        bool *bool_p;
57        int *int_p;
58        double *double_p;
59        std::string *string_p;
60        struct {
61          void (*p)(void *);
62          void *data;
63        } func_p;
64         
65      };
66      std::string help;
67      bool mandatory;
68      OptType type;
69      bool set;
70      bool ingroup;
71      bool has_syn;
72      bool syn;
73      bool self_delete;
74      ParData() : mandatory(false), type(UNKNOWN), set(false), ingroup(false),
75                  has_syn(false), syn(false), self_delete(false) {}
76    };
77
78    typedef std::map<std::string,ParData> Opts;
79    Opts _opts;
80
81    class GroupData
82    {
83    public:
84      typedef std::list<std::string> Opts;
85      Opts opts;
86      bool only_one;
87      bool mandatory;
88      GroupData() :only_one(false), mandatory(false) {}
89    };
90     
91    typedef std::map<std::string,GroupData> Groups;
92    Groups _groups;
93
94    struct OtherArg
95    {
96      std::string name;
97      std::string help;
98      OtherArg(std::string n, std::string h) :name(n), help(h) {}
99
100    };
101     
102    std::vector<OtherArg> _others_help;
103    std::vector<std::string> _file_args;
104    std::string _command_name;
105   
106  public:
107
108    ///\e
109    ArgParser(int argc, char **argv);
110
111    ~ArgParser();
112
113    ///Add a new integer type option
114
115    ///\param name The name of the option. The leading '-' must be omitted.
116    ///\param help A help string.
117    ///\retval value The value of the argument will be written to this variable.
118    ///\param obl Indicate if the option is mandatory.
119    ArgParser &intOption(const std::string &name,
120                    const std::string &help,
121                    int value=0, bool obl=false);
122
123    ///Add a new floating type option
124
125    ///\param name The name of the option. The leading '-' must be omitted.
126    ///\param help A help string.
127    ///\retval value The value of the argument will be written to this variable.
128    ///\param obl Indicate if the option is mandatory.
129    ArgParser &doubleOption(const std::string &name,
130                      const std::string &help,
131                      double value=0, bool obl=false);
132
133    ///Add a new bool type option
134
135    ///\param name The name of the option. The leading '-' must be omitted.
136    ///\param help A help string.
137    ///\retval value The value of the argument will be written to this variable.
138    ///\param obl Indicate if the option is mandatory.
139    ////\note A mandatory bool obtion is of very little use.)
140    ArgParser &boolOption(const std::string &name,
141                      const std::string &help,
142                      bool value=false, bool obl=false);
143
144    ///Add a new string type option
145
146    ///\param name The name of the option. The leading '-' must be omitted.
147    ///\param help A help string.
148    ///\retval value The value of the argument will be written to this variable.
149    ///\param obl Indicate if the option is mandatory.
150    ArgParser &stringOption(const std::string &name,
151                      const std::string &help,
152                      std::string value="", bool obl=false);
153   
154
155
156
157    ///Add a new integer type option
158
159    ///\param name The name of the option. The leading '-' must be omitted.
160    ///\param help A help string.
161    ///\retval value The value of the argument will be written to this variable.
162    ///\param obl Indicate if the option is mandatory.
163    ArgParser &refOption(const std::string &name,
164                    const std::string &help,
165                    int &value, bool obl=false);
166
167    ///Add a new floating type option
168
169    ///\param name The name of the option. The leading '-' must be omitted.
170    ///\param help A help string.
171    ///\retval value The value of the argument will be written to this variable.
172    ///\param obl Indicate if the option is mandatory.
173    ArgParser &refOption(const std::string &name,
174                      const std::string &help,
175                      double &value, bool obl=false);
176
177    ///Add a new bool type option
178
179    ///\param name The name of the option. The leading '-' must be omitted.
180    ///\param help A help string.
181    ///\retval value The value of the argument will be written to this variable.
182    ///\param obl Indicate if the option is mandatory.
183    ////\note A mandatory bool obtion is of very little use.)
184    ArgParser &refOption(const std::string &name,
185                      const std::string &help,
186                      bool &value, bool obl=false);
187
188    ///Add a new string type option
189
190    ///\param name The name of the option. The leading '-' must be omitted.
191    ///\param help A help string.
192    ///\retval value The value of the argument will be written to this variable.
193    ///\param obl Indicate if the option is mandatory.
194    ArgParser &refOption(const std::string &name,
195                      const std::string &help,
196                      std::string &value, bool obl=false);
197   
198    ///Bind a function to an option.
199
200    ///\param name The name of the option. The leading '-' must be omitted.
201    ///\param help A help string.
202    ///\retval func The function to be called when the option is given. It
203    ///  must be of type "void f(void *)"
204    ///\param data Data to be passed to \c func
205    ArgParser &refOption(const std::string &name,
206                    const std::string &help,
207                    void (*func)(void *),void *data);
208
209    ///Boundle some options into a group
210
211    /// You can group some option by calling this function repeatedly for each
212    /// option to be grupped with the same groupname.
213    ///\param group The group name
214    ///\param opt The option name
215    ArgParser &optionGroup(const std::string &group,
216                           const std::string &opt);
217
218    ///Make the members of a group exclusive
219
220    ///If you call this function for a group, than at most one of them can be
221    ///given at the same time
222    ArgParser &onlyOneGroup(const std::string &group);
223 
224    ///Create synonym to an option
225
226    ///With this function you can create a sysnonym called \c sys of the
227    ///option \c opt.
228    ArgParser &synonym(const std::string &syn,
229                           const std::string &opt);
230   
231    ///Make a group mandatory
232
233    ///Using this function, at least one of the members of \c group
234    ///must be given.
235    ArgParser &mandatoryGroup(const std::string &group);
236   
237    ///Give help string for non-parsed arguments.
238
239    ///With this function you can give help string for non-parsed arguments.
240    ///the parameter \c name will be printed in the short usage line, while
241    ///\c help gives a more detailed description.
242    ArgParser &other(const std::string &name,
243                     const std::string &help="");
244   
245    ///Non option type arguments.
246
247    ///Gives back a reference to a vector consisting of the program arguments
248    ///not starting with a '-' character.
249    std::vector<std::string> &files() { return _file_args; }
250
251    ///Give back the command name (the 0th argument)
252    const std::string &commandName() { return _command_name; }
253
254    void show(std::ostream &os,Opts::iterator i);
255    void show(std::ostream &os,Groups::iterator i);
256    void showHelp(Opts::iterator i);
257    void showHelp(std::vector<OtherArg>::iterator i);
258    void shortHelp();
259    void showHelp();
260
261    void unknownOpt(std::string arg);
262
263    void requiresValue(std::string arg, OptType t);
264    void checkMandatories();
265   
266    ///\e
267    ArgParser &parse();
268
269    /// Synonym for parse()
270    ArgParser &run()
271    {
272      return parse();
273    }
274   
275    ///Check if an opion has been given to the command.
276    bool given(std::string op)
277    {
278      Opts::iterator i = _opts.find(op);
279      return i!=_opts.end()?i->second.set:false;
280    }
281
282
283    class RefType
284    {
285      ArgParser &_parser;
286      std::string _name;
287    public:
288      RefType(ArgParser &p,const std::string &n) :_parser(p),_name(n) {}
289      operator bool()
290      {
291        Opts::iterator i = _parser._opts.find(_name);
292        if(i==_parser._opts.end()) exit(3); ///\todo throw exception instead
293        else if(i->second.type!=ArgParser::BOOL) exit(3);
294        else return *(i->second.bool_p);
295      }
296      operator std::string()
297      {
298        Opts::iterator i = _parser._opts.find(_name);
299        if(i==_parser._opts.end()) exit(3); ///\todo throw exception instead
300        else if(i->second.type!=ArgParser::STRING) exit(3);
301        else return *(i->second.string_p);
302      }
303      operator double()
304      {
305        Opts::iterator i = _parser._opts.find(_name);
306        if(i==_parser._opts.end()) exit(3); ///\todo throw exception instead
307        else if(i->second.type!=ArgParser::DOUBLE) exit(3);
308        else return *(i->second.double_p);
309      }
310      operator int()
311      {
312        Opts::iterator i = _parser._opts.find(_name);
313        if(i==_parser._opts.end()) exit(3); ///\todo throw exception instead
314        else if(i->second.type!=ArgParser::INTEGER) exit(3);
315        else return *(i->second.int_p);
316      }
317
318    };
319
320    RefType operator[](const std::string &n)
321    {
322      return RefType(*this, n);
323    }
324   
325     
326  };
327}
328
329   
330
331#endif // LEMON_MAIN_PARAMS
Note: See TracBrowser for help on using the repository browser.