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