Cleanup exceptions.
[command.git] / include / command.h
index a48ab91f5ee02b8eed81a7645cbf2be904f3e9c2..0cbb3d6eba84d4a02c1391f316f710de189c1514 100644 (file)
@@ -3,9 +3,10 @@
 
 #include <string>
 #include <vector>
-#include <iostream>
+#include <typeinfo>
 
 #include "parameter.h"
+#include "exception/missingRequiredParameter.h"
 
 namespace command {
     /**
@@ -13,7 +14,7 @@ namespace command {
      */
     class Command {
     protected:
-        std::vector<Parameter *> args;
+        std::vector<Parameter *> parameters;
     public:
         /**
          * Default constructor.
@@ -24,35 +25,58 @@ namespace command {
          *      responsible for correctly handle user data.
          */
         Command(unsigned int argc, char *argv[], std::initializer_list<Parameter *> params)
-            : args(params) {
+            : parameters(params) {
 
-            matchArguments(argc, argv);
-            invoke();
+            try {
+                matchArguments(argc, argv);
+            }
+            catch(const std::invalid_argument & exception) {
+                releaseMemory();
+                throw;
+            }
+            catch(const std::logic_error & exception) {
+                releaseMemory();
+                throw;
+            }
         }
 
         /**
          * Destructor. Releases allocated memory.
          */
         ~Command() {
-            for (Parameter * parameter : args) {
-                delete parameter;
-            }
+            releaseMemory();
         }
     protected:
         /**
          * Matches user passed arguments with available parameter handlers.
          */
         void matchArguments(unsigned int argc, char *argv[]) {
-//             param->passUserValue();
+            for (unsigned int i = 1; i < argc; i++) {
+                for(Parameter *param : parameters) {
+                    if (param->understand(argv[i])) {
+                        param->handle();
+                        break;
+                    }
+                }
+            }
+            for(Parameter *param : parameters) {
+                if (param->isRequired() && !param->isUsed()) {
+                    throw MissingRequiredParameter(param->describe() + " is required but it was not passed");
+                }
+            }
         }
 
         /**
-         * Invokes passed parameter handlers
+         * Releases acquired memory
          */
-        void invoke() {
-            for(Parameter *param : params) {
-                param->handle();
+        void releaseMemory() {
+            for (Parameter * parameter : parameters) {
+                if (parameter != NULL) {
+                    delete parameter;
+                }
             }
+            parameters.clear();
+            parameters.shrink_to_fit();
         }
     };
 }