gravatar
alpar (Alpar Juttner)
alpar@cs.elte.hu
Merge
0 2 0
merge default
0 files changed with 45 insertions and 41 deletions:
↑ Collapse diff ↑
Show white space 12288 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
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 72
    _opts[name]=p;
73 73
    return *this;
74 74
  }
75 75

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

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

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

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

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

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

	
158 158
    ref = false;
159 159

	
160 160
    return *this;
161 161
  }
162 162

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

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

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

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

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

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

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

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

	
264
  void ArgParser::show(std::ostream &os,Groups::iterator i)
264
  void ArgParser::show(std::ostream &os,Groups::const_iterator i) const
265 265
  {
266
    GroupData::Opts::iterator o=i->second.opts.begin();
266
    GroupData::Opts::const_iterator o=i->second.opts.begin();
267 267
    while(o!=i->second.opts.end()) {
268 268
      show(os,_opts.find(*o));
269 269
      ++o;
270 270
      if(o!=i->second.opts.end()) os<<'|';
271 271
    }
272 272
  }
273 273

	
274
  void ArgParser::showHelp(Opts::iterator i)
274
  void ArgParser::showHelp(Opts::const_iterator i) const
275 275
  {
276 276
    if(i->second.help.size()==0||i->second.syn) return;
277 277
    std::cerr << "  ";
278 278
    show(std::cerr,i);
279 279
    std::cerr << std::endl;
280 280
    std::cerr << "     " << i->second.help << std::endl;
281 281
  }
282
  void ArgParser::showHelp(std::vector<ArgParser::OtherArg>::iterator i)
282
  void ArgParser::showHelp(std::vector<ArgParser::OtherArg>::const_iterator i)
283
    const
283 284
  {
284 285
    if(i->help.size()==0) return;
285 286
    std::cerr << "  " << i->name << std::endl
286 287
              << "     " << i->help << std::endl;
287 288
  }
288 289

	
289
  void ArgParser::shortHelp()
290
  void ArgParser::shortHelp() const
290 291
  {
291 292
    const unsigned int LINE_LEN=77;
292 293
    const std::string indent("    ");
293 294
    std::cerr << "Usage:\n  " << _command_name;
294 295
    int pos=_command_name.size()+2;
295
    for(Groups::iterator g=_groups.begin();g!=_groups.end();++g) {
296
    for(Groups::const_iterator g=_groups.begin();g!=_groups.end();++g) {
296 297
      std::ostringstream cstr;
297 298
      cstr << ' ';
298 299
      if(!g->second.mandatory) cstr << '[';
299 300
      show(cstr,g);
300 301
      if(!g->second.mandatory) cstr << ']';
301 302
      if(pos+cstr.str().size()>LINE_LEN) {
302 303
        std::cerr << std::endl << indent;
303 304
        pos=indent.size();
304 305
      }
305 306
      std::cerr << cstr.str();
306 307
      pos+=cstr.str().size();
307 308
    }
308
    for(Opts::iterator i=_opts.begin();i!=_opts.end();++i)
309
    for(Opts::const_iterator i=_opts.begin();i!=_opts.end();++i)
309 310
      if(!i->second.ingroup&&!i->second.syn) {
310 311
        std::ostringstream cstr;
311 312
        cstr << ' ';
312 313
        if(!i->second.mandatory) cstr << '[';
313 314
        show(cstr,i);
314 315
        if(!i->second.mandatory) cstr << ']';
315 316
        if(pos+cstr.str().size()>LINE_LEN) {
316 317
          std::cerr << std::endl << indent;
317 318
          pos=indent.size();
318 319
        }
319 320
        std::cerr << cstr.str();
320 321
        pos+=cstr.str().size();
321 322
      }
322
    for(std::vector<OtherArg>::iterator i=_others_help.begin();
323
    for(std::vector<OtherArg>::const_iterator i=_others_help.begin();
323 324
        i!=_others_help.end();++i)
324 325
      {
325 326
        std::ostringstream cstr;
326 327
        cstr << ' ' << i->name;
327 328

	
328 329
        if(pos+cstr.str().size()>LINE_LEN) {
329 330
          std::cerr << std::endl << indent;
330 331
          pos=indent.size();
331 332
        }
332 333
        std::cerr << cstr.str();
333 334
        pos+=cstr.str().size();
334 335
      }
335 336
    std::cerr << std::endl;
336 337
  }
337 338

	
338
  void ArgParser::showHelp()
339
  void ArgParser::showHelp() const
339 340
  {
340 341
    shortHelp();
341 342
    std::cerr << "Where:\n";
342
    for(std::vector<OtherArg>::iterator i=_others_help.begin();
343
    for(std::vector<OtherArg>::const_iterator i=_others_help.begin();
343 344
        i!=_others_help.end();++i) showHelp(i);
344
    for(Opts::iterator i=_opts.begin();i!=_opts.end();++i) showHelp(i);
345
    for(Opts::const_iterator i=_opts.begin();i!=_opts.end();++i) showHelp(i);
345 346
    exit(1);
346 347
  }
347 348

	
348 349

	
349
  void ArgParser::unknownOpt(std::string arg)
350
  void ArgParser::unknownOpt(std::string arg) const
350 351
  {
351 352
    std::cerr << "\nUnknown option: " << arg << "\n";
352 353
    std::cerr << "\nType '" << _command_name <<
353 354
      " --help' to obtain a short summary on the usage.\n\n";
354 355
    exit(1);
355 356
  }
356 357

	
357
  void ArgParser::requiresValue(std::string arg, OptType t)
358
  void ArgParser::requiresValue(std::string arg, OptType t) const
358 359
  {
359 360
    std::cerr << "Argument '" << arg << "' requires a";
360 361
    switch(t) {
361 362
    case STRING:
362 363
      std::cerr << " string";
363 364
      break;
364 365
    case INTEGER:
365 366
      std::cerr << "n integer";
366 367
      break;
367 368
    case DOUBLE:
368 369
      std::cerr << " floating point";
369 370
      break;
370 371
    default:
371 372
      break;
372 373
    }
373 374
    std::cerr << " value\n\n";
374 375
    showHelp();
375 376
  }
376 377

	
377 378

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

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

	
462 463
    return *this;
463 464
  }
464 465

	
465 466
}
Show white space 12288 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5 5
 * Copyright (C) 2003-2008
6 6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
8 8
 *
9 9
 * Permission to use, modify and distribute this software is granted
10 10
 * provided that this copyright notice appears in all copies. For
11 11
 * precise terms see the accompanying LICENSE file.
12 12
 *
13 13
 * This software is provided "AS IS" with no warranty of any kind,
14 14
 * express or implied, and with no claim as to its suitability for any
15 15
 * purpose.
16 16
 *
17 17
 */
18 18

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

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

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

	
35 35
namespace lemon {
36 36

	
37 37
  ///Command line arguments parser
38 38

	
39 39
  ///\ingroup misc
40 40
  ///Command line arguments parser.
41 41
  ///
42 42
  ///For a complete example see the \ref arg_parser_demo.cc demo file.
43 43
  class ArgParser {
44 44

	
45 45
    static void _showHelp(void *p);
46 46
  protected:
47 47

	
48 48
    int _argc;
49 49
    const char **_argv;
50 50

	
51 51
    enum OptType { UNKNOWN=0, BOOL=1, STRING=2, DOUBLE=3, INTEGER=4, FUNC=5 };
52 52

	
53 53
    class ParData {
54 54
    public:
55 55
      union {
56 56
        bool *bool_p;
57 57
        int *int_p;
58 58
        double *double_p;
59 59
        std::string *string_p;
60 60
        struct {
61 61
          void (*p)(void *);
62 62
          void *data;
63 63
        } func_p;
64 64

	
65 65
      };
66 66
      std::string help;
67 67
      bool mandatory;
68 68
      OptType type;
69 69
      bool set;
70 70
      bool ingroup;
71 71
      bool has_syn;
72 72
      bool syn;
73 73
      bool self_delete;
74 74
      ParData() : mandatory(false), type(UNKNOWN), set(false), ingroup(false),
75 75
                  has_syn(false), syn(false), self_delete(false) {}
76 76
    };
77 77

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

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

	
91 91
    typedef std::map<std::string,GroupData> Groups;
92 92
    Groups _groups;
93 93

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

	
100 100
    };
101 101

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

	
106 106

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

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

	
119 119
  public:
120 120

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

	
124 124
    ~ArgParser();
125 125

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

	
129 129
    ///@{
130 130

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

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

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

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

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

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

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

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

	
176 176
    ///Give help string for non-parsed arguments.
177 177

	
178 178
    ///With this function you can give help string for non-parsed arguments.
179 179
    ///The parameter \c name will be printed in the short usage line, while
180 180
    ///\c help gives a more detailed description.
181 181
    ArgParser &other(const std::string &name,
182 182
                     const std::string &help="");
183 183

	
184 184
    ///@}
185 185

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

	
190 190
    ///@{
191 191

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

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

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

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

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

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

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

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

	
237 237
    ///@}
238 238

	
239 239
    ///\name Option Groups and Synonyms
240 240
    ///
241 241

	
242 242
    ///@{
243 243

	
244 244
    ///Bundle some options into a group
245 245

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

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

	
255 255
    ///If you call this function for a group, than at most one of them can be
256 256
    ///given at the same time.
257 257
    ArgParser &onlyOneGroup(const std::string &group);
258 258

	
259 259
    ///Make a group mandatory
260 260

	
261 261
    ///Using this function, at least one of the members of \c group
262 262
    ///must be given.
263 263
    ArgParser &mandatoryGroup(const std::string &group);
264 264

	
265 265
    ///Create synonym to an option
266 266

	
267 267
    ///With this function you can create a synonym \c syn of the
268 268
    ///option \c opt.
269 269
    ArgParser &synonym(const std::string &syn,
270 270
                           const std::string &opt);
271 271

	
272 272
    ///@}
273 273

	
274
    void show(std::ostream &os,Opts::iterator i);
275
    void show(std::ostream &os,Groups::iterator i);
276
    void showHelp(Opts::iterator i);
277
    void showHelp(std::vector<OtherArg>::iterator i);
278
    void shortHelp();
279
    void showHelp();
274
  private:
275
    void show(std::ostream &os,Opts::const_iterator i) const;
276
    void show(std::ostream &os,Groups::const_iterator i) const;
277
    void showHelp(Opts::const_iterator i) const;
278
    void showHelp(std::vector<OtherArg>::const_iterator i) const;
280 279

	
281
    void unknownOpt(std::string arg);
280
    void unknownOpt(std::string arg) const;
282 281

	
283
    void requiresValue(std::string arg, OptType t);
284
    void checkMandatories();
282
    void requiresValue(std::string arg, OptType t) const;
283
    void checkMandatories() const;
284

	
285
    void shortHelp() const;
286
    void showHelp() const;
287
  public:
285 288

	
286 289
    ///Start the parsing process
287 290
    ArgParser &parse();
288 291

	
289 292
    /// Synonym for parse()
290 293
    ArgParser &run()
291 294
    {
292 295
      return parse();
293 296
    }
294 297

	
295 298
    ///Give back the command name (the 0th argument)
296
    const std::string &commandName() { return _command_name; }
299
    const std::string &commandName() const { return _command_name; }
297 300

	
298 301
    ///Check if an opion has been given to the command.
299
    bool given(std::string op)
302
    bool given(std::string op) const
300 303
    {
301
      Opts::iterator i = _opts.find(op);
304
      Opts::const_iterator i = _opts.find(op);
302 305
      return i!=_opts.end()?i->second.set:false;
303 306
    }
304 307

	
305 308

	
306 309
    ///Magic type for operator[]
307 310

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

	
362 365
    };
363 366

	
364 367
    ///Give back the value of an option
365 368

	
366 369
    ///Give back the value of an option.
367 370
    ///\sa RefType
368
    RefType operator[](const std::string &n)
371
    RefType operator[](const std::string &n) const
369 372
    {
370 373
      return RefType(*this, n);
371 374
    }
372 375

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

	
375 378
    ///Give back a reference to a vector consisting of the program arguments
376 379
    ///not starting with a '-' character.
377
    std::vector<std::string> &files() { return _file_args; }
380
    const std::vector<std::string> &files() const { return _file_args; }
378 381

	
379 382
  };
380 383
}
381 384

	
382 385
#endif // LEMON_ARG_PARSER
0 comments (0 inline)