Add try-catch block in example in order to fix memory leaks. Added specialized except...
authorRafał Długołęcki <rafal@dlugolecki.net.pl>
Sat, 9 May 2015 09:57:15 +0000 (11:57 +0200)
committerRafał Długołęcki <rafal@dlugolecki.net.pl>
Sat, 9 May 2015 09:57:15 +0000 (11:57 +0200)
include/exception/missingOptionValue.h [new file with mode: 0644]
include/exception/optionFailedConversion.h [new file with mode: 0644]
include/option.h
src/main.cpp

diff --git a/include/exception/missingOptionValue.h b/include/exception/missingOptionValue.h
new file mode 100644 (file)
index 0000000..c305005
--- /dev/null
@@ -0,0 +1,29 @@
+#ifndef __COMMAND_EXCEPTION_MISSING_OPTION_VALUE_H
+#define __COMMAND_EXCEPTION_MISSING_OPTION_VALUE_H
+
+#include <stdexcept>
+#include <string>
+
+namespace command {
+
+/**
+ * Helper template class used for releasing resources.
+ */
+class MissingOptionValue : public std::invalid_argument {
+private:
+    std::string message;
+public:
+    explicit MissingOptionValue(const std::string& what_arg) :
+        std::invalid_argument(what_arg), message(what_arg) { }
+
+    explicit MissingOptionValue(const char* what_arg) :
+        std::invalid_argument(what_arg), message(what_arg) { }
+
+    virtual const char* what() const throw() {
+        return message.c_str();
+    }
+};
+
+}
+
+#endif /* __COMMAND_EXCEPTION_MISSING_OPTION_VALUE_H */
diff --git a/include/exception/optionFailedConversion.h b/include/exception/optionFailedConversion.h
new file mode 100644 (file)
index 0000000..e4004f9
--- /dev/null
@@ -0,0 +1,29 @@
+#ifndef __COMMAND_EXCEPTION_OPTION_FAILED_CONVERSION_H
+#define __COMMAND_EXCEPTION_OPTION_FAILED_CONVERSION_H
+
+#include <stdexcept>
+#include <string>
+
+namespace command {
+
+/**
+ * Helper template class used for releasing resources.
+ */
+class OptionFailedConversion : public std::invalid_argument {
+protected:
+    std::string message;
+public:
+    explicit OptionFailedConversion(const std::string& what_arg) :
+        std::invalid_argument(what_arg), message(what_arg) { }
+
+    explicit OptionFailedConversion(const char* what_arg) :
+        std::invalid_argument(what_arg), message(what_arg) { }
+
+    virtual const char* what() const throw() {
+        return message.c_str();
+    }
+};
+
+}
+
+#endif /* __COMMAND_EXCEPTION_OPTION_FAILED_CONVERSION_H */
index 516fce016eb80c6d6e350c6e050fc498e9d3c497..21f814e105f9f3e6b1fffc91d50864109700c749 100644 (file)
@@ -6,6 +6,8 @@
 #include <stdexcept>
 
 #include "parameter.h"
+#include "exception/missingOptionValue.h"
+#include "exception/optionFailedConversion.h"
 
 namespace command {
     /**
@@ -79,29 +81,26 @@ namespace command {
          *  converted to ParameterType, returns true and Option is set as used one.
          *  Otherwise returns false and can be used to check against next value.
          *
-         * @throw std::invalid_argument when OptionName part has no equal sign
-         *  after itself
-         * @throw std::invalid_argument when OptionValue part failed conversion
+         * @throw MissingOptionValue when OptionValue part is missing after
+         *  equal sign
+         * @throw OptionFailedConversion when OptionValue part failed conversion
          *  to ParameterType
          */
-        virtual bool understand(const std::string & argv)
-            throw(std::invalid_argument) {
+        virtual bool understand(const std::string & argv) {
 
             if ((!isUsed()) && (argv.find(name) == 0)) {
                 std::size_t pos = argv.find("=");
 
                 if (pos != name.size()) {
-                    throw std::invalid_argument("Option: " + name + " requires value but no one has been provided");
+                    throw MissingOptionValue("Option: " + name + " requires value but no one has been provided");
                 }
 
                 std::stringstream ss;
                 ss << argv.substr(pos + 1);
-                ss >> value;// memory leak? when uncommented and exception is
-                            // thrown, valgrind shows e.g.:
-                            //  possibly lost: 380 bytes in 7 blocks
+                ss >> value;
 
                 if (ss.fail()) {
-                    throw std::invalid_argument("Value for option: " + name + " failed conversion to the required type");
+                    throw OptionFailedConversion("Value for option: " + name + " failed conversion to the required type");
                 }
 
                 used = true;
index 5cf4e83d018373e5e665bafaee685ee2989e7bff..42c44cb57118ee8b6e0bd2096c31fd4e9de5658d 100644 (file)
@@ -21,12 +21,18 @@ void void_function(void) {
 }
 
 int main(int argc, char *argv[]) {
-    Command command(argc, argv, {
-//         new Argument<std::string>("File path", [](std::string value)->void { std::cout << "Hello from lambda " << value << std::endl; }),
-        new Required(new Argument<bool>("File path", argument_function)),
-        new Option<std::string>("f", "Optional file", option_function),
-        new Option<void>("h", "Help", void_function)
-    });
+    try {
+        Command command(argc, argv, {
+//             new Argument<std::string>("File path", [](std::string value)->void { std::cout << "Hello from lambda " << value << std::endl; }),
+            new Required(new Argument<bool>("File path", argument_function)),
+            new Option<std::string>("f", "Optional file", option_function),
+            new Option<void>("h", "Help", void_function)
+        });
+
+    }
+    catch(const std::exception & e) {
+        std::cout << e.what() << std::endl;
+    }
 
     return 0;
 }
\ No newline at end of file