1.1 --- a/demo/arg_parser_demo.cc Fri Feb 12 22:24:26 2010 +0100
1.2 +++ b/demo/arg_parser_demo.cc Sun Feb 14 19:23:55 2010 +0100
1.3 @@ -65,9 +65,18 @@
1.4 ap.other("infile", "The input file.")
1.5 .other("...");
1.6
1.7 + // Throw an exception when problems occurs. The default behavior is to
1.8 + // exit(1) on these cases, but this makes Valgrind falsely warn
1.9 + // about memory leaks.
1.10 + ap.throwOnProblems();
1.11 +
1.12 // Perform the parsing process
1.13 // (in case of any error it terminates the program)
1.14 - ap.parse();
1.15 + // The try {} construct is necessary only if the ap.trowOnProblems()
1.16 + // setting is in use.
1.17 + try {
1.18 + ap.parse();
1.19 + } catch (ArgParserException &) { return 1; }
1.20
1.21 // Check each option if it has been given and print its value
1.22 std::cout << "Parameters of '" << ap.commandName() << "':\n";
2.1 --- a/lemon/arg_parser.cc Fri Feb 12 22:24:26 2010 +0100
2.2 +++ b/lemon/arg_parser.cc Sun Feb 14 19:23:55 2010 +0100
2.3 @@ -20,14 +20,23 @@
2.4
2.5 namespace lemon {
2.6
2.7 + void ArgParser::_terminate(ArgParserException::Reason reason) const
2.8 + {
2.9 + if(_exit_on_problems)
2.10 + exit(1);
2.11 + else throw(ArgParserException(reason));
2.12 + }
2.13 +
2.14 +
2.15 void ArgParser::_showHelp(void *p)
2.16 {
2.17 (static_cast<ArgParser*>(p))->showHelp();
2.18 - exit(1);
2.19 + (static_cast<ArgParser*>(p))->_terminate(ArgParserException::HELP);
2.20 }
2.21
2.22 ArgParser::ArgParser(int argc, const char * const *argv)
2.23 - :_argc(argc), _argv(argv), _command_name(argv[0]) {
2.24 + :_argc(argc), _argv(argv), _command_name(argv[0]),
2.25 + _exit_on_problems(true) {
2.26 funcOption("-help","Print a short help message",_showHelp,this);
2.27 synonym("help","-help");
2.28 synonym("h","-help");
2.29 @@ -342,7 +351,7 @@
2.30 for(std::vector<OtherArg>::const_iterator i=_others_help.begin();
2.31 i!=_others_help.end();++i) showHelp(i);
2.32 for(Opts::const_iterator i=_opts.begin();i!=_opts.end();++i) showHelp(i);
2.33 - exit(1);
2.34 + _terminate(ArgParserException::HELP);
2.35 }
2.36
2.37
2.38 @@ -351,7 +360,7 @@
2.39 std::cerr << "\nUnknown option: " << arg << "\n";
2.40 std::cerr << "\nType '" << _command_name <<
2.41 " --help' to obtain a short summary on the usage.\n\n";
2.42 - exit(1);
2.43 + _terminate(ArgParserException::UNKNOWN_OPT);
2.44 }
2.45
2.46 void ArgParser::requiresValue(std::string arg, OptType t) const
2.47 @@ -414,7 +423,7 @@
2.48 if(!ok) {
2.49 std::cerr << "\nType '" << _command_name <<
2.50 " --help' to obtain a short summary on the usage.\n\n";
2.51 - exit(1);
2.52 + _terminate(ArgParserException::INVALID_OPT);
2.53 }
2.54 }
2.55
3.1 --- a/lemon/arg_parser.h Fri Feb 12 22:24:26 2010 +0100
3.2 +++ b/lemon/arg_parser.h Sun Feb 14 19:23:55 2010 +0100
3.3 @@ -34,6 +34,44 @@
3.4
3.5 namespace lemon {
3.6
3.7 + ///Exception used by ArgParser
3.8 + class ArgParserException : public Exception {
3.9 + public:
3.10 + enum Reason {
3.11 + HELP, /// <tt>--help</tt> option was given
3.12 + UNKNOWN_OPT, /// Unknown option was given
3.13 + INVALID_OPT /// Invalid combination of options
3.14 + };
3.15 +
3.16 + private:
3.17 + Reason _reason;
3.18 +
3.19 + public:
3.20 + ///Constructor
3.21 + ArgParserException(Reason r) throw() : _reason(r) {}
3.22 + ///Virtual destructor
3.23 + virtual ~ArgParserException() throw() {}
3.24 + ///A short description of the exception
3.25 + virtual const char* what() const throw() {
3.26 + switch(_reason)
3.27 + {
3.28 + case HELP:
3.29 + return "lemon::ArgParseException: ask for help";
3.30 + break;
3.31 + case UNKNOWN_OPT:
3.32 + return "lemon::ArgParseException: unknown option";
3.33 + break;
3.34 + case INVALID_OPT:
3.35 + return "lemon::ArgParseException: invalid combination of options";
3.36 + break;
3.37 + }
3.38 + return "";
3.39 + }
3.40 + ///Return the reason for the failure
3.41 + Reason reason() const {return _reason; }
3.42 + };
3.43 +
3.44 +
3.45 ///Command line arguments parser
3.46
3.47 ///\ingroup misc
3.48 @@ -103,7 +141,7 @@
3.49 std::vector<std::string> _file_args;
3.50 std::string _command_name;
3.51
3.52 -
3.53 +
3.54 private:
3.55 //Bind a function to an option.
3.56
3.57 @@ -116,6 +154,10 @@
3.58 const std::string &help,
3.59 void (*func)(void *),void *data);
3.60
3.61 + bool _exit_on_problems;
3.62 +
3.63 + void _terminate(ArgParserException::Reason reason) const;
3.64 +
3.65 public:
3.66
3.67 ///Constructor
3.68 @@ -380,6 +422,11 @@
3.69 ///not starting with a '-' character.
3.70 const std::vector<std::string> &files() const { return _file_args; }
3.71
3.72 + ///Throw instead of exit in case of problems
3.73 + void throwOnProblems()
3.74 + {
3.75 + _exit_on_problems=false;
3.76 + }
3.77 };
3.78 }
3.79