gravatar
kpeter (Peter Kovacs)
kpeter@inf.elte.hu
Minor improvements in arg_parser files
0 3 0
default
3 files changed with 29 insertions and 31 deletions:
↑ Collapse diff ↑
Ignore white space 6 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
/// This example shows how can the argument parser used.
23
/// This example shows how the argument parser can be used.
24 24
///
25
/// \include arg_parser.cc
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 32
  ArgParser ap(argc,argv);
33 33
  int i;
34 34
  std::string s;
35 35
  double d;
36 36
  bool b,sil;
37 37
  bool g1,g2,g3;
38
  ap.refOption("n", "an integer input", i, true)
39
    .refOption("val", "a double input", d)
38
  ap.refOption("n", "An integer input.", i, true)
39
    .refOption("val", "A double input.", d)
40 40
    .synonym("vals","val")
41
    .refOption("name", "a string input", s)
42
    .refOption("f", "a switch", b)
41
    .refOption("name", "A string input.", s)
42
    .refOption("f", "A switch.", b)
43 43
    .refOption("nohelp", "", sil)
44
    .refOption("gra","Choise A",g1)
45
    .refOption("grb","Choise B",g2)
46
    .refOption("grc","Choise C",g3)
44
    .refOption("gra","Choice A",g1)
45
    .refOption("grb","Choice B",g2)
46
    .refOption("grc","Choice C",g3)
47 47
    .optionGroup("gr","gra")
48 48
    .optionGroup("gr","grb")
49 49
    .optionGroup("gr","grc")
50 50
    .mandatoryGroup("gr")
51 51
    .onlyOneGroup("gr")
52
    .other("infile","The input file")
52
    .other("infile","The input file.")
53 53
    .other("...");
54 54
  
55 55
  ap.parse();
56 56

	
57 57
  std::cout << "Parameters of '" << ap.commandName() << "':\n";
58 58

	
59 59
  if(ap.given("n")) std::cout << "  Value of -n: " << i << std::endl;
60 60
  if(ap.given("val")) std::cout << "  Value of -val: " << d << std::endl;
61 61
  if(ap.given("name")) std::cout << "  Value of -name: " << s << std::endl;
62 62
  if(ap.given("f")) std::cout << "  -f is given\n";
63 63
  if(ap.given("nohelp")) std::cout << "  Value of -nohelp: " << sil << std::endl;
64

	
64
  if(ap.given("gra")) std::cout << "  -gra is given\n";
65
  if(ap.given("grb")) std::cout << "  -grb is given\n";
66
  if(ap.given("grc")) std::cout << "  -grc is given\n";
67
                                     
65 68
  switch(ap.files().size()) {
66 69
  case 0:
67 70
    std::cout << "  No file argument was given.\n";
68 71
    break;
69 72
  case 1:
70 73
    std::cout << "  1 file argument was given. It is:\n";
71 74
    break;
72 75
  default:
73 76
    std::cout << "  "
74 77
	      << ap.files().size() << " file arguments were given. They are:\n";
75 78
  }
76 79
  for(unsigned int i=0;i<ap.files().size();++i)
77 80
    std::cout << "    '" << ap.files()[i] << "'\n";
78 81
  
79 82
}
Ignore white space 6 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
#include <lemon/arg_parser.h>
20 20

	
21 21
namespace lemon {
22 22

	
23 23
  void ArgParser::_showHelp(void *p)
24 24
  {
25 25
    (static_cast<ArgParser*>(p))->showHelp();
26 26
    exit(1);
27 27
  }
28 28

	
29 29
  ArgParser::ArgParser(int argc, const char **argv) :_argc(argc), _argv(argv),
30 30
                                                     _command_name(argv[0]) {
31 31
    funcOption("-help","Print a short help message",_showHelp,this);
32 32
    synonym("help","-help");
33 33
    synonym("h","-help");
34 34

	
35 35
  }
36 36

	
37 37
  ArgParser::~ArgParser()
38 38
  {
39 39
    for(Opts::iterator i=_opts.begin();i!=_opts.end();++i)
40 40
      if(i->second.self_delete)
41 41
	switch(i->second.type) {
42 42
	case BOOL:
43 43
	  delete i->second.bool_p;
44 44
	  break;
45 45
	case STRING:
46 46
	  delete i->second.string_p;
47 47
	  break;
48 48
	case DOUBLE:
49 49
	  delete i->second.double_p;
50 50
	  break;
51 51
	case INTEGER:
52 52
	  delete i->second.int_p;
53 53
	  break;
54 54
	case UNKNOWN:
55 55
	  break;
56 56
	case FUNC:
57 57
	  break;
58 58
	}
59 59
  }
60 60
  
61 61

	
62 62
  ArgParser &ArgParser::intOption(const std::string &name,
63 63
			       const std::string &help,
64 64
			       int value, bool obl)
65 65
  {
66 66
    ParData p;
67 67
    p.int_p=new int(value);
68 68
    p.self_delete=true;
69 69
    p.help=help;
70 70
    p.type=INTEGER;
71 71
    p.mandatory=obl;
72
    p.self_delete=true;
73 72
    _opts[name]=p;
74 73
    return *this;
75 74
  }
76 75

	
77 76
  ArgParser &ArgParser::doubleOption(const std::string &name,
78 77
			       const std::string &help,
79 78
			       double value, bool obl)
80 79
  {
81 80
    ParData p;
82 81
    p.double_p=new double(value);
83 82
    p.self_delete=true;
84 83
    p.help=help;
85 84
    p.type=DOUBLE;
86 85
    p.mandatory=obl;
87 86
    _opts[name]=p;
88 87
    return *this;
89 88
  }
90 89

	
91 90
  ArgParser &ArgParser::boolOption(const std::string &name,
92 91
			       const std::string &help,
93 92
			       bool value, bool obl)
94 93
  {
95 94
    ParData p;
96 95
    p.bool_p=new bool(value);
97 96
    p.self_delete=true;
98 97
    p.help=help;
99 98
    p.type=BOOL;
100 99
    p.mandatory=obl;
101 100
    _opts[name]=p;
102

	
103
    value = false;
104

	
105 101
    return *this;
106 102
  }
107 103

	
108 104
  ArgParser &ArgParser::stringOption(const std::string &name,
109 105
			       const std::string &help,
110 106
			       std::string value, bool obl)
111 107
  {
112 108
    ParData p;
113 109
    p.string_p=new std::string(value);
114 110
    p.self_delete=true;
115 111
    p.help=help;
116 112
    p.type=STRING;
117 113
    p.mandatory=obl;
118 114
    _opts[name]=p;
119 115
    return *this;
120 116
  }
121 117

	
122 118
  ArgParser &ArgParser::refOption(const std::string &name,
123 119
			       const std::string &help,
124 120
			       int &ref, bool obl)
125 121
  {
126 122
    ParData p;
127 123
    p.int_p=&ref;
128 124
    p.self_delete=false;
129 125
    p.help=help;
130 126
    p.type=INTEGER;
131 127
    p.mandatory=obl;
132 128
    _opts[name]=p;
133 129
    return *this;
134 130
  }
135 131

	
136 132
  ArgParser &ArgParser::refOption(const std::string &name,
137 133
                                  const std::string &help,
138 134
                                  double &ref, bool obl)
139 135
  {
140 136
    ParData p;
141 137
    p.double_p=&ref;
142 138
    p.self_delete=false;
143 139
    p.help=help;
144 140
    p.type=DOUBLE;
145 141
    p.mandatory=obl;
146 142
    _opts[name]=p;
147 143
    return *this;
148 144
  }
149 145

	
150 146
  ArgParser &ArgParser::refOption(const std::string &name,
151 147
                                  const std::string &help,
152 148
                                  bool &ref, bool obl)
153 149
  {
154 150
    ParData p;
155 151
    p.bool_p=&ref;
156 152
    p.self_delete=false;
157 153
    p.help=help;
158 154
    p.type=BOOL;
159 155
    p.mandatory=obl;
160 156
    _opts[name]=p;
161 157

	
162 158
    ref = false;
163 159

	
164 160
    return *this;
165 161
  }
166 162

	
167 163
  ArgParser &ArgParser::refOption(const std::string &name,
168 164
			       const std::string &help,
169 165
			       std::string &ref, bool obl)
170 166
  {
171 167
    ParData p;
172 168
    p.string_p=&ref;
173 169
    p.self_delete=false;
174 170
    p.help=help;
175 171
    p.type=STRING;
176 172
    p.mandatory=obl;
177 173
    _opts[name]=p;
178 174
    return *this;
179 175
  }
180 176

	
181 177
  ArgParser &ArgParser::funcOption(const std::string &name,
182 178
			       const std::string &help,
183 179
			       void (*func)(void *),void *data)
184 180
  {
185 181
    ParData p;
186 182
    p.func_p.p=func;
187 183
    p.func_p.data=data;
188 184
    p.self_delete=false;
189 185
    p.help=help;
190 186
    p.type=FUNC;
191 187
    p.mandatory=false;
192 188
    _opts[name]=p;
193 189
    return *this;
194 190
  }
195 191

	
196 192
  ArgParser &ArgParser::optionGroup(const std::string &group,
197 193
				    const std::string &opt)
198 194
  {
199 195
    Opts::iterator i = _opts.find(opt);
200 196
    LEMON_ASSERT(i!=_opts.end(), "Unknown option: '"+opt+"'");
201 197
    LEMON_ASSERT(!(i->second.ingroup), 
202 198
                 "Option already in option group: '"+opt+"'");
203 199
    GroupData &g=_groups[group];
204 200
    g.opts.push_back(opt);
205 201
    i->second.ingroup=true;
206 202
    return *this;
207 203
  }
208 204

	
209 205
  ArgParser &ArgParser::onlyOneGroup(const std::string &group)
210 206
  {
211 207
    GroupData &g=_groups[group];
212 208
    g.only_one=true;
213 209
    return *this;
214 210
  }
215 211

	
216 212
  ArgParser &ArgParser::synonym(const std::string &syn,
217 213
				const std::string &opt)
218 214
  {
219 215
    Opts::iterator o = _opts.find(opt);
220 216
    Opts::iterator s = _opts.find(syn);
221 217
    LEMON_ASSERT(o!=_opts.end(), "Unknown option: '"+opt+"'");
222 218
    LEMON_ASSERT(s==_opts.end(), "Option already used: '"+syn+"'");
223 219
    ParData p;
224 220
    p.help=opt;
225 221
    p.mandatory=false;
226 222
    p.syn=true;
227 223
    _opts[syn]=p;
228 224
    o->second.has_syn=true;
229 225
    return *this;
230 226
  }
231 227

	
232 228
  ArgParser &ArgParser::mandatoryGroup(const std::string &group)
233 229
  {
234 230
    GroupData &g=_groups[group];
235 231
    g.mandatory=true;
236 232
    return *this;
237 233
  }
238 234

	
239 235
  ArgParser &ArgParser::other(const std::string &name,
240 236
			      const std::string &help)
241 237
  {
242 238
    _others_help.push_back(OtherArg(name,help));
243 239
    return *this;
244 240
  }
245 241

	
246 242
  void ArgParser::show(std::ostream &os,Opts::iterator i)
247 243
  {
248 244
    os << "-" << i->first;
249 245
    if(i->second.has_syn)
250 246
      for(Opts::iterator j=_opts.begin();j!=_opts.end();++j)
251 247
	if(j->second.syn&&j->second.help==i->first)
252 248
	  os << "|-" << j->first;
253 249
    switch(i->second.type) {
254 250
    case STRING:
255 251
      os << " str";
256 252
      break;
257 253
    case INTEGER:
258 254
      os << " int";
259 255
      break;
260 256
    case DOUBLE:
261 257
      os << " num";
262 258
      break;
263 259
    default:
264 260
      break;
265 261
    }
266 262
  }
267 263

	
268 264
  void ArgParser::show(std::ostream &os,Groups::iterator i)
269 265
  {
270 266
    GroupData::Opts::iterator o=i->second.opts.begin();
271 267
    while(o!=i->second.opts.end()) {
272 268
      show(os,_opts.find(*o));
273 269
      ++o;
274 270
      if(o!=i->second.opts.end()) os<<'|';
275 271
    }
276 272
  }
277 273
    
278 274
  void ArgParser::showHelp(Opts::iterator i)
279 275
  {
280 276
    if(i->second.help.size()==0||i->second.syn) return;
281 277
    std::cerr << "  ";
282 278
    show(std::cerr,i);
283 279
    std::cerr << std::endl;
284 280
    std::cerr << "     " << i->second.help << std::endl;
285 281
  }
286 282
  void ArgParser::showHelp(std::vector<ArgParser::OtherArg>::iterator i)
287 283
  {
288 284
    if(i->help.size()==0) return;
289 285
    std::cerr << "  " << i->name << std::endl
290 286
	      << "     " << i->help << std::endl;
291 287
  }
292 288
    
293 289
  void ArgParser::shortHelp()
294 290
  {
295 291
    const unsigned int LINE_LEN=77;
296 292
    const std::string indent("    ");
297 293
    std::cerr << "Usage:\n  " << _command_name;
298 294
    int pos=_command_name.size()+2;
299 295
    for(Groups::iterator g=_groups.begin();g!=_groups.end();++g) {
300 296
      std::ostringstream cstr;
301 297
      cstr << ' ';
302 298
      if(!g->second.mandatory) cstr << '[';
303 299
      show(cstr,g);
304 300
      if(!g->second.mandatory) cstr << ']';
305 301
      if(pos+cstr.str().size()>LINE_LEN) {
306 302
	std::cerr << std::endl << indent;
307 303
	pos=indent.size();
308 304
      }
309 305
      std::cerr << cstr.str();
310 306
      pos+=cstr.str().size();
311 307
    }
312 308
    for(Opts::iterator i=_opts.begin();i!=_opts.end();++i)
313 309
      if(!i->second.ingroup&&!i->second.syn) {
314 310
	std::ostringstream cstr;
315 311
	cstr << ' ';
316 312
	if(!i->second.mandatory) cstr << '[';
317 313
	show(cstr,i);
318 314
	if(!i->second.mandatory) cstr << ']';
319 315
	if(pos+cstr.str().size()>LINE_LEN) {
320 316
	  std::cerr << std::endl << indent;
321 317
	  pos=indent.size();
322 318
	}
323 319
	std::cerr << cstr.str();
324 320
	pos+=cstr.str().size();
325 321
      }
326 322
    for(std::vector<OtherArg>::iterator i=_others_help.begin();
327 323
	i!=_others_help.end();++i)
328 324
      {
329 325
	std::ostringstream cstr;
330 326
	cstr << ' ' << i->name;
331 327
      
332 328
	if(pos+cstr.str().size()>LINE_LEN) {
333 329
	  std::cerr << std::endl << indent;
334 330
	  pos=indent.size();
335 331
	}
336 332
	std::cerr << cstr.str();
337 333
	pos+=cstr.str().size();
338 334
      }
339 335
    std::cerr << std::endl;
340 336
  }
341 337
    
342 338
  void ArgParser::showHelp()
343 339
  {
344 340
    shortHelp();
345 341
    std::cerr << "Where:\n";
346 342
    for(std::vector<OtherArg>::iterator i=_others_help.begin();
347 343
	i!=_others_help.end();++i) showHelp(i);
348 344
    for(Opts::iterator i=_opts.begin();i!=_opts.end();++i) showHelp(i);
349 345
    exit(1);
350 346
  }
351 347
    
352 348
      
353 349
  void ArgParser::unknownOpt(std::string arg) 
354 350
  {
355 351
    std::cerr << "\nUnknown option: " << arg << "\n";
356 352
    std::cerr << "\nType '" << _command_name <<
357 353
      " --help' to obtain a short summary on the usage.\n\n";
358 354
    exit(1);
359 355
  }
360 356
    
361 357
  void ArgParser::requiresValue(std::string arg, OptType t) 
362 358
  {
363 359
    std::cerr << "Argument '" << arg << "' requires a";
364 360
    switch(t) {
365 361
    case STRING:
366 362
      std::cerr << " string";
367 363
      break;
368 364
    case INTEGER:
369 365
      std::cerr << "n integer";
370 366
      break;
371 367
    case DOUBLE:
372 368
      std::cerr << " floating point";
373 369
      break;
374 370
    default:
375 371
      break;
376 372
    }
377 373
    std::cerr << " value\n\n";
378 374
    showHelp();
379 375
  }
380 376
    
381 377

	
382 378
  void ArgParser::checkMandatories()
383 379
  {
384 380
    bool ok=true;
385 381
    for(Opts::iterator i=_opts.begin();i!=_opts.end();++i)
386 382
      if(i->second.mandatory&&!i->second.set) 
387 383
	{
388 384
	  if(ok)
389 385
	    std::cerr << _command_name 
390 386
		      << ": The following mandatory arguments are missing.\n";
391 387
	  ok=false;
392 388
	  showHelp(i);
393 389
	}
394 390
    for(Groups::iterator i=_groups.begin();i!=_groups.end();++i)
395 391
      if(i->second.mandatory||i->second.only_one)
396 392
	{
397 393
	  int set=0;
398 394
	  for(GroupData::Opts::iterator o=i->second.opts.begin();
399 395
	      o!=i->second.opts.end();++o)
400 396
	    if(_opts.find(*o)->second.set) ++set;
401 397
	  if(i->second.mandatory&&!set) {
402 398
	    std::cerr << _command_name 
403 399
		      << ": At least one of the following arguments is mandatory.\n";
404 400
	    ok=false;
405 401
	    for(GroupData::Opts::iterator o=i->second.opts.begin();
406 402
		o!=i->second.opts.end();++o)
407 403
	      showHelp(_opts.find(*o));
408 404
	  }
409 405
	  if(i->second.only_one&&set>1) {
410 406
	    std::cerr << _command_name 
411 407
		      << ": At most one of the following arguments can be given.\n";
412 408
	    ok=false;
413 409
	    for(GroupData::Opts::iterator o=i->second.opts.begin();
414 410
		o!=i->second.opts.end();++o)
415 411
	      showHelp(_opts.find(*o));
416 412
	  }
417 413
	}
418 414
    if(!ok) {
419 415
      std::cerr << "\nType '" << _command_name <<
420 416
	" --help' to obtain a short summary on the usage.\n\n";
421 417
      exit(1);
422 418
    }
423 419
  }
424 420

	
425 421
  ArgParser &ArgParser::parse()
426 422
  {
427 423
    for(int ar=1; ar<_argc; ++ar) {
428 424
      std::string arg(_argv[ar]);
429 425
      if (arg[0] != '-' || arg.size() == 1) {
430 426
	_file_args.push_back(arg);
431 427
      }
432 428
      else {
433 429
	Opts::iterator i = _opts.find(arg.substr(1));
434 430
	if(i==_opts.end()) unknownOpt(arg);
435 431
	else {
436 432
	  if(i->second.syn) i=_opts.find(i->second.help);
437 433
	  ParData &p(i->second);
438 434
	  if (p.type==BOOL) *p.bool_p=true;
439 435
	  else if (p.type==FUNC) p.func_p.p(p.func_p.data);
440 436
	  else if(++ar==_argc) requiresValue(arg, p.type);
441 437
	  else {
442 438
	    std::string val(_argv[ar]);
443 439
	    std::istringstream vals(val);
444 440
	    switch(p.type) {
445 441
	    case STRING:
446 442
	      *p.string_p=val;
447 443
	      break;
448 444
	    case INTEGER:
449 445
	      vals >> *p.int_p;
450 446
	      break;
451 447
	    case DOUBLE:
452 448
	      vals >> *p.double_p;
453 449
	      break;
454 450
	    default:
455 451
	      break;
456 452
	    }
457 453
	    if(p.type!=STRING&&(!vals||!vals.eof()))
458 454
	      requiresValue(arg, p.type);
459 455
	  }
460 456
	  p.set = true;
461 457
	}
462 458
      }
463 459
    }
464 460
    checkMandatories();
465 461

	
466 462
    return *this;
467 463
  }  
468 464

	
469 465
}
Ignore white space 6144 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/error.h>
30 30

	
31 31
///\ingroup misc
32 32
///\file
33
///\brief A tools to parse command line arguments.
34
///
35
///\author Alpar Juttner
33
///\brief A tool to parse command line arguments.
36 34

	
37 35
namespace lemon {
38 36

	
39 37
  ///Command line arguments parser
40 38

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

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

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

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

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

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

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

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

	
125 124
    ~ArgParser();
126 125

	
127 126
    ///Add a new integer type option
128 127

	
129 128
    ///\param name The name of the option. The leading '-' must be omitted.
130 129
    ///\param help A help string.
131 130
    ///\retval value The value of the argument will be written to this variable.
132 131
    ///\param obl Indicate if the option is mandatory.
133 132
    ArgParser &intOption(const std::string &name,
134 133
		    const std::string &help,
135 134
		    int value=0, bool obl=false);
136 135

	
137 136
    ///Add a new floating point type option
138 137

	
139 138
    ///\param name The name of the option. The leading '-' must be omitted.
140 139
    ///\param help A help string.
141 140
    ///\retval value The value of the argument will be written to this variable.
142 141
    ///\param obl Indicate if the option is mandatory.
143 142
    ArgParser &doubleOption(const std::string &name,
144 143
		      const std::string &help,
145 144
		      double value=0, bool obl=false);
146 145

	
147 146
    ///Add a new bool type option
148 147

	
149 148
    ///\param name The name of the option. The leading '-' must be omitted.
150 149
    ///\param help A help string.
151 150
    ///\retval value The value of the argument will be written to this variable.
152 151
    ///\param obl Indicate if the option is mandatory.
153 152
    ////\note A mandatory bool obtion is of very little use.)
154 153
    ArgParser &boolOption(const std::string &name,
155 154
		      const std::string &help,
156 155
		      bool value=false, bool obl=false);
157 156

	
158 157
    ///Add a new string type option
159 158

	
160 159
    ///\param name The name of the option. The leading '-' must be omitted.
161 160
    ///\param help A help string.
162 161
    ///\retval value The value of the argument will be written to this variable.
163 162
    ///\param obl Indicate if the option is mandatory.
164 163
    ArgParser &stringOption(const std::string &name,
165 164
		      const std::string &help,
166 165
		      std::string value="", bool obl=false);
167 166

	
168
    ///\name Options with an external strorage.
167
    ///\name Options with external storage
169 168
    ///Using this functions, the value of the option will be directly written
170 169
    ///into a variable once the option appears in the command line.
171 170

	
172 171
    ///@{
173 172

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

	
176 175
    ///\param name The name of the option. The leading '-' must be omitted.
177 176
    ///\param help A help string.
178 177
    ///\retval ref The value of the argument will be written to this variable.
179 178
    ///\param obl Indicate if the option is mandatory.
180 179
    ArgParser &refOption(const std::string &name,
181 180
		    const std::string &help,
182 181
		    int &ref, bool obl=false);
183 182

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

	
186 185
    ///\param name The name of the option. The leading '-' must be omitted.
187 186
    ///\param help A help string.
188 187
    ///\retval ref The value of the argument will be written to this variable.
189 188
    ///\param obl Indicate if the option is mandatory.
190 189
    ArgParser &refOption(const std::string &name,
191 190
		      const std::string &help,
192 191
		      double &ref, bool obl=false);
193 192

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

	
196 195
    ///\param name The name of the option. The leading '-' must be omitted.
197 196
    ///\param help A help string.
198 197
    ///\retval ref The value of the argument will be written to this variable.
199 198
    ///\param obl Indicate if the option is mandatory.
200 199
    ////\note A mandatory bool obtion is of very little use.)
201 200
    ArgParser &refOption(const std::string &name,
202 201
		      const std::string &help,
203 202
		      bool &ref, bool obl=false);
204 203

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

	
207 206
    ///\param name The name of the option. The leading '-' must be omitted.
208 207
    ///\param help A help string.
209 208
    ///\retval ref The value of the argument will be written to this variable.
210 209
    ///\param obl Indicate if the option is mandatory.
211 210
    ArgParser &refOption(const std::string &name,
212 211
		      const std::string &help,
213 212
		      std::string &ref, bool obl=false);
214 213
    
215 214
    ///@}
216 215

	
217 216
    ///\name Option Groups and Synonyms
218 217
    ///
219 218
    
220 219
    ///@{
221 220

	
222 221
    ///Boundle some options into a group
223 222

	
224 223
    /// 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
224
    /// option to be grouped with the same groupname.
225
    ///\param group The group name.
226
    ///\param opt The option name.
228 227
    ArgParser &optionGroup(const std::string &group,
229 228
			   const std::string &opt);
230 229

	
231 230
    ///Make the members of a group exclusive
232 231

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

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

	
245
    ///With this function you can create a sysnonym called \c sys of the
244
    ///With this function you can create a synonym \c syn of the
246 245
    ///option \c opt.
247 246
    ArgParser &synonym(const std::string &syn,
248 247
			   const std::string &opt);
249 248
    
250 249
    ///@}
251 250

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

	
254 253
    ///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
254
    ///The parameter \c name will be printed in the short usage line, while
256 255
    ///\c help gives a more detailed description.
257 256
    ArgParser &other(const std::string &name,
258 257
		     const std::string &help="");
259 258
    
260
    ///Non option type arguments.
259
    ///Give back the non-option type arguments.
261 260

	
262
    ///Gives back a reference to a vector consisting of the program arguments
261
    ///Give back a reference to a vector consisting of the program arguments
263 262
    ///not starting with a '-' character.
264 263
    std::vector<std::string> &files() { return _file_args; }
265 264

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

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

	
276 275
    void unknownOpt(std::string arg);
277 276

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

	
284 283
    /// Synonym for parse()
285 284
    ArgParser &run() 
286 285
    {
287 286
      return parse();
288 287
    }
289 288
    
290 289
    ///Check if an opion has been given to the command.
291 290
    bool given(std::string op) 
292 291
    {
293 292
      Opts::iterator i = _opts.find(op);
294 293
      return i!=_opts.end()?i->second.set:false;
295 294
    }
296 295

	
297 296

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

	
354 353
    };
355 354

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

	
368 367
    
369 368

	
370 369
#endif // LEMON_MAIN_PARAMS
0 comments (0 inline)