]>
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); } | |
21 | #define LogWarning(fmt, ...) { wxPrintf("WARNING: " fmt "\n", __VA_ARGS__); fflush(stdout); } | |
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) | |
35 | { SetFromString(type); } | |
36 | ||
37 | void SetFromString(const wxString& t); | |
38 | wxString GetAsString() const | |
39 | { return m_strType; } | |
40 | ||
41 | wxString GetClean() const; | |
42 | ||
43 | bool IsConst() const | |
44 | { return m_strType.Contains("const"); } | |
45 | bool IsStatic() const | |
46 | { return m_strType.Contains("static"); } | |
47 | bool IsPointer() const | |
48 | { return m_strType.Contains("*"); } | |
49 | bool IsReference() const | |
50 | { return m_strType.Contains("&"); } | |
51 | ||
52 | bool operator==(const wxType& m) const; | |
53 | bool operator!=(const wxType& m) const | |
54 | { return !(*this == m); } | |
55 | ||
56 | bool IsOk() const; | |
57 | ||
58 | protected: | |
59 | wxString m_strType; | |
60 | }; | |
61 | ||
62 | extern wxType wxEmptyType; | |
63 | WX_DECLARE_OBJARRAY(wxType, wxTypeArray); | |
64 | ||
65 | ||
66 | ||
67 | // ---------------------------------------------------------------------------- | |
68 | // Represents a single prototype of a class' member. | |
69 | // ---------------------------------------------------------------------------- | |
70 | class wxMethod | |
71 | { | |
72 | public: | |
73 | wxMethod() { m_bConst=m_bVirtual=m_bStatic=false; m_nLine=-1; } | |
74 | wxMethod(const wxType& rettype, const wxString& name, | |
75 | const wxTypeArray& arguments, const wxArrayString& defaults, | |
76 | bool isConst, bool isStatic, bool isVirtual) | |
77 | : m_retType(rettype), m_strName(name.Strip(wxString::both)), | |
78 | m_bConst(isConst), m_bStatic(isStatic), m_bVirtual(isVirtual) | |
79 | { SetArgumentTypes(arguments,defaults); m_nLine=-1; } | |
80 | ||
81 | ||
82 | public: // getters | |
83 | ||
84 | //void SetFromString(const wxString& proto); | |
85 | wxString GetAsString() const; | |
86 | ||
87 | // parser of the prototype: | |
88 | // all these functions return strings with spaces stripped | |
89 | wxType GetReturnType() const | |
90 | { return m_retType; } | |
91 | wxString GetName() const | |
92 | { return m_strName; } | |
93 | wxTypeArray GetArgumentTypes() const | |
94 | { return m_args; } | |
95 | wxArrayString GetArgumentDefaults() const | |
96 | { return m_argDefaults; } | |
97 | int GetLocation() const | |
98 | { return m_nLine; } | |
99 | ||
100 | bool IsConst() const | |
101 | { return m_bConst; } | |
102 | bool IsStatic() const | |
103 | { return m_bStatic; } | |
104 | bool IsVirtual() const | |
105 | { return m_bVirtual; } | |
106 | ||
107 | bool IsOk() const; | |
108 | bool IsCtor() const | |
109 | { return m_retType==wxEmptyType && !m_strName.StartsWith("~"); } | |
110 | bool IsDtor() const | |
111 | { return m_retType==wxEmptyType && m_strName.StartsWith("~"); } | |
112 | ||
113 | ||
114 | public: // setters | |
115 | ||
116 | void SetReturnType(const wxType& t) | |
117 | { m_retType=t; } | |
118 | void SetName(const wxString& name) | |
119 | { m_strName=name; } | |
120 | void SetArgumentTypes(const wxTypeArray& arr, const wxArrayString& defaults); | |
121 | void SetConst(bool c = true) | |
122 | { m_bConst=c; } | |
123 | void SetStatic(bool c = true) | |
124 | { m_bStatic=c; } | |
125 | void SetVirtual(bool c = true) | |
126 | { m_bVirtual=c; } | |
127 | void SetLocation(int lineNumber) | |
128 | { m_nLine=lineNumber; } | |
129 | ||
130 | public: // misc | |
131 | ||
132 | bool operator==(const wxMethod&) const; | |
133 | bool operator!=(const wxMethod& m) const | |
134 | { return !(*this == m); } | |
135 | ||
136 | void Dump(wxTextOutputStream& stream) const; | |
137 | ||
138 | protected: | |
139 | wxType m_retType; | |
140 | wxString m_strName; | |
141 | wxTypeArray m_args; | |
142 | wxArrayString m_argDefaults; | |
143 | bool m_bConst; | |
144 | bool m_bStatic; | |
145 | bool m_bVirtual; | |
146 | int m_nLine; | |
147 | }; | |
148 | ||
149 | WX_DECLARE_OBJARRAY(wxMethod, wxMethodArray); | |
150 | WX_DEFINE_ARRAY(const wxMethod*, wxMethodPtrArray); | |
151 | ||
152 | ||
153 | // ---------------------------------------------------------------------------- | |
154 | // Represents a class of the wx API/interface. | |
155 | // ---------------------------------------------------------------------------- | |
156 | class wxClass | |
157 | { | |
158 | public: | |
159 | wxClass() {} | |
160 | wxClass(const wxString& name, const wxString& headername) | |
161 | : m_strName(name), m_strHeader(headername) {} | |
162 | ||
163 | void AddMethod(const wxMethod& func) | |
164 | { m_methods.Add(func); } | |
165 | ||
166 | void SetHeader(const wxString& header) | |
167 | { m_strHeader=header; } | |
168 | void SetName(const wxString& name) | |
169 | { m_strName=name; } | |
170 | wxString GetName() const | |
171 | { return m_strName; } | |
172 | wxString GetHeader() const | |
173 | { return m_strHeader; } | |
174 | wxString GetNameWithoutTemplate() const; | |
175 | ||
176 | bool IsOk() const | |
177 | { return !m_strName.IsEmpty() && !m_methods.IsEmpty(); } | |
178 | ||
179 | bool IsValidCtorForThisClass(const wxMethod& m) const; | |
180 | bool IsValidDtorForThisClass(const wxMethod& m) const; | |
181 | ||
182 | unsigned int GetMethodCount() const | |
183 | { return m_methods.GetCount(); } | |
184 | wxMethod& GetMethod(unsigned int n) const | |
185 | { return m_methods[n]; } | |
186 | wxMethod& GetLastMethod() const | |
187 | { return m_methods.Last(); } | |
188 | ||
189 | // returns a single result (the first, which is also the only | |
190 | // one if CheckConsistency() return true) | |
191 | const wxMethod* FindMethod(const wxMethod& m) const; | |
192 | ||
193 | // returns an array of pointers to the overloaded methods with the | |
194 | // same given name | |
195 | wxMethodPtrArray FindMethodNamed(const wxString& m) const; | |
196 | ||
197 | // dumps all methods to the given output stream | |
198 | void Dump(wxTextOutputStream& stream) const; | |
199 | ||
200 | // slow check | |
201 | bool CheckConsistency() const; | |
202 | ||
203 | protected: | |
204 | wxString m_strName; | |
205 | wxString m_strHeader; | |
206 | wxMethodArray m_methods; | |
207 | }; | |
208 | ||
209 | WX_DECLARE_OBJARRAY(wxClass, wxClassArray); | |
210 | WX_DEFINE_ARRAY(const wxClass*, wxClassPtrArray); | |
211 | ||
212 | ||
213 | ||
214 | // ---------------------------------------------------------------------------- | |
215 | // wxXmlInterface | |
216 | // ---------------------------------------------------------------------------- | |
217 | class wxXmlInterface | |
218 | { | |
219 | public: | |
220 | wxXmlInterface() {} | |
221 | ||
222 | const wxClass* FindClass(const wxString& classname) const | |
223 | { | |
224 | for (unsigned int i=0; i<m_classes.GetCount(); i++) | |
225 | if (m_classes[i].GetName() == classname) | |
226 | return &m_classes[i]; | |
227 | return NULL; | |
228 | } | |
229 | ||
230 | void Dump(const wxString& filename); | |
231 | ||
232 | const wxClassArray& GetClasses() const | |
233 | { return m_classes; } | |
234 | ||
235 | unsigned int GetClassesCount() const | |
236 | { return m_classes.GetCount(); } | |
237 | ||
238 | unsigned int GetMethodCount() const | |
239 | { | |
240 | unsigned int methods = 0; | |
241 | for (unsigned i=0; i < m_classes.GetCount(); i++) | |
242 | methods += m_classes[i].GetMethodCount(); | |
243 | return methods; | |
244 | } | |
245 | ||
246 | void ShowProgress() | |
247 | { /*wxPrint(".");*/ } | |
248 | ||
249 | bool CheckParseResults() const; | |
250 | ||
251 | protected: | |
252 | wxClassArray m_classes; | |
253 | }; | |
254 | ||
255 | #if 1 | |
256 | WX_DECLARE_STRING_HASH_MAP( wxString, wxStringHashMap ); | |
257 | #else | |
258 | #include <map> | |
259 | typedef std::basic_string<char> stlString; | |
260 | typedef std::map<stlString, stlString> wxStringHashMap; | |
261 | #endif | |
262 | ||
263 | ||
264 | // ---------------------------------------------------------------------------- | |
265 | // Represents the real interface of wxWidgets | |
266 | // Loads it from the XML produced by gccXML: http://www.gccxml.org | |
267 | // ---------------------------------------------------------------------------- | |
268 | class wxXmlGccInterface : public wxXmlInterface | |
269 | { | |
270 | public: | |
271 | wxXmlGccInterface() {} | |
272 | ||
273 | // !!SPEEDUP-TODO!! | |
274 | // Using wxXmlDocument::Load as is, all the types contained in the | |
275 | // the entire gccXML file are stored in memory while parsing; | |
276 | // however we are only interested to wx's own structs/classes/funcs/etc | |
277 | // so that we could use the file IDs to avoid loading stuff which does | |
278 | // not belong to wx. See the very end of the gccXML file: it contains | |
279 | // a set of <File> nodes referenced by all nodes above. | |
280 | ||
281 | bool Parse(const wxString& filename); | |
282 | bool ParseMethod(const wxXmlNode *p, | |
283 | const wxStringHashMap& types, | |
284 | wxMethod& m); | |
285 | }; | |
286 | ||
287 | ||
288 | // ---------------------------------------------------------------------------- | |
289 | // Represents the interface of the doxygen headers of wxWidgets | |
290 | // Loads it from the XML produced by Doxygen: http://www.doxygen.org | |
291 | // ---------------------------------------------------------------------------- | |
292 | class wxXmlDoxygenInterface : public wxXmlInterface | |
293 | { | |
294 | public: | |
295 | wxXmlDoxygenInterface() {} | |
296 | ||
297 | // !!SPEEDUP-TODO!! | |
298 | // Using wxXmlDocument::Load as is, the entire XML file is parsed | |
299 | // and an entire tree of wxXmlNodes is built in memory. | |
300 | // We need however only small portions of the Doxygen-generated XML: to speedup the | |
301 | // processing we could detach the expat callbacks when we detect the beginning of a | |
302 | // node we're not interested about, or just don't create a wxXmlNode for it! | |
303 | // This needs a modification of wxXml API. | |
304 | ||
305 | bool Parse(const wxString& filename); | |
306 | bool ParseCompoundDefinition(const wxString& filename); | |
307 | bool ParseMethod(const wxXmlNode*, wxMethod&, wxString& header); | |
308 | }; | |
309 | ||
310 | ||
311 | ||
312 | #endif // _XMLPARSER_H_ | |
313 |