[Lemon-commits] Alpar Juttner: ArgParser can throw exception ins...
Lemon HG
hg at lemon.cs.elte.hu
Sun Feb 28 19:25:45 CET 2010
details: http://lemon.cs.elte.hu/hg/lemon/rev/c2ff0a365245
changeset: 915:c2ff0a365245
user: Alpar Juttner <alpar [at] cs.elte.hu>
date: Sun Feb 14 19:23:55 2010 +0100
description:
ArgParser can throw exception instead of exit(1) (#332)
diffstat:
demo/arg_parser_demo.cc | 11 ++++++++++-
lemon/arg_parser.cc | 19 ++++++++++++++-----
lemon/arg_parser.h | 49 ++++++++++++++++++++++++++++++++++++++++++++++++-
3 files changed, 72 insertions(+), 7 deletions(-)
diffs (159 lines):
diff --git a/demo/arg_parser_demo.cc b/demo/arg_parser_demo.cc
--- a/demo/arg_parser_demo.cc
+++ b/demo/arg_parser_demo.cc
@@ -65,9 +65,18 @@
ap.other("infile", "The input file.")
.other("...");
+ // Throw an exception when problems occurs. The default behavior is to
+ // exit(1) on these cases, but this makes Valgrind falsely warn
+ // about memory leaks.
+ ap.throwOnProblems();
+
// Perform the parsing process
// (in case of any error it terminates the program)
- ap.parse();
+ // The try {} construct is necessary only if the ap.trowOnProblems()
+ // setting is in use.
+ try {
+ ap.parse();
+ } catch (ArgParserException &) { return 1; }
// Check each option if it has been given and print its value
std::cout << "Parameters of '" << ap.commandName() << "':\n";
diff --git a/lemon/arg_parser.cc b/lemon/arg_parser.cc
--- a/lemon/arg_parser.cc
+++ b/lemon/arg_parser.cc
@@ -20,14 +20,23 @@
namespace lemon {
+ void ArgParser::_terminate(ArgParserException::Reason reason) const
+ {
+ if(_exit_on_problems)
+ exit(1);
+ else throw(ArgParserException(reason));
+ }
+
+
void ArgParser::_showHelp(void *p)
{
(static_cast<ArgParser*>(p))->showHelp();
- exit(1);
+ (static_cast<ArgParser*>(p))->_terminate(ArgParserException::HELP);
}
ArgParser::ArgParser(int argc, const char * const *argv)
- :_argc(argc), _argv(argv), _command_name(argv[0]) {
+ :_argc(argc), _argv(argv), _command_name(argv[0]),
+ _exit_on_problems(true) {
funcOption("-help","Print a short help message",_showHelp,this);
synonym("help","-help");
synonym("h","-help");
@@ -342,7 +351,7 @@
for(std::vector<OtherArg>::const_iterator i=_others_help.begin();
i!=_others_help.end();++i) showHelp(i);
for(Opts::const_iterator i=_opts.begin();i!=_opts.end();++i) showHelp(i);
- exit(1);
+ _terminate(ArgParserException::HELP);
}
@@ -351,7 +360,7 @@
std::cerr << "\nUnknown option: " << arg << "\n";
std::cerr << "\nType '" << _command_name <<
" --help' to obtain a short summary on the usage.\n\n";
- exit(1);
+ _terminate(ArgParserException::UNKNOWN_OPT);
}
void ArgParser::requiresValue(std::string arg, OptType t) const
@@ -414,7 +423,7 @@
if(!ok) {
std::cerr << "\nType '" << _command_name <<
" --help' to obtain a short summary on the usage.\n\n";
- exit(1);
+ _terminate(ArgParserException::INVALID_OPT);
}
}
diff --git a/lemon/arg_parser.h b/lemon/arg_parser.h
--- a/lemon/arg_parser.h
+++ b/lemon/arg_parser.h
@@ -34,6 +34,44 @@
namespace lemon {
+ ///Exception used by ArgParser
+ class ArgParserException : public Exception {
+ public:
+ enum Reason {
+ HELP, /// <tt>--help</tt> option was given
+ UNKNOWN_OPT, /// Unknown option was given
+ INVALID_OPT /// Invalid combination of options
+ };
+
+ private:
+ Reason _reason;
+
+ public:
+ ///Constructor
+ ArgParserException(Reason r) throw() : _reason(r) {}
+ ///Virtual destructor
+ virtual ~ArgParserException() throw() {}
+ ///A short description of the exception
+ virtual const char* what() const throw() {
+ switch(_reason)
+ {
+ case HELP:
+ return "lemon::ArgParseException: ask for help";
+ break;
+ case UNKNOWN_OPT:
+ return "lemon::ArgParseException: unknown option";
+ break;
+ case INVALID_OPT:
+ return "lemon::ArgParseException: invalid combination of options";
+ break;
+ }
+ return "";
+ }
+ ///Return the reason for the failure
+ Reason reason() const {return _reason; }
+ };
+
+
///Command line arguments parser
///\ingroup misc
@@ -103,7 +141,7 @@
std::vector<std::string> _file_args;
std::string _command_name;
-
+
private:
//Bind a function to an option.
@@ -116,6 +154,10 @@
const std::string &help,
void (*func)(void *),void *data);
+ bool _exit_on_problems;
+
+ void _terminate(ArgParserException::Reason reason) const;
+
public:
///Constructor
@@ -380,6 +422,11 @@
///not starting with a '-' character.
const std::vector<std::string> &files() const { return _file_args; }
+ ///Throw instead of exit in case of problems
+ void throwOnProblems()
+ {
+ _exit_on_problems=false;
+ }
};
}
More information about the Lemon-commits
mailing list