gravatar
alpar (Alpar Juttner)
alpar@cs.elte.hu
Port arg_parser from svn -r3438
0 3 3
default
6 files changed with 925 insertions and 2 deletions:
↑ Collapse diff ↑
Ignore white space 6 line context
1
/* -*- C++ -*-
2
 *
3
 * This file is a part of LEMON, a generic C++ optimization library
4
 *
5
 * Copyright (C) 2003-2008
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
///\ingroup demos
20
///\file
21
///\brief Argument parser demo
22
///
23
/// This example shows how can the argument parser used.
24
///
25
/// \include arg_parser.cc
26

	
27
#include <lemon/arg_parser.h>
28

	
29
using namespace lemon;
30
int main(int argc, const char **argv)
31
{
32
  ArgParser ap(argc,argv);
33
  int i;
34
  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
    .synonym("vals","val")
41
    .refOption("name", "a string input", s)
42
    .refOption("f", "a switch", b)
43
    .refOption("nohelp", "", sil)
44
    .refOption("gra","Choise A",g1)
45
    .refOption("grb","Choise B",g2)
46
    .refOption("grc","Choise C",g3)
47
    .optionGroup("gr","gra")
48
    .optionGroup("gr","grb")
49
    .optionGroup("gr","grc")
50
    .mandatoryGroup("gr")
51
    .onlyOneGroup("gr")
52
    .other("infile","The input file")
53
    .other("...");
54
  
55
  ap.parse();
56

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

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

	
65
  switch(ap.files().size()) {
66
  case 0:
67
    std::cout << "  No file argument was given.\n";
68
    break;
69
  case 1:
70
    std::cout << "  1 file argument was given. It is:\n";
71
    break;
72
  default:
73
    std::cout << "  "
74
	      << ap.files().size() << " file arguments were given. They are:\n";
75
  }
76
  for(unsigned int i=0;i<ap.files().size();++i)
77
    std::cout << "    '" << ap.files()[i] << "'\n";
78
  
79
}
Ignore white space 6 line context
1
/* -*- C++ -*-
2
 *
3
 * This file is a part of LEMON, a generic C++ optimization library
4
 *
5
 * Copyright (C) 2003-2008
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
#include <lemon/arg_parser.h>
20

	
21
namespace lemon {
22

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

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

	
35
  }
36

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

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

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

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

	
103
    value = false;
104

	
105
    return *this;
106
  }
107

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

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

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

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

	
162
    ref = false;
163

	
164
    return *this;
165
  }
166

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

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

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

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

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

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

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

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

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

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

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

	
466
    return *this;
467
  }  
468

	
469
}
Ignore white space 6 line context
1
/* -*- C++ -*-
2
 *
3
 * This file is a part of LEMON, a generic C++ optimization library
4
 *
5
 * Copyright (C) 2003-2008
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
#include <lemon/error.h>
30

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

	
37
namespace lemon {
38

	
39
  ///Command line arguments parser
40

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

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

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

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

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

	
109
    ///\e
110
    ArgParser(int argc, const char **argv);
111

	
112
    ~ArgParser();
113

	
114
    ///Add a new integer type option
115

	
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);
123

	
124
    ///Add a new floating type option
125

	
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);
133

	
134
    ///Add a new bool type option
135

	
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);
144

	
145
    ///Add a new string type option
146

	
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);
154
    
155
    ///Bind a function to an option.
156

	
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);
165

	
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.
169

	
170
    ///@{
171

	
172
    ///Add a new integer type option with a storage reference
173

	
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);
181

	
182
    ///Add a new floating type option with a storage reference
183

	
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);
191

	
192
    ///Add a new bool type option with a storage reference
193

	
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);
202

	
203
    ///Add a new string type option with a storage reference
204

	
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);
212
    
213
    ///@}
214

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

	
220
    ///Boundle some options into a group
221

	
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);
228

	
229
    ///Make the members of a group exclusive
230

	
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);
234
  
235
    ///Make a group mandatory
236

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

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

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

	
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="");
257
    
258
    ///Non option type arguments.
259

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

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

	
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);
271
    void shortHelp();
272
    void showHelp();
273

	
274
    void unknownOpt(std::string arg);
275

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

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

	
295

	
296
    ///Magic type for operator[]
297
    
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).
302
    class RefType 
303
    {
304
      ArgParser &_parser;
305
      std::string _name;
306
    public:
307
      ///\e
308
      RefType(ArgParser &p,const std::string &n) :_parser(p),_name(n) {}
309
      ///\e
310
      operator bool() 
311
      {
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);
318
      }
319
      ///\e
320
      operator std::string()
321
      {
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);
328
      }
329
      ///\e
330
      operator double() 
331
      {
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);
340
      }
341
      ///\e
342
      operator int() 
343
      {
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);
350
      }
351

	
352
    };
353

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

	
366
    
367

	
368
#endif // LEMON_MAIN_PARAMS
Ignore white space 6 line context
... ...
@@ -33,2 +33,3 @@
33 33
^objs.*/.*
34
^test/[a-z_]*$
... ...
 No newline at end of file
34
^test/[a-z_]*$
35
^demo/.*_demo$
Show white space 6 line context
... ...
@@ -5,4 +5,8 @@
5 5

	
6
noinst_PROGRAMS +=
6
noinst_PROGRAMS += \
7
        demo/arg_parser_demo
7 8

	
8 9
endif WANT_DEMO
10

	
11
demo_arg_parser_demo_SOURCES = demo/arg_parser_demo.cc
12

	
Ignore white space 6 line context
... ...
@@ -9,2 +9,3 @@
9 9
lemon_libemon_la_SOURCES = \
10
        lemon/arg_parser.cc \
10 11
        lemon/base.cc \
... ...
@@ -17,2 +18,3 @@
17 18
lemon_HEADERS += \
19
        lemon/arg_parser.h \
18 20
        lemon/dim2.h \
0 comments (0 inline)