]>
Commit | Line | Data |
---|---|---|
5934cda1 FM |
1 | ///////////////////////////////////////////////////////////////////////////// |
2 | // Name: xmlparser.h | |
3 | // Purpose: Parser of the API/interface XML files | |
4 | // Author: Francesco Montorsi | |
5 | // Created: 2008/03/17 | |
6 | // RCS-ID: $Id$ | |
7 | // Copyright: (c) 2008 Francesco Montorsi | |
8 | // Licence: wxWindows licence | |
9 | ///////////////////////////////////////////////////////////////////////////// | |
10 | ||
11 | ||
12 | #ifndef _XMLPARSER_H_ | |
13 | #define _XMLPARSER_H_ | |
14 | ||
15 | #include <wx/txtstrm.h> | |
16 | #include <wx/dynarray.h> | |
17 | #include <wx/xml/xml.h> | |
18 | ||
19 | // helper macros | |
20 | #define LogMessage(fmt, ...) { wxPrintf(fmt "\n", __VA_ARGS__); fflush(stdout); } | |
4168bc45 | 21 | #define LogWarning(fmt, ...) { wxPrintf(fmt "\n", __VA_ARGS__); fflush(stdout); } |
5934cda1 FM |
22 | #define LogError(fmt, ...) { wxPrintf("ERROR: " fmt "\n", __VA_ARGS__); fflush(stdout); } |
23 | #define wxPrint(str) { wxPrintf(str); fflush(stdout); } | |
24 | ||
25 | ||
26 | // ---------------------------------------------------------------------------- | |
27 | // Represents a type with or without const/static/ qualifier | |
28 | // and with or without & and * operators | |
29 | // ---------------------------------------------------------------------------- | |
30 | class wxType | |
31 | { | |
32 | public: | |
33 | wxType() {} | |
34 | wxType(const wxString& type) | |
f270e1dd | 35 | { SetTypeFromString(type); } |
5934cda1 | 36 | |
f270e1dd | 37 | void SetTypeFromString(const wxString& t); |
5934cda1 FM |
38 | wxString GetAsString() const |
39 | { return m_strType; } | |
40 | ||
5934cda1 FM |
41 | bool IsConst() const |
42 | { return m_strType.Contains("const"); } | |
43 | bool IsStatic() const | |
44 | { return m_strType.Contains("static"); } | |
45 | bool IsPointer() const | |
46 | { return m_strType.Contains("*"); } | |
47 | bool IsReference() const | |
48 | { return m_strType.Contains("&"); } | |
49 | ||
50 | bool operator==(const wxType& m) const; | |
51 | bool operator!=(const wxType& m) const | |
52 | { return !(*this == m); } | |
53 | ||
54 | bool IsOk() const; | |
55 | ||
56 | protected: | |
57 | wxString m_strType; | |
f270e1dd FM |
58 | |
59 | // utility for doing comparisons | |
60 | wxString GetClean() const; | |
5934cda1 FM |
61 | }; |
62 | ||
63 | extern wxType wxEmptyType; | |
64 | WX_DECLARE_OBJARRAY(wxType, wxTypeArray); | |
65 | ||
66 | ||
f270e1dd FM |
67 | // ---------------------------------------------------------------------------- |
68 | // Represents a type used as argument for some wxMethod | |
69 | // ---------------------------------------------------------------------------- | |
70 | class wxArgumentType : public wxType | |
71 | { | |
72 | public: | |
73 | wxArgumentType() {} | |
74 | wxArgumentType(const wxString& type, const wxString& defVal, | |
75 | const wxString& argName = wxEmptyString) | |
76 | { SetTypeFromString(type); SetDefaultValue(defVal); m_strArgName = argName; } | |
77 | ||
78 | void SetArgumentName(const wxString& name) | |
79 | { m_strArgName=name.Strip(wxString::both); } | |
80 | wxString GetArgumentName() const | |
81 | { return m_strArgName; } | |
82 | ||
83 | void SetDefaultValue(const wxString& defval); | |
84 | wxString GetDefaultValue() const | |
85 | { return m_strDefaultValue; } | |
86 | ||
203ba76a FM |
87 | bool HasDefaultValue() const |
88 | { return !m_strDefaultValue.IsEmpty(); } | |
89 | ||
f270e1dd FM |
90 | bool operator==(const wxArgumentType& m) const; |
91 | bool operator!=(const wxArgumentType& m) const | |
92 | { return !(*this == m); } | |
93 | ||
94 | protected: | |
95 | wxString m_strDefaultValue; | |
96 | wxString m_strArgName; // this one only makes sense when this wxType is | |
97 | // used as argument type (and not as return type) | |
98 | // and can be empty. | |
99 | }; | |
100 | ||
101 | extern wxArgumentType wxEmptyArgumentType; | |
102 | WX_DECLARE_OBJARRAY(wxArgumentType, wxArgumentTypeArray); | |
103 | ||
5934cda1 FM |
104 | |
105 | // ---------------------------------------------------------------------------- | |
106 | // Represents a single prototype of a class' member. | |
107 | // ---------------------------------------------------------------------------- | |
108 | class wxMethod | |
109 | { | |
110 | public: | |
0403e5dc | 111 | wxMethod() |
a7be99c8 | 112 | { m_bConst=m_bVirtual=m_bPureVirtual=m_bStatic=m_bDeprecated=false; m_nLine=-1; } |
0403e5dc | 113 | |
5934cda1 | 114 | wxMethod(const wxType& rettype, const wxString& name, |
f270e1dd | 115 | const wxArgumentTypeArray& arguments, |
5934cda1 FM |
116 | bool isConst, bool isStatic, bool isVirtual) |
117 | : m_retType(rettype), m_strName(name.Strip(wxString::both)), | |
118 | m_bConst(isConst), m_bStatic(isStatic), m_bVirtual(isVirtual) | |
f270e1dd | 119 | { SetArgumentTypes(arguments); m_nLine=-1; } |
5934cda1 FM |
120 | |
121 | ||
122 | public: // getters | |
123 | ||
f270e1dd | 124 | wxString GetAsString(bool bWithArgumentNames = true) const; |
5934cda1 FM |
125 | |
126 | // parser of the prototype: | |
127 | // all these functions return strings with spaces stripped | |
128 | wxType GetReturnType() const | |
129 | { return m_retType; } | |
130 | wxString GetName() const | |
131 | { return m_strName; } | |
f270e1dd | 132 | wxArgumentTypeArray GetArgumentTypes() const |
5934cda1 | 133 | { return m_args; } |
5934cda1 FM |
134 | int GetLocation() const |
135 | { return m_nLine; } | |
136 | ||
137 | bool IsConst() const | |
138 | { return m_bConst; } | |
139 | bool IsStatic() const | |
140 | { return m_bStatic; } | |
141 | bool IsVirtual() const | |
142 | { return m_bVirtual; } | |
a7be99c8 FM |
143 | bool IsPureVirtual() const |
144 | { return m_bPureVirtual; } | |
5934cda1 FM |
145 | |
146 | bool IsOk() const; | |
147 | bool IsCtor() const | |
148 | { return m_retType==wxEmptyType && !m_strName.StartsWith("~"); } | |
149 | bool IsDtor() const | |
150 | { return m_retType==wxEmptyType && m_strName.StartsWith("~"); } | |
151 | ||
0403e5dc FM |
152 | bool IsDeprecated() const |
153 | { return m_bDeprecated; } | |
154 | ||
5934cda1 FM |
155 | |
156 | public: // setters | |
157 | ||
158 | void SetReturnType(const wxType& t) | |
159 | { m_retType=t; } | |
160 | void SetName(const wxString& name) | |
161 | { m_strName=name; } | |
f270e1dd FM |
162 | void SetArgumentTypes(const wxArgumentTypeArray& arr) |
163 | { m_args=arr; } | |
5934cda1 FM |
164 | void SetConst(bool c = true) |
165 | { m_bConst=c; } | |
166 | void SetStatic(bool c = true) | |
167 | { m_bStatic=c; } | |
168 | void SetVirtual(bool c = true) | |
169 | { m_bVirtual=c; } | |
a7be99c8 | 170 | void SetPureVirtual(bool c = true) |
d5978709 FM |
171 | { |
172 | m_bPureVirtual=c; | |
173 | if (c) m_bVirtual=c; // pure virtual => virtual | |
174 | } | |
0403e5dc FM |
175 | void SetDeprecated(bool c = true) |
176 | { m_bDeprecated=c; } | |
5934cda1 FM |
177 | void SetLocation(int lineNumber) |
178 | { m_nLine=lineNumber; } | |
179 | ||
180 | public: // misc | |
181 | ||
182 | bool operator==(const wxMethod&) const; | |
183 | bool operator!=(const wxMethod& m) const | |
184 | { return !(*this == m); } | |
185 | ||
186 | void Dump(wxTextOutputStream& stream) const; | |
187 | ||
188 | protected: | |
189 | wxType m_retType; | |
190 | wxString m_strName; | |
f270e1dd | 191 | wxArgumentTypeArray m_args; |
5934cda1 FM |
192 | bool m_bConst; |
193 | bool m_bStatic; | |
194 | bool m_bVirtual; | |
a7be99c8 | 195 | bool m_bPureVirtual; |
0403e5dc | 196 | bool m_bDeprecated; |
5934cda1 FM |
197 | int m_nLine; |
198 | }; | |
199 | ||
200 | WX_DECLARE_OBJARRAY(wxMethod, wxMethodArray); | |
201 | WX_DEFINE_ARRAY(const wxMethod*, wxMethodPtrArray); | |
202 | ||
203 | ||
204 | // ---------------------------------------------------------------------------- | |
205 | // Represents a class of the wx API/interface. | |
206 | // ---------------------------------------------------------------------------- | |
207 | class wxClass | |
208 | { | |
209 | public: | |
210 | wxClass() {} | |
211 | wxClass(const wxString& name, const wxString& headername) | |
212 | : m_strName(name), m_strHeader(headername) {} | |
213 | ||
214 | void AddMethod(const wxMethod& func) | |
215 | { m_methods.Add(func); } | |
216 | ||
217 | void SetHeader(const wxString& header) | |
218 | { m_strHeader=header; } | |
219 | void SetName(const wxString& name) | |
220 | { m_strName=name; } | |
221 | wxString GetName() const | |
222 | { return m_strName; } | |
223 | wxString GetHeader() const | |
224 | { return m_strHeader; } | |
225 | wxString GetNameWithoutTemplate() const; | |
226 | ||
227 | bool IsOk() const | |
228 | { return !m_strName.IsEmpty() && !m_methods.IsEmpty(); } | |
229 | ||
230 | bool IsValidCtorForThisClass(const wxMethod& m) const; | |
231 | bool IsValidDtorForThisClass(const wxMethod& m) const; | |
232 | ||
233 | unsigned int GetMethodCount() const | |
234 | { return m_methods.GetCount(); } | |
235 | wxMethod& GetMethod(unsigned int n) const | |
236 | { return m_methods[n]; } | |
237 | wxMethod& GetLastMethod() const | |
238 | { return m_methods.Last(); } | |
239 | ||
240 | // returns a single result (the first, which is also the only | |
241 | // one if CheckConsistency() return true) | |
242 | const wxMethod* FindMethod(const wxMethod& m) const; | |
243 | ||
244 | // returns an array of pointers to the overloaded methods with the | |
245 | // same given name | |
246 | wxMethodPtrArray FindMethodNamed(const wxString& m) const; | |
247 | ||
248 | // dumps all methods to the given output stream | |
249 | void Dump(wxTextOutputStream& stream) const; | |
250 | ||
251 | // slow check | |
252 | bool CheckConsistency() const; | |
253 | ||
254 | protected: | |
255 | wxString m_strName; | |
256 | wxString m_strHeader; | |
257 | wxMethodArray m_methods; | |
258 | }; | |
259 | ||
260 | WX_DECLARE_OBJARRAY(wxClass, wxClassArray); | |
261 | WX_DEFINE_ARRAY(const wxClass*, wxClassPtrArray); | |
262 | ||
263 | ||
264 | ||
265 | // ---------------------------------------------------------------------------- | |
266 | // wxXmlInterface | |
267 | // ---------------------------------------------------------------------------- | |
268 | class wxXmlInterface | |
269 | { | |
270 | public: | |
271 | wxXmlInterface() {} | |
272 | ||
273 | const wxClass* FindClass(const wxString& classname) const | |
274 | { | |
275 | for (unsigned int i=0; i<m_classes.GetCount(); i++) | |
276 | if (m_classes[i].GetName() == classname) | |
277 | return &m_classes[i]; | |
278 | return NULL; | |
279 | } | |
280 | ||
281 | void Dump(const wxString& filename); | |
282 | ||
283 | const wxClassArray& GetClasses() const | |
284 | { return m_classes; } | |
285 | ||
286 | unsigned int GetClassesCount() const | |
287 | { return m_classes.GetCount(); } | |
288 | ||
289 | unsigned int GetMethodCount() const | |
290 | { | |
291 | unsigned int methods = 0; | |
292 | for (unsigned i=0; i < m_classes.GetCount(); i++) | |
293 | methods += m_classes[i].GetMethodCount(); | |
294 | return methods; | |
295 | } | |
296 | ||
297 | void ShowProgress() | |
298 | { /*wxPrint(".");*/ } | |
299 | ||
300 | bool CheckParseResults() const; | |
301 | ||
302 | protected: | |
303 | wxClassArray m_classes; | |
304 | }; | |
305 | ||
306 | #if 1 | |
74bda203 FM |
307 | // for wxTypeIdHashMap, keys == gccxml IDs and values == associated type strings |
308 | // e.g. key = "0x123f" and value = "const wxAboutDialogInfo&" | |
fdd4a897 FM |
309 | WX_DECLARE_HASH_MAP( unsigned long, wxString, |
310 | wxIntegerHash, wxIntegerEqual, | |
311 | wxTypeIdHashMap ); | |
5934cda1 FM |
312 | #else |
313 | #include <map> | |
314 | typedef std::basic_string<char> stlString; | |
fdd4a897 | 315 | typedef std::map<unsigned long, stlString> wxTypeIdHashMap; |
5934cda1 FM |
316 | #endif |
317 | ||
318 | ||
319 | // ---------------------------------------------------------------------------- | |
320 | // Represents the real interface of wxWidgets | |
321 | // Loads it from the XML produced by gccXML: http://www.gccxml.org | |
322 | // ---------------------------------------------------------------------------- | |
323 | class wxXmlGccInterface : public wxXmlInterface | |
324 | { | |
325 | public: | |
326 | wxXmlGccInterface() {} | |
327 | ||
328 | // !!SPEEDUP-TODO!! | |
329 | // Using wxXmlDocument::Load as is, all the types contained in the | |
330 | // the entire gccXML file are stored in memory while parsing; | |
331 | // however we are only interested to wx's own structs/classes/funcs/etc | |
332 | // so that we could use the file IDs to avoid loading stuff which does | |
333 | // not belong to wx. See the very end of the gccXML file: it contains | |
334 | // a set of <File> nodes referenced by all nodes above. | |
335 | ||
336 | bool Parse(const wxString& filename); | |
337 | bool ParseMethod(const wxXmlNode *p, | |
fdd4a897 | 338 | const wxTypeIdHashMap& types, |
5934cda1 FM |
339 | wxMethod& m); |
340 | }; | |
341 | ||
342 | ||
343 | // ---------------------------------------------------------------------------- | |
344 | // Represents the interface of the doxygen headers of wxWidgets | |
345 | // Loads it from the XML produced by Doxygen: http://www.doxygen.org | |
346 | // ---------------------------------------------------------------------------- | |
347 | class wxXmlDoxygenInterface : public wxXmlInterface | |
348 | { | |
349 | public: | |
350 | wxXmlDoxygenInterface() {} | |
351 | ||
352 | // !!SPEEDUP-TODO!! | |
353 | // Using wxXmlDocument::Load as is, the entire XML file is parsed | |
354 | // and an entire tree of wxXmlNodes is built in memory. | |
355 | // We need however only small portions of the Doxygen-generated XML: to speedup the | |
356 | // processing we could detach the expat callbacks when we detect the beginning of a | |
357 | // node we're not interested about, or just don't create a wxXmlNode for it! | |
358 | // This needs a modification of wxXml API. | |
359 | ||
360 | bool Parse(const wxString& filename); | |
361 | bool ParseCompoundDefinition(const wxString& filename); | |
362 | bool ParseMethod(const wxXmlNode*, wxMethod&, wxString& header); | |
363 | }; | |
364 | ||
365 | ||
366 | ||
367 | #endif // _XMLPARSER_H_ | |
368 |