0cbb3d6eba84d4a02c1391f316f710de189c1514
[command.git] / include / command.h
1 #ifndef __COMMAND_COMMAND_H
2 #define __COMMAND_COMMAND_H
3
4 #include <string>
5 #include <vector>
6 #include <typeinfo>
7
8 #include "parameter.h"
9 #include "exception/missingRequiredParameter.h"
10
11 namespace command {
12     /**
13      * Main class for handling user passed parameters from command line.
14      */
15     class Command {
16     protected:
17         std::vector<Parameter *> parameters;
18     public:
19         /**
20          * Default constructor.
21          *
22          * @param argc passed to the main function
23          * @param argv passed to the main function
24          * @param params initializer_list containing Parameter handlers
25          *      responsible for correctly handle user data.
26          */
27         Command(unsigned int argc, char *argv[], std::initializer_list<Parameter *> params)
28             : parameters(params) {
29
30             try {
31                 matchArguments(argc, argv);
32             }
33             catch(const std::invalid_argument & exception) {
34                 releaseMemory();
35                 throw;
36             }
37             catch(const std::logic_error & exception) {
38                 releaseMemory();
39                 throw;
40             }
41         }
42
43         /**
44          * Destructor. Releases allocated memory.
45          */
46         ~Command() {
47             releaseMemory();
48         }
49     protected:
50         /**
51          * Matches user passed arguments with available parameter handlers.
52          */
53         void matchArguments(unsigned int argc, char *argv[]) {
54             for (unsigned int i = 1; i < argc; i++) {
55                 for(Parameter *param : parameters) {
56                     if (param->understand(argv[i])) {
57                         param->handle();
58                         break;
59                     }
60                 }
61             }
62             for(Parameter *param : parameters) {
63                 if (param->isRequired() && !param->isUsed()) {
64                     throw MissingRequiredParameter(param->describe() + " is required but it was not passed");
65                 }
66             }
67         }
68
69         /**
70          * Releases acquired memory
71          */
72         void releaseMemory() {
73             for (Parameter * parameter : parameters) {
74                 if (parameter != NULL) {
75                     delete parameter;
76                 }
77             }
78             parameters.clear();
79             parameters.shrink_to_fit();
80         }
81     };
82 }
83
84 #endif /* __COMMAND_COMMAND_H */