gravatar
kpeter (Peter Kovacs)
kpeter@inf.elte.hu
Doc improvements related to ArgParser
0 2 0
default
2 files changed with 80 insertions and 47 deletions:
↑ Collapse diff ↑
Ignore white space 50331648 line context
1 1
/* -*- C++ -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library
4 4
 *
5 5
 * Copyright (C) 2003-2008
6 6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
8 8
 *
9 9
 * Permission to use, modify and distribute this software is granted
10 10
 * provided that this copyright notice appears in all copies. For
11 11
 * precise terms see the accompanying LICENSE file.
12 12
 *
13 13
 * This software is provided "AS IS" with no warranty of any kind,
14 14
 * express or implied, and with no claim as to its suitability for any
15 15
 * purpose.
16 16
 *
17 17
 */
18 18

	
19 19
///\ingroup demos
20 20
///\file
21 21
///\brief Argument parser demo
22 22
///
23 23
/// This example shows how the argument parser can be used.
24 24
///
25 25
/// \include arg_parser_demo.cc
26 26

	
27 27
#include <lemon/arg_parser.h>
28 28

	
29 29
using namespace lemon;
30 30
int main(int argc, const char **argv)
31 31
{
32
  ArgParser ap(argc,argv);
32
  // Initialize the argument parser
33
  ArgParser ap(argc, argv);
33 34
  int i;
34 35
  std::string s;
35
  double d;
36
  bool b,sil;
37
  bool g1,g2,g3;
38
  ap.refOption("n", "An integer input.", i, true)
39
    .refOption("val", "A double input.", d)
40
    .doubleOption("val2", "A double input.", d)
41
    .synonym("vals","val")
42
    .refOption("name", "A string input.", s)
43
    .refOption("f", "A switch.", b)
44
    .refOption("nohelp", "", sil)
45
    .refOption("gra","Choice A",g1)
46
    .refOption("grb","Choice B",g2)
47
    .refOption("grc","Choice C",g3)
48
    .optionGroup("gr","gra")
49
    .optionGroup("gr","grb")
50
    .optionGroup("gr","grc")
51
    .mandatoryGroup("gr")
52
    .onlyOneGroup("gr")
53
    .other("infile","The input file.")
36
  double d = 1.0;
37
  bool b, nh;
38
  bool g1, g2, g3;
39

	
40
  // Add a mandatory integer option with storage reference
41
  ap.refOption("n", "An integer input.", i, true);
42
  // Add a double option with storage reference (the default value is 1.0)
43
  ap.refOption("val", "A double input.", d);
44
  // Add a double option without storage reference (the default value is 3.14)
45
  ap.doubleOption("val2", "A double input.", 3.14);
46
  // Set synonym for -val option
47
  ap.synonym("vals", "val");
48
  // Add a string option
49
  ap.refOption("name", "A string input.", s);
50
  // Add bool options
51
  ap.refOption("f", "A switch.", b)
52
    .refOption("nohelp", "", nh)
53
    .refOption("gra", "Choice A", g1)
54
    .refOption("grb", "Choice B", g2)
55
    .refOption("grc", "Choice C", g3);
56
  // Bundle -gr* options into a group
57
  ap.optionGroup("gr", "gra")
58
    .optionGroup("gr", "grb")
59
    .optionGroup("gr", "grc");
60
  // Set the group mandatory
61
  ap.mandatoryGroup("gr");
62
  // Set the options of the group exclusive (only one option can be given)
63
  ap.onlyOneGroup("gr");
64
  // Add non-parsed arguments (e.g. input files)
65
  ap.other("infile", "The input file.")
54 66
    .other("...");
55 67
  
68
  // Perform the parsing process
69
  // (in case of any error it terminates the program)
56 70
  ap.parse();
57 71

	
72
  // Check each option if it has been given and print its value
58 73
  std::cout << "Parameters of '" << ap.commandName() << "':\n";
59 74

	
60
  if(ap.given("n")) std::cout << "  Value of -n: " << i << std::endl;
75
  std::cout << "  Value of -n: " << i << std::endl;
61 76
  if(ap.given("val")) std::cout << "  Value of -val: " << d << std::endl;
77
  if(ap.given("val2")) {
78
    d = ap["val2"];
79
    std::cout << "  Value of -val2: " << d << std::endl;
80
  }
62 81
  if(ap.given("name")) std::cout << "  Value of -name: " << s << std::endl;
63 82
  if(ap.given("f")) std::cout << "  -f is given\n";
64
  if(ap.given("nohelp")) std::cout << "  Value of -nohelp: " << sil << std::endl;
83
  if(ap.given("nohelp")) std::cout << "  Value of -nohelp: " << nh << std::endl;
65 84
  if(ap.given("gra")) std::cout << "  -gra is given\n";
66 85
  if(ap.given("grb")) std::cout << "  -grb is given\n";
67 86
  if(ap.given("grc")) std::cout << "  -grc is given\n";
68
                                     
87
  
69 88
  switch(ap.files().size()) {
70 89
  case 0:
71 90
    std::cout << "  No file argument was given.\n";
72 91
    break;
73 92
  case 1:
74 93
    std::cout << "  1 file argument was given. It is:\n";
75 94
    break;
76 95
  default:
77 96
    std::cout << "  "
78 97
	      << ap.files().size() << " file arguments were given. They are:\n";
79 98
  }
80 99
  for(unsigned int i=0;i<ap.files().size();++i)
81 100
    std::cout << "    '" << ap.files()[i] << "'\n";
82 101
  
102
  return 0;
83 103
}
Ignore white space 50331648 line context
1 1
/* -*- C++ -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library
4 4
 *
5 5
 * Copyright (C) 2003-2008
6 6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
8 8
 *
9 9
 * Permission to use, modify and distribute this software is granted
10 10
 * provided that this copyright notice appears in all copies. For
11 11
 * precise terms see the accompanying LICENSE file.
12 12
 *
13 13
 * This software is provided "AS IS" with no warranty of any kind,
14 14
 * express or implied, and with no claim as to its suitability for any
15 15
 * purpose.
16 16
 *
17 17
 */
18 18

	
19 19
#ifndef LEMON_ARG_PARSER
20 20
#define LEMON_ARG_PARSER
21 21

	
22 22
#include <vector>
23 23
#include <map>
24 24
#include <list>
25 25
#include <string>
26 26
#include <iostream>
27 27
#include <sstream>
28 28
#include <algorithm>
29 29
#include <lemon/assert.h>
30 30

	
31 31
///\ingroup misc
32 32
///\file
33 33
///\brief A tool to parse command line arguments.
34 34

	
35 35
namespace lemon {
36 36

	
37 37
  ///Command line arguments parser
38 38

	
39 39
  ///\ingroup misc
40 40
  ///Command line arguments parser.
41 41
  ///
42 42
  ///For a complete example see the \ref arg_parser_demo.cc demo file.
43 43
  class ArgParser {
44 44
    
45 45
    static void _showHelp(void *p);
46 46
  protected:
47 47
    
48 48
    int _argc;
49 49
    const char **_argv;
50 50
    
51 51
    enum OptType { UNKNOWN=0, BOOL=1, STRING=2, DOUBLE=3, INTEGER=4, FUNC=5 };
52 52
    
53 53
    class ParData {
54 54
    public:
55 55
      union {
56 56
	bool *bool_p;
57 57
	int *int_p;
58 58
	double *double_p;
59 59
	std::string *string_p;
60 60
	struct {
61 61
	  void (*p)(void *);
62 62
	  void *data;
63 63
	} func_p;
64 64
	  
65 65
      };
66 66
      std::string help;
67 67
      bool mandatory;
68 68
      OptType type;
69 69
      bool set;
70 70
      bool ingroup;
71 71
      bool has_syn;
72 72
      bool syn;
73 73
      bool self_delete;
74 74
      ParData() : mandatory(false), type(UNKNOWN), set(false), ingroup(false),
75 75
		  has_syn(false), syn(false), self_delete(false) {}
76 76
    };
77 77

	
78 78
    typedef std::map<std::string,ParData> Opts;
79 79
    Opts _opts;
80 80

	
81 81
    class GroupData 
82 82
    {
83 83
    public:
84 84
      typedef std::list<std::string> Opts;
85 85
      Opts opts;
86 86
      bool only_one;
87 87
      bool mandatory;
88 88
      GroupData() :only_one(false), mandatory(false) {}
89 89
    };
90 90
      
91 91
    typedef std::map<std::string,GroupData> Groups;
92 92
    Groups _groups;
93 93

	
94 94
    struct OtherArg
95 95
    {
96 96
      std::string name;
97 97
      std::string help;
98 98
      OtherArg(std::string n, std::string h) :name(n), help(h) {}
99 99

	
100 100
    };
101 101
      
102 102
    std::vector<OtherArg> _others_help;
103 103
    std::vector<std::string> _file_args;
104 104
    std::string _command_name;
105 105

	
106 106
    
107 107
  private:
108 108
    //Bind a function to an option.
109 109

	
110 110
    //\param name The name of the option. The leading '-' must be omitted.
111 111
    //\param help A help string.
112 112
    //\retval func The function to be called when the option is given. It
113 113
    //  must be of type "void f(void *)"
114 114
    //\param data Data to be passed to \c func
115 115
    ArgParser &funcOption(const std::string &name,
116 116
		    const std::string &help,
117 117
		    void (*func)(void *),void *data);
118 118
    
119 119
  public:
120 120

	
121
    ///\e
121
    ///Constructor
122 122
    ArgParser(int argc, const char **argv);
123 123

	
124 124
    ~ArgParser();
125 125

	
126
    ///\name Options
127
    ///
128

	
129
    ///@{
130

	
126 131
    ///Add a new integer type option
127 132

	
133
    ///Add a new integer type option.
128 134
    ///\param name The name of the option. The leading '-' must be omitted.
129 135
    ///\param help A help string.
130 136
    ///\param value A default value for the option.
131 137
    ///\param obl Indicate if the option is mandatory.
132 138
    ArgParser &intOption(const std::string &name,
133 139
		    const std::string &help,
134 140
		    int value=0, bool obl=false);
135 141

	
136 142
    ///Add a new floating point type option
137 143

	
144
    ///Add a new floating point type option.
138 145
    ///\param name The name of the option. The leading '-' must be omitted.
139 146
    ///\param help A help string.
140 147
    ///\param value A default value for the option.
141 148
    ///\param obl Indicate if the option is mandatory.
142 149
    ArgParser &doubleOption(const std::string &name,
143 150
		      const std::string &help,
144 151
		      double value=0, bool obl=false);
145 152

	
146 153
    ///Add a new bool type option
147 154

	
155
    ///Add a new bool type option.
148 156
    ///\param name The name of the option. The leading '-' must be omitted.
149 157
    ///\param help A help string.
150 158
    ///\param value A default value for the option.
151 159
    ///\param obl Indicate if the option is mandatory.
152 160
    ///\note A mandatory bool obtion is of very little use.
153 161
    ArgParser &boolOption(const std::string &name,
154 162
		      const std::string &help,
155 163
		      bool value=false, bool obl=false);
156 164

	
157 165
    ///Add a new string type option
158 166

	
167
    ///Add a new string type option.
159 168
    ///\param name The name of the option. The leading '-' must be omitted.
160 169
    ///\param help A help string.
161 170
    ///\param value A default value for the option.
162 171
    ///\param obl Indicate if the option is mandatory.
163 172
    ArgParser &stringOption(const std::string &name,
164 173
		      const std::string &help,
165 174
		      std::string value="", bool obl=false);
166 175

	
167
    ///\name Options with external storage
176
    ///Give help string for non-parsed arguments.
177

	
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="");
183
    
184
    ///@}
185

	
186
    ///\name Options with External Storage
168 187
    ///Using this functions, the value of the option will be directly written
169 188
    ///into a variable once the option appears in the command line.
170 189

	
171 190
    ///@{
172 191

	
173 192
    ///Add a new integer type option with a storage reference
174 193

	
194
    ///Add a new integer type option with a storage reference.
175 195
    ///\param name The name of the option. The leading '-' must be omitted.
176 196
    ///\param help A help string.
177 197
    ///\param obl Indicate if the option is mandatory.
178 198
    ///\retval ref The value of the argument will be written to this variable.
179 199
    ArgParser &refOption(const std::string &name,
180 200
		    const std::string &help,
181 201
		    int &ref, bool obl=false);
182 202

	
183 203
    ///Add a new floating type option with a storage reference
184 204

	
205
    ///Add a new floating type option with a storage reference.
185 206
    ///\param name The name of the option. The leading '-' must be omitted.
186 207
    ///\param help A help string.
187 208
    ///\param obl Indicate if the option is mandatory.
188 209
    ///\retval ref The value of the argument will be written to this variable.
189 210
    ArgParser &refOption(const std::string &name,
190 211
		      const std::string &help,
191 212
		      double &ref, bool obl=false);
192 213

	
193 214
    ///Add a new bool type option with a storage reference
194 215

	
216
    ///Add a new bool type option with a storage reference.
195 217
    ///\param name The name of the option. The leading '-' must be omitted.
196 218
    ///\param help A help string.
197 219
    ///\param obl Indicate if the option is mandatory.
198 220
    ///\retval ref The value of the argument will be written to this variable.
199 221
    ///\note A mandatory bool obtion is of very little use.
200 222
    ArgParser &refOption(const std::string &name,
201 223
		      const std::string &help,
202 224
		      bool &ref, bool obl=false);
203 225

	
204 226
    ///Add a new string type option with a storage reference
205 227

	
228
    ///Add a new string type option with a storage reference.
206 229
    ///\param name The name of the option. The leading '-' must be omitted.
207 230
    ///\param help A help string.
208 231
    ///\param obl Indicate if the option is mandatory.
209 232
    ///\retval ref The value of the argument will be written to this variable.
210 233
    ArgParser &refOption(const std::string &name,
211 234
		      const std::string &help,
212 235
		      std::string &ref, bool obl=false);
213 236
    
214 237
    ///@}
215 238

	
216 239
    ///\name Option Groups and Synonyms
217 240
    ///
218 241
    
219 242
    ///@{
220 243

	
221
    ///Boundle some options into a group
244
    ///Bundle some options into a group
222 245

	
223 246
    /// You can group some option by calling this function repeatedly for each
224 247
    /// option to be grouped with the same groupname.
225 248
    ///\param group The group name.
226 249
    ///\param opt The option name.
227 250
    ArgParser &optionGroup(const std::string &group,
228 251
			   const std::string &opt);
229 252

	
230 253
    ///Make the members of a group exclusive
231 254

	
232 255
    ///If you call this function for a group, than at most one of them can be
233
    ///given at the same time
256
    ///given at the same time.
234 257
    ArgParser &onlyOneGroup(const std::string &group);
235 258
  
236 259
    ///Make a group mandatory
237 260

	
238 261
    ///Using this function, at least one of the members of \c group
239 262
    ///must be given.
240 263
    ArgParser &mandatoryGroup(const std::string &group);
241 264
    
242 265
    ///Create synonym to an option
243 266

	
244 267
    ///With this function you can create a synonym \c syn of the
245 268
    ///option \c opt.
246 269
    ArgParser &synonym(const std::string &syn,
247 270
			   const std::string &opt);
248 271
    
249 272
    ///@}
250 273

	
251
    ///Give help string for non-parsed arguments.
252

	
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="");
258
    
259
    ///Give back the non-option type arguments.
260

	
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; }
264

	
265
    ///Give back the command name (the 0th argument)
266
    const std::string &commandName() { return _command_name; }
267

	
268 274
    void show(std::ostream &os,Opts::iterator i);
269 275
    void show(std::ostream &os,Groups::iterator i);
270 276
    void showHelp(Opts::iterator i);
271 277
    void showHelp(std::vector<OtherArg>::iterator i);
272 278
    void shortHelp();
273 279
    void showHelp();
274 280

	
275 281
    void unknownOpt(std::string arg);
276 282

	
277 283
    void requiresValue(std::string arg, OptType t);
278 284
    void checkMandatories();
279 285
    
280 286
    ///Start the parsing process
281 287
    ArgParser &parse();
282 288

	
283 289
    /// Synonym for parse()
284 290
    ArgParser &run() 
285 291
    {
286 292
      return parse();
287 293
    }
288 294
    
295
    ///Give back the command name (the 0th argument)
296
    const std::string &commandName() { return _command_name; }
297

	
289 298
    ///Check if an opion has been given to the command.
290 299
    bool given(std::string op) 
291 300
    {
292 301
      Opts::iterator i = _opts.find(op);
293 302
      return i!=_opts.end()?i->second.set:false;
294 303
    }
295 304

	
296 305

	
297 306
    ///Magic type for operator[]
298 307
    
299 308
    ///This is the type of the return value of ArgParser::operator[]().
300 309
    ///It automatically converts to \c int, \c double, \c bool or
301 310
    ///\c std::string if the type of the option matches, otherwise it
302 311
    ///throws an exception (i.e. it performs runtime type checking).
303 312
    class RefType 
304 313
    {
305 314
      ArgParser &_parser;
306 315
      std::string _name;
307 316
    public:
308 317
      ///\e
309 318
      RefType(ArgParser &p,const std::string &n) :_parser(p),_name(n) {}
310 319
      ///\e
311 320
      operator bool() 
312 321
      {
313 322
	Opts::iterator i = _parser._opts.find(_name);
314 323
	LEMON_ASSERT(i!=_parser._opts.end(),
315 324
		     std::string()+"Unkown option: '"+_name+"'");
316 325
	LEMON_ASSERT(i->second.type==ArgParser::BOOL,
317 326
		     std::string()+"'"+_name+"' is a bool option");
318 327
	return *(i->second.bool_p);
319 328
      }
320 329
      ///\e
321 330
      operator std::string()
322 331
      {
323 332
	Opts::iterator i = _parser._opts.find(_name);
324 333
	LEMON_ASSERT(i!=_parser._opts.end(),
325 334
		     std::string()+"Unkown option: '"+_name+"'");
326 335
	LEMON_ASSERT(i->second.type==ArgParser::STRING,
327 336
		     std::string()+"'"+_name+"' is a string option");
328 337
	return *(i->second.string_p);
329 338
      }
330 339
      ///\e
331 340
      operator double() 
332 341
      {
333 342
	Opts::iterator i = _parser._opts.find(_name);
334 343
	LEMON_ASSERT(i!=_parser._opts.end(),
335 344
		     std::string()+"Unkown option: '"+_name+"'");
336 345
	LEMON_ASSERT(i->second.type==ArgParser::DOUBLE ||
337 346
		     i->second.type==ArgParser::INTEGER,
338 347
		     std::string()+"'"+_name+"' is a floating point option");
339 348
	return i->second.type==ArgParser::DOUBLE ?
340 349
	  *(i->second.double_p) : *(i->second.int_p);
341 350
      }
342 351
      ///\e
343 352
      operator int() 
344 353
      {
345 354
	Opts::iterator i = _parser._opts.find(_name);
346 355
	LEMON_ASSERT(i!=_parser._opts.end(),
347 356
		     std::string()+"Unkown option: '"+_name+"'");
348 357
	LEMON_ASSERT(i->second.type==ArgParser::INTEGER,
349 358
		     std::string()+"'"+_name+"' is an integer option");
350 359
	return *(i->second.int_p);
351 360
      }
352 361

	
353 362
    };
354 363

	
355 364
    ///Give back the value of an option
356 365
    
357 366
    ///Give back the value of an option.
358 367
    ///\sa RefType
359 368
    RefType operator[](const std::string &n)
360 369
    {
361 370
      return RefType(*this, n);
362 371
    }    
372

	
373
    ///Give back the non-option type arguments.
374

	
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; }
363 378
 
364 379
  };
365 380
}
366 381

	
367
    
368

	
369
#endif // LEMON_MAIN_PARAMS
382
#endif // LEMON_ARG_PARSER
0 comments (0 inline)