gravatar
alpar (Alpar Juttner)
alpar@cs.elte.hu
ArgParser can throw exception instead of exit(1) (#332)
0 3 0
default
3 files changed with 70 insertions and 5 deletions:
↑ Collapse diff ↑
Show white space 6 line context
... ...
@@ -65,9 +65,18 @@
65 65
  ap.other("infile", "The input file.")
66 66
    .other("...");
67 67

	
68
  // Throw an exception when problems occurs. The default behavior is to
69
  // exit(1) on these cases, but this makes Valgrind falsely warn
70
  // about memory leaks.
71
  ap.throwOnProblems();
72
  
68 73
  // Perform the parsing process
69 74
  // (in case of any error it terminates the program)
75
  // The try {} construct is necessary only if the ap.trowOnProblems()
76
  // setting is in use.
77
  try {
70 78
  ap.parse();
79
  } catch (ArgParserException &) { return 1; }
71 80

	
72 81
  // Check each option if it has been given and print its value
73 82
  std::cout << "Parameters of '" << ap.commandName() << "':\n";
Show white space 6 line context
... ...
@@ -20,14 +20,23 @@
20 20

	
21 21
namespace lemon {
22 22

	
23
  void ArgParser::_terminate(ArgParserException::Reason reason) const
24
  {
25
    if(_exit_on_problems)
26
      exit(1);
27
    else throw(ArgParserException(reason));
28
  }
29
  
30
  
23 31
  void ArgParser::_showHelp(void *p)
24 32
  {
25 33
    (static_cast<ArgParser*>(p))->showHelp();
26
    exit(1);
34
    (static_cast<ArgParser*>(p))->_terminate(ArgParserException::HELP);
27 35
  }
28 36

	
29 37
  ArgParser::ArgParser(int argc, const char * const *argv)
30
    :_argc(argc), _argv(argv), _command_name(argv[0]) {
38
    :_argc(argc), _argv(argv), _command_name(argv[0]),
39
    _exit_on_problems(true) {
31 40
    funcOption("-help","Print a short help message",_showHelp,this);
32 41
    synonym("help","-help");
33 42
    synonym("h","-help");
... ...
@@ -342,7 +351,7 @@
342 351
    for(std::vector<OtherArg>::const_iterator i=_others_help.begin();
343 352
        i!=_others_help.end();++i) showHelp(i);
344 353
    for(Opts::const_iterator i=_opts.begin();i!=_opts.end();++i) showHelp(i);
345
    exit(1);
354
    _terminate(ArgParserException::HELP);
346 355
  }
347 356

	
348 357

	
... ...
@@ -351,7 +360,7 @@
351 360
    std::cerr << "\nUnknown option: " << arg << "\n";
352 361
    std::cerr << "\nType '" << _command_name <<
353 362
      " --help' to obtain a short summary on the usage.\n\n";
354
    exit(1);
363
    _terminate(ArgParserException::UNKNOWN_OPT);
355 364
  }
356 365

	
357 366
  void ArgParser::requiresValue(std::string arg, OptType t) const
... ...
@@ -414,7 +423,7 @@
414 423
    if(!ok) {
415 424
      std::cerr << "\nType '" << _command_name <<
416 425
        " --help' to obtain a short summary on the usage.\n\n";
417
      exit(1);
426
      _terminate(ArgParserException::INVALID_OPT);
418 427
    }
419 428
  }
420 429

	
Show white space 6 line context
... ...
@@ -34,6 +34,44 @@
34 34

	
35 35
namespace lemon {
36 36

	
37
  ///Exception used by ArgParser
38
  class ArgParserException : public Exception {
39
  public:
40
    enum Reason {
41
      HELP,         /// <tt>--help</tt> option was given
42
      UNKNOWN_OPT,  /// Unknown option was given
43
      INVALID_OPT   /// Invalid combination of options
44
    };
45
    
46
  private:
47
    Reason _reason;
48
    
49
  public:
50
    ///Constructor
51
    ArgParserException(Reason r) throw() : _reason(r) {}
52
    ///Virtual destructor
53
    virtual ~ArgParserException() throw() {}
54
    ///A short description of the exception
55
    virtual const char* what() const throw() {
56
      switch(_reason)
57
        {
58
        case HELP:
59
          return "lemon::ArgParseException: ask for help";
60
          break;
61
        case UNKNOWN_OPT:
62
          return "lemon::ArgParseException: unknown option";
63
          break;
64
        case INVALID_OPT:
65
          return "lemon::ArgParseException: invalid combination of options";
66
          break;
67
        }
68
      return "";
69
    }
70
    ///Return the reason for the failure
71
    Reason reason() const {return _reason; }
72
  };
73

	
74

	
37 75
  ///Command line arguments parser
38 76

	
39 77
  ///\ingroup misc
... ...
@@ -116,6 +154,10 @@
116 154
                    const std::string &help,
117 155
                    void (*func)(void *),void *data);
118 156

	
157
    bool _exit_on_problems;
158
    
159
    void _terminate(ArgParserException::Reason reason) const;
160

	
119 161
  public:
120 162

	
121 163
    ///Constructor
... ...
@@ -380,6 +422,11 @@
380 422
    ///not starting with a '-' character.
381 423
    const std::vector<std::string> &files() const { return _file_args; }
382 424

	
425
    ///Throw instead of exit in case of problems
426
    void throwOnProblems() 
427
    {
428
      _exit_on_problems=false;
429
    }
383 430
  };
384 431
}
385 432

	
0 comments (0 inline)