Cleanup exceptions.
[command.git] / include / command.h
index f53227ea4a994d32e7b3c645b009def1f169b22f..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,29 +14,69 @@ namespace command {
      */
     class Command {
     protected:
-        unsigned int argc;
-        std::vector<std::string> _argv;
-        std::vector<Parameter *> args;
+        std::vector<Parameter *> parameters;
     public:
         /**
          * Default constructor.
          *
-         * @param 
-         * @param 
-         * @param 
+         * @param argc passed to the main function
+         * @param argv passed to the main function
+         * @param params initializer_list containing Parameter handlers
+         *      responsible for correctly handle user data.
          */
         Command(unsigned int argc, char *argv[], std::initializer_list<Parameter *> params)
-            : args(params) {
-            for(Parameter *param : params) {
-                std::cout << "Command foreach" << std::endl;
-                param->handle();
+            : parameters(params) {
+
+            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[]) {
+            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");
+                }
+            }
+        }
+
+        /**
+         * Releases acquired memory
+         */
+        void releaseMemory() {
+            for (Parameter * parameter : parameters) {
+                if (parameter != NULL) {
+                    delete parameter;
+                }
             }
+            parameters.clear();
+            parameters.shrink_to_fit();
         }
     };
 }