]> granicus.if.org Git - icinga2/blob - tools/mkclass/classcompiler.hpp
Hide internal attributes in the API
[icinga2] / tools / mkclass / classcompiler.hpp
1 /******************************************************************************
2  * Icinga 2                                                                   *
3  * Copyright (C) 2012-2015 Icinga Development Team (http://www.icinga.org)    *
4  *                                                                            *
5  * This program is free software; you can redistribute it and/or              *
6  * modify it under the terms of the GNU General Public License                *
7  * as published by the Free Software Foundation; either version 2             *
8  * of the License, or (at your option) any later version.                     *
9  *                                                                            *
10  * This program is distributed in the hope that it will be useful,            *
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of             *
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the              *
13  * GNU General Public License for more details.                               *
14  *                                                                            *
15  * You should have received a copy of the GNU General Public License          *
16  * along with this program; if not, write to the Free Software Foundation     *
17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.             *
18  ******************************************************************************/
19
20 #ifndef CLASSCOMPILER_H
21 #define CLASSCOMPILER_H
22
23 #include <string>
24 #include <istream>
25 #include <vector>
26 #include <algorithm>
27 #include <map>
28
29 namespace icinga
30 {
31
32 struct ClassDebugInfo
33 {
34         std::string path;
35         int first_line;
36         int first_column;
37         int last_line;
38         int last_column;
39 };
40
41 enum FieldAccessorType
42 {
43         FTGet,
44         FTSet,
45         FTDefault,
46         FTTrack,
47         FTNavigate
48 };
49
50 struct FieldAccessor
51 {
52         FieldAccessorType Type;
53         std::string Accessor;
54         bool Pure;
55
56         FieldAccessor(FieldAccessorType type, const std::string& accessor, bool pure)
57                 : Type(type), Accessor(accessor), Pure(pure)
58         { }
59 };
60
61 /* keep this in sync with lib/base/type.hpp */
62 enum FieldAttribute
63 {
64         FAEphemeral = 1,
65         FAConfig = 2,
66         FAState = 4,
67         FAEnum = 8,
68         FAGetProtected = 16,
69         FASetProtected = 32,
70         FANoStorage = 64,
71         FALoadDependency = 128,
72         FARequired = 256,
73         FANavigation = 512,
74         FANoUserModify = 1024,
75         FANoUserView = 2048
76 };
77
78 struct FieldType
79 {
80         bool IsName;
81         std::string TypeName;
82         int ArrayRank;
83
84         FieldType(void)
85                 : IsName(false), ArrayRank(0)
86         { }
87
88         inline std::string GetRealType(void) const
89         {
90                 if (ArrayRank > 0)
91                         return "Array::Ptr";
92
93                 if (IsName)
94                         return "String";
95
96                 return TypeName;
97         }
98
99         inline std::string GetArgumentType(void) const
100         {
101                 std::string realType = GetRealType();
102
103                 if (realType == "bool" || realType == "double" || realType == "int")
104                         return realType;
105                 else
106                         return "const " + realType + "&";
107         }
108 };
109
110 struct Field
111 {
112         int Attributes;
113         FieldType Type;
114         std::string Name;
115         std::string AlternativeName;
116         std::string GetAccessor;
117         bool PureGetAccessor;
118         std::string SetAccessor;
119         bool PureSetAccessor;
120         std::string DefaultAccessor;
121         std::string TrackAccessor;
122         std::string NavigationName;
123         std::string NavigateAccessor;
124         bool PureNavigateAccessor;
125
126         Field(void)
127                 : Attributes(0), PureGetAccessor(false), PureSetAccessor(false), PureNavigateAccessor(false)
128         { }
129
130         inline std::string GetFriendlyName(void) const
131         {
132                 if (!AlternativeName.empty())
133                         return AlternativeName;
134
135                 bool cap = true;
136                 std::string name = Name;
137
138                 for (size_t i = 0; i < name.size(); i++) {
139                         if (name[i] == '_') {
140                                 cap = true;
141                                 continue;
142                         }
143
144                         if (cap) {
145                                 name[i] = toupper(name[i]);
146                                 cap = false;
147                         }
148                 }
149
150                 name.erase(
151                         std::remove(name.begin(), name.end(), '_'),
152                         name.end()
153                         );
154
155                 /* TODO: figure out name */
156                 return name;
157         }
158 };
159
160 enum TypeAttribute
161 {
162         TAAbstract = 1
163 };
164
165 struct Klass
166 {
167         std::string Name;
168         std::string Parent;
169         std::string TypeBase;
170         int Attributes;
171         std::vector<Field> Fields;
172         std::vector<std::string> LoadDependencies;
173 };
174
175 enum RuleAttribute
176 {
177         RARequired = 1
178 };
179
180 struct Rule
181 {
182         int Attributes;
183         bool IsName;
184         std::string Type;
185         std::string Pattern;
186
187         std::vector<Rule> Rules;
188 };
189
190 enum ValidatorType
191 {
192         ValidatorField,
193         ValidatorArray,
194         ValidatorDictionary
195 };
196
197 struct Validator
198 {
199         std::string Name;
200         std::vector<Rule> Rules;
201 };
202
203 class ClassCompiler
204 {
205 public:
206         ClassCompiler(const std::string& path, std::istream& input, std::ostream& oimpl, std::ostream& oheader);
207         ~ClassCompiler(void);
208
209         void Compile(void);
210
211         std::string GetPath(void) const;
212
213         void InitializeScanner(void);
214         void DestroyScanner(void);
215
216         void *GetScanner(void);
217
218         size_t ReadInput(char *buffer, size_t max_size);
219
220         void HandleInclude(const std::string& path, const ClassDebugInfo& locp);
221         void HandleAngleInclude(const std::string& path, const ClassDebugInfo& locp);
222         void HandleImplInclude(const std::string& path, const ClassDebugInfo& locp);
223         void HandleAngleImplInclude(const std::string& path, const ClassDebugInfo& locp);
224         void HandleClass(const Klass& klass, const ClassDebugInfo& locp);
225         void HandleValidator(const Validator& validator, const ClassDebugInfo& locp);
226         void HandleNamespaceBegin(const std::string& name, const ClassDebugInfo& locp);
227         void HandleNamespaceEnd(const ClassDebugInfo& locp);
228         void HandleCode(const std::string& code, const ClassDebugInfo& locp);
229         void HandleLibrary(const std::string& library, const ClassDebugInfo& locp);
230         void HandleMissingValidators(void);
231
232         void CodeGenValidator(const std::string& name, const std::string& klass, const std::vector<Rule>& rules, const std::string& field, const FieldType& fieldType, ValidatorType validatorType);
233         void CodeGenValidatorSubrules(const std::string& name, const std::string& klass, const std::vector<Rule>& rules);
234
235         static void CompileFile(const std::string& inputpath, const std::string& implpath,
236             const std::string& headerpath);
237         static void CompileStream(const std::string& path, std::istream& input,
238             std::ostream& oimpl, std::ostream& oheader);
239
240         static void OptimizeStructLayout(std::vector<Field>& fields);
241
242 private:
243         std::string m_Path;
244         std::istream& m_Input;
245         std::ostream& m_Impl;
246         std::ostream& m_Header;
247         void *m_Scanner;
248
249         std::string m_Library;
250
251         std::map<std::pair<std::string, std::string>, Field> m_MissingValidators;
252
253         static unsigned long SDBM(const std::string& str, size_t len);
254         static std::string BaseName(const std::string& path);
255         static std::string FileNameToGuardName(const std::string& path);
256 };
257
258 }
259
260 #endif /* CLASSCOMPILER_H */
261