gravatar
ladanyi@tmit.bme.hu
ladanyi@tmit.bme.hu
Fix an erroneous const declaration in ArgParser
0 3 0
default
3 files changed with 5 insertions and 6 deletions:
↑ Collapse diff ↑
Ignore white space 6 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
///\ingroup demos
20 20
///\file
21 21
///\brief Argument parser demo
22 22
///
23 23
/// This example shows how the argument parser can be used.
24 24
///
25 25
/// \include arg_parser_demo.cc
26 26

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

	
29 29
using namespace lemon;
30
int main(int argc, const char **argv)
30
int main(int argc, char **argv)
31 31
{
32 32
  // Initialize the argument parser
33 33
  ArgParser ap(argc, argv);
34 34
  int i;
35 35
  std::string s;
36 36
  double d = 1.0;
37 37
  bool b, nh;
38 38
  bool g1, g2, g3;
39 39

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

	
68 68
  // Perform the parsing process
69 69
  // (in case of any error it terminates the program)
70 70
  ap.parse();
71 71

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

	
75 75
  std::cout << "  Value of -n: " << i << std::endl;
76 76
  if(ap.given("val")) std::cout << "  Value of -val: " << d << std::endl;
77 77
  if(ap.given("val2")) {
78 78
    d = ap["val2"];
79 79
    std::cout << "  Value of -val2: " << d << std::endl;
80 80
  }
81 81
  if(ap.given("name")) std::cout << "  Value of -name: " << s << std::endl;
82 82
  if(ap.given("f")) std::cout << "  -f is given\n";
83 83
  if(ap.given("nohelp")) std::cout << "  Value of -nohelp: " << nh << std::endl;
84 84
  if(ap.given("gra")) std::cout << "  -gra is given\n";
85 85
  if(ap.given("grb")) std::cout << "  -grb is given\n";
86 86
  if(ap.given("grc")) std::cout << "  -grc is given\n";
87 87

	
88 88
  switch(ap.files().size()) {
89 89
  case 0:
90 90
    std::cout << "  No file argument was given.\n";
91 91
    break;
92 92
  case 1:
93 93
    std::cout << "  1 file argument was given. It is:\n";
94 94
    break;
95 95
  default:
96 96
    std::cout << "  "
97 97
              << ap.files().size() << " file arguments were given. They are:\n";
98 98
  }
99 99
  for(unsigned int i=0;i<ap.files().size();++i)
100 100
    std::cout << "    '" << ap.files()[i] << "'\n";
101 101

	
102 102
  return 0;
103 103
}
Ignore white space 768 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
  ArgParser::ArgParser(int argc, const char **argv) :_argc(argc), _argv(argv),
30
                                                     _command_name(argv[0]) {
29
  ArgParser::ArgParser(int argc, const char * const *argv)
30
    :_argc(argc), _argv(argv), _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

	
35 34
  }
36 35

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

	
61 60

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

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

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

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

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

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

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

	
158 157
    ref = false;
159 158

	
160 159
    return *this;
161 160
  }
162 161

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

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

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

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

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

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

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

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

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

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

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

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

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

	
349 348

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

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

	
378 377

	
379 378
  void ArgParser::checkMandatories() const
380 379
  {
381 380
    bool ok=true;
382 381
    for(Opts::const_iterator i=_opts.begin();i!=_opts.end();++i)
383 382
      if(i->second.mandatory&&!i->second.set)
384 383
        {
385 384
          if(ok)
386 385
            std::cerr << _command_name
387 386
                      << ": The following mandatory arguments are missing.\n";
388 387
          ok=false;
389 388
          showHelp(i);
390 389
        }
391 390
    for(Groups::const_iterator i=_groups.begin();i!=_groups.end();++i)
392 391
      if(i->second.mandatory||i->second.only_one)
393 392
        {
394 393
          int set=0;
395 394
          for(GroupData::Opts::const_iterator o=i->second.opts.begin();
396 395
              o!=i->second.opts.end();++o)
397 396
            if(_opts.find(*o)->second.set) ++set;
398 397
          if(i->second.mandatory&&!set) {
399 398
            std::cerr << _command_name <<
400 399
              ": At least one of the following arguments is mandatory.\n";
401 400
            ok=false;
402 401
            for(GroupData::Opts::const_iterator o=i->second.opts.begin();
403 402
                o!=i->second.opts.end();++o)
404 403
              showHelp(_opts.find(*o));
405 404
          }
406 405
          if(i->second.only_one&&set>1) {
407 406
            std::cerr << _command_name <<
408 407
              ": At most one of the following arguments can be given.\n";
409 408
            ok=false;
410 409
            for(GroupData::Opts::const_iterator o=i->second.opts.begin();
411 410
                o!=i->second.opts.end();++o)
412 411
              showHelp(_opts.find(*o));
413 412
          }
414 413
        }
415 414
    if(!ok) {
416 415
      std::cerr << "\nType '" << _command_name <<
417 416
        " --help' to obtain a short summary on the usage.\n\n";
418 417
      exit(1);
Ignore white space 6 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_H
20 20
#define LEMON_ARG_PARSER_H
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
    const char **_argv;
49
    const char * const *_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
    ArgParser(int argc, const char **argv);
122
    ArgParser(int argc, const char * const *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 274
  private:
275 275
    void show(std::ostream &os,Opts::const_iterator i) const;
276 276
    void show(std::ostream &os,Groups::const_iterator i) const;
277 277
    void showHelp(Opts::const_iterator i) const;
278 278
    void showHelp(std::vector<OtherArg>::const_iterator i) const;
279 279

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

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

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

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

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

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

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

	
308 308

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

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

	
366 366
    };
367 367

	
368 368
    ///Give back the value of an option
369 369

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

	
377 377
    ///Give back the non-option type arguments.
378 378

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

	
383 383
  };
384 384
}
385 385

	
386 386
#endif // LEMON_ARG_PARSER_H
0 comments (0 inline)