]> granicus.if.org Git - icinga2/blob - tools/mkclass/classcompiler.hpp
Merge pull request #7591 from Icinga/feature/docs-api-joins
[icinga2] / tools / mkclass / classcompiler.hpp
1 /* Icinga 2 | (c) 2012 Icinga GmbH | GPLv2+ */
2
3 #ifndef CLASSCOMPILER_H
4 #define CLASSCOMPILER_H
5
6 #include <string>
7 #include <istream>
8 #include <utility>
9 #include <vector>
10 #include <algorithm>
11 #include <map>
12
13 namespace icinga
14 {
15
16 struct ClassDebugInfo
17 {
18         std::string path;
19         int first_line;
20         int first_column;
21         int last_line;
22         int last_column;
23 };
24
25 enum FieldAccessorType
26 {
27         FTGet,
28         FTSet,
29         FTDefault,
30         FTTrack,
31         FTNavigate
32 };
33
34 struct FieldAccessor
35 {
36         FieldAccessorType Type;
37         std::string Accessor;
38         bool Pure;
39
40         FieldAccessor(FieldAccessorType type, std::string accessor, bool pure)
41                 : Type(type), Accessor(std::move(accessor)), Pure(pure)
42         { }
43 };
44
45 /* keep this in sync with lib/base/type.hpp */
46 enum FieldAttribute
47 {
48         FAEphemeral = 1,
49         FAConfig = 2,
50         FAState = 4,
51         FAEnum = 8,
52         FAGetProtected = 16,
53         FASetProtected = 32,
54         FANoStorage = 64,
55         FALoadDependency = 128,
56         FARequired = 256,
57         FANavigation = 512,
58         FANoUserModify = 1024,
59         FANoUserView = 2048,
60         FADeprecated = 4096,
61         FAGetVirtual = 8192,
62         FASetVirtual = 16384,
63         FAActivationPriority = 32768
64 };
65
66 struct FieldType
67 {
68         bool IsName{false};
69         std::string TypeName;
70         int ArrayRank{0};
71
72         inline std::string GetRealType() const
73         {
74                 if (ArrayRank > 0)
75                         return "Array::Ptr";
76
77                 if (IsName)
78                         return "String";
79
80                 return TypeName;
81         }
82
83         inline std::string GetArgumentType() const
84         {
85                 std::string realType = GetRealType();
86
87                 if (realType == "bool" || realType == "double" || realType == "int")
88                         return realType;
89                 else
90                         return "const " + realType + "&";
91         }
92 };
93
94 struct Field
95 {
96         int Attributes{0};
97         FieldType Type;
98         std::string Name;
99         std::string AlternativeName;
100         std::string GetAccessor;
101         bool PureGetAccessor{false};
102         std::string SetAccessor;
103         bool PureSetAccessor{false};
104         std::string DefaultAccessor;
105         std::string TrackAccessor;
106         std::string NavigationName;
107         std::string NavigateAccessor;
108         bool PureNavigateAccessor{false};
109         int Priority{0};
110
111         inline std::string GetFriendlyName() const
112         {
113                 if (!AlternativeName.empty())
114                         return AlternativeName;
115
116                 bool cap = true;
117                 std::string name = Name;
118
119                 for (char& ch : name) {
120                         if (ch == '_') {
121                                 cap = true;
122                                 continue;
123                         }
124
125                         if (cap) {
126                                 ch = toupper(ch);
127                                 cap = false;
128                         }
129                 }
130
131                 name.erase(
132                         std::remove(name.begin(), name.end(), '_'),
133                         name.end()
134                         );
135
136                 /* TODO: figure out name */
137                 return name;
138         }
139 };
140
141 enum TypeAttribute
142 {
143         TAAbstract = 1,
144         TAVarArgConstructor = 2
145 };
146
147 struct Klass
148 {
149         std::string Name;
150         std::string Parent;
151         std::string TypeBase;
152         int Attributes;
153         std::vector<Field> Fields;
154         std::vector<std::string> LoadDependencies;
155         int ActivationPriority{0};
156 };
157
158 enum RuleAttribute
159 {
160         RARequired = 1
161 };
162
163 struct Rule
164 {
165         int Attributes;
166         bool IsName;
167         std::string Type;
168         std::string Pattern;
169
170         std::vector<Rule> Rules;
171 };
172
173 enum ValidatorType
174 {
175         ValidatorField,
176         ValidatorArray,
177         ValidatorDictionary
178 };
179
180 struct Validator
181 {
182         std::string Name;
183         std::vector<Rule> Rules;
184 };
185
186 class ClassCompiler
187 {
188 public:
189         ClassCompiler(std::string path, std::istream& input, std::ostream& oimpl, std::ostream& oheader);
190         ~ClassCompiler();
191
192         void Compile();
193
194         std::string GetPath() const;
195
196         void InitializeScanner();
197         void DestroyScanner();
198
199         void *GetScanner();
200
201         size_t ReadInput(char *buffer, size_t max_size);
202
203         void HandleInclude(const std::string& path, const ClassDebugInfo& locp);
204         void HandleAngleInclude(const std::string& path, const ClassDebugInfo& locp);
205         void HandleImplInclude(const std::string& path, const ClassDebugInfo& locp);
206         void HandleAngleImplInclude(const std::string& path, const ClassDebugInfo& locp);
207         void HandleClass(const Klass& klass, const ClassDebugInfo& locp);
208         void HandleValidator(const Validator& validator, const ClassDebugInfo& locp);
209         void HandleNamespaceBegin(const std::string& name, const ClassDebugInfo& locp);
210         void HandleNamespaceEnd(const ClassDebugInfo& locp);
211         void HandleCode(const std::string& code, const ClassDebugInfo& locp);
212         void HandleLibrary(const std::string& library, const ClassDebugInfo& locp);
213         void HandleMissingValidators();
214
215         void CodeGenValidator(const std::string& name, const std::string& klass, const std::vector<Rule>& rules, const std::string& field, const FieldType& fieldType, ValidatorType validatorType);
216         void CodeGenValidatorSubrules(const std::string& name, const std::string& klass, const std::vector<Rule>& rules);
217
218         static void CompileFile(const std::string& inputpath, const std::string& implpath,
219                 const std::string& headerpath);
220         static void CompileStream(const std::string& path, std::istream& input,
221                 std::ostream& oimpl, std::ostream& oheader);
222
223         static void OptimizeStructLayout(std::vector<Field>& fields);
224
225 private:
226         std::string m_Path;
227         std::istream& m_Input;
228         std::ostream& m_Impl;
229         std::ostream& m_Header;
230         void *m_Scanner;
231
232         std::string m_Library;
233
234         std::map<std::pair<std::string, std::string>, Field> m_MissingValidators;
235
236         static unsigned long SDBM(const std::string& str, size_t len);
237         static std::string BaseName(const std::string& path);
238         static std::string FileNameToGuardName(const std::string& path);
239 };
240
241 }
242
243 #endif /* CLASSCOMPILER_H */
244