gravatar
alpar (Alpar Juttner)
alpar@cs.elte.hu
Merge
0 3 3
merge default
1 file 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 the argument parser can be used.
24
///
25
/// \include arg_parser_demo.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","Choice A",g1)
45
    .refOption("grb","Choice B",g2)
46
    .refOption("grc","Choice 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
  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
                                     
68
  switch(ap.files().size()) {
69
  case 0:
70
    std::cout << "  No file argument was given.\n";
71
    break;
72
  case 1:
73
    std::cout << "  1 file argument was given. It is:\n";
74
    break;
75
  default:
76
    std::cout << "  "
77
	      << ap.files().size() << " file arguments were given. They are:\n";
78
  }
79
  for(unsigned int i=0;i<ap.files().size();++i)
80
    std::cout << "    '" << ap.files()[i] << "'\n";
81
  
82
}
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
    _opts[name]=p;
73
    return *this;
74
  }
75

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

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

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

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

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

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

	
158
    ref = false;
159

	
160
    return *this;
161
  }
162

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

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

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

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

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

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

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

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

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

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

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

	
462
    return *this;
463
  }  
464

	
465
}
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 tool to parse command line arguments.
34

	
35
namespace lemon {
36

	
37
  ///Command line arguments parser
38

	
39
  ///\ingroup misc
40
  ///Command line arguments parser.
41
  ///
42
  ///For a complete example see the \ref arg_parser_demo.cc demo file.
43
  class ArgParser {
44
    
45
    static void _showHelp(void *p);
46
  protected:
47
    
48
    int _argc;
49
    const 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
    
107
  private:
108
    //Bind a function to an option.
109

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

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

	
124
    ~ArgParser();
125

	
126
    ///Add a new integer type option
127

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

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

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

	
146
    ///Add a new bool type option
147

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

	
157
    ///Add a new string 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 &stringOption(const std::string &name,
164
		      const std::string &help,
165
		      std::string value="", bool obl=false);
166

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

	
171
    ///@{
172

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

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

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

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

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

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

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

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

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

	
221
    ///Boundle some options into a group
222

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

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

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

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

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

	
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
    void show(std::ostream &os,Opts::iterator i);
269
    void show(std::ostream &os,Groups::iterator i);
270
    void showHelp(Opts::iterator i);
271
    void showHelp(std::vector<OtherArg>::iterator i);
272
    void shortHelp();
273
    void showHelp();
274

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

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

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

	
296

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

	
353
    };
354

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

	
367
    
368

	
369
#endif // LEMON_MAIN_PARAMS
Ignore white space 6 line context
... ...
@@ -28,7 +28,8 @@
28 28

	
29 29
syntax: regexp
30 30
^doc/html/.*
31 31
^autom4te.cache/.*
32 32
^build-aux/.*
33 33
^objs.*/.*
34
^test/[a-z_]*$
... ...
 No newline at end of file
34
^test/[a-z_]*$
35
^demo/.*_demo$
Ignore white space 12 line context
1 1
EXTRA_DIST += \
2 2
	demo/Makefile
3 3

	
4 4
if WANT_DEMO
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
... ...
@@ -4,20 +4,22 @@
4 4

	
5 5
pkgconfig_DATA += lemon/lemon.pc
6 6

	
7 7
lib_LTLIBRARIES += lemon/libemon.la
8 8

	
9 9
lemon_libemon_la_SOURCES = \
10
        lemon/arg_parser.cc \
10 11
        lemon/base.cc \
11 12
        lemon/random.cc
12 13

	
13 14

	
14 15
lemon_libemon_la_CXXFLAGS = $(GLPK_CFLAGS) $(CPLEX_CFLAGS) $(SOPLEX_CXXFLAGS)
15 16
lemon_libemon_la_LDFLAGS = $(GLPK_LIBS) $(CPLEX_LIBS) $(SOPLEX_LIBS)
16 17

	
17 18
lemon_HEADERS += \
19
        lemon/arg_parser.h \
18 20
        lemon/concept_check.h \
19 21
        lemon/dim2.h \
20 22
	lemon/error.h \
21 23
	lemon/list_graph.h \
22 24
	lemon/maps.h \
23 25
	lemon/math.h \
0 comments (0 inline)