]> git.saurik.com Git - wxWidgets.git/blob - utils/ifacecheck/src/xmlparser.h
build fix for non-PCH builds (thanks to buildbot emails ;))
[wxWidgets.git] / utils / ifacecheck / src / xmlparser.h
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 #include <wx/platinfo.h>
19
20 // helper macros
21 #define LogMessage(fmt, ...) { wxPrintf(fmt "\n", __VA_ARGS__); fflush(stdout); }
22 #define LogWarning(fmt, ...) { wxPrintf(fmt "\n", __VA_ARGS__); fflush(stdout); }
23 #define LogError(fmt, ...) { wxPrintf("ERROR: " fmt "\n", __VA_ARGS__); fflush(stdout); }
24 #define wxPrint(str) { wxPrintf(str); fflush(stdout); }
25
26
27 // ----------------------------------------------------------------------------
28 // Represents a type with or without const/static/ qualifier
29 // and with or without & and * operators
30 // ----------------------------------------------------------------------------
31 class wxType
32 {
33 public:
34 wxType() {}
35 wxType(const wxString& type)
36 { SetTypeFromString(type); }
37
38 void SetTypeFromString(const wxString& t);
39 wxString GetAsString() const
40 { return m_strType; }
41
42 bool IsConst() const
43 { return m_strType.Contains("const"); }
44 bool IsStatic() const
45 { return m_strType.Contains("static"); }
46 bool IsPointer() const
47 { return m_strType.Contains("*"); }
48 bool IsReference() const
49 { return m_strType.Contains("&"); }
50
51 bool operator==(const wxType& m) const;
52 bool operator!=(const wxType& m) const
53 { return !(*this == m); }
54
55 bool IsOk() const;
56
57 protected:
58 wxString m_strType;
59
60 // utility for doing comparisons
61 wxString GetClean() const;
62 };
63
64 extern wxType wxEmptyType;
65 WX_DECLARE_OBJARRAY(wxType, wxTypeArray);
66
67
68 // ----------------------------------------------------------------------------
69 // Represents a type used as argument for some wxMethod
70 // ----------------------------------------------------------------------------
71 class wxArgumentType : public wxType
72 {
73 public:
74 wxArgumentType() {}
75 wxArgumentType(const wxString& type, const wxString& defVal,
76 const wxString& argName = wxEmptyString)
77 { SetTypeFromString(type); SetDefaultValue(defVal); m_strArgName = argName; }
78
79 void SetArgumentName(const wxString& name)
80 { m_strArgName=name.Strip(wxString::both); }
81 wxString GetArgumentName() const
82 { return m_strArgName; }
83
84 void SetDefaultValue(const wxString& defval, const wxString& defvalForCmp = wxEmptyString);
85 wxString GetDefaultValue() const
86 { return m_strDefaultValue; }
87
88 bool HasDefaultValue() const
89 { return !m_strDefaultValue.IsEmpty(); }
90
91 bool operator==(const wxArgumentType& m) const;
92 bool operator!=(const wxArgumentType& m) const
93 { return !(*this == m); }
94
95 protected:
96 wxString m_strDefaultValue;
97
98 // this string may differ from m_strDefaultValue if there were
99 // preprocessor substitutions; can be wxEmptyString.
100 wxString m_strDefaultValueForCmp;
101
102 wxString m_strArgName; // this one only makes sense when this wxType is
103 // used as argument type (and not as return type)
104 // and can be empty.
105 };
106
107 extern wxArgumentType wxEmptyArgumentType;
108 WX_DECLARE_OBJARRAY(wxArgumentType, wxArgumentTypeArray);
109
110
111 // ----------------------------------------------------------------------------
112 // Represents a single prototype of a class' member.
113 // ----------------------------------------------------------------------------
114 class wxMethod
115 {
116 public:
117 wxMethod()
118 { m_bConst=m_bVirtual=m_bPureVirtual=m_bStatic=m_bDeprecated=false;
119 m_nLine=-1; m_nAvailability=wxPORT_UNKNOWN; }
120
121 wxMethod(const wxType& rettype, const wxString& name,
122 const wxArgumentTypeArray& arguments,
123 bool isConst, bool isStatic, bool isVirtual)
124 : m_retType(rettype), m_strName(name.Strip(wxString::both)),
125 m_bConst(isConst), m_bStatic(isStatic), m_bVirtual(isVirtual)
126 { SetArgumentTypes(arguments); m_nLine=-1; }
127
128
129 public: // getters
130
131 wxString GetAsString(bool bWithArgumentNames = true) const;
132
133 // parser of the prototype:
134 // all these functions return strings with spaces stripped
135 wxType GetReturnType() const
136 { return m_retType; }
137 wxString GetName() const
138 { return m_strName; }
139 wxArgumentTypeArray GetArgumentTypes() const
140 { return m_args; }
141 int GetLocation() const
142 { return m_nLine; }
143 int GetAvailability() const
144 { return m_nAvailability; }
145
146 bool IsConst() const
147 { return m_bConst; }
148 bool IsStatic() const
149 { return m_bStatic; }
150 bool IsVirtual() const
151 { return m_bVirtual; }
152 bool IsPureVirtual() const
153 { return m_bPureVirtual; }
154
155 bool IsOk() const;
156 bool IsCtor() const
157 { return m_retType==wxEmptyType && !m_strName.StartsWith("~"); }
158 bool IsDtor() const
159 { return m_retType==wxEmptyType && m_strName.StartsWith("~"); }
160
161 bool IsDeprecated() const
162 { return m_bDeprecated; }
163
164
165 public: // setters
166
167 void SetReturnType(const wxType& t)
168 { m_retType=t; }
169 void SetName(const wxString& name)
170 { m_strName=name; }
171 void SetArgumentTypes(const wxArgumentTypeArray& arr)
172 { m_args=arr; }
173 void SetConst(bool c = true)
174 { m_bConst=c; }
175 void SetStatic(bool c = true)
176 { m_bStatic=c; }
177 void SetVirtual(bool c = true)
178 { m_bVirtual=c; }
179 void SetPureVirtual(bool c = true)
180 {
181 m_bPureVirtual=c;
182 if (c) m_bVirtual=c; // pure virtual => virtual
183 }
184 void SetDeprecated(bool c = true)
185 { m_bDeprecated=c; }
186 void SetLocation(int lineNumber)
187 { m_nLine=lineNumber; }
188 void SetAvailability(int nAvail)
189 { m_nAvailability=nAvail; }
190
191 public: // misc
192
193 bool operator==(const wxMethod&) const;
194 bool operator!=(const wxMethod& m) const
195 { return !(*this == m); }
196
197 void Dump(wxTextOutputStream& stream) const;
198
199 protected:
200 wxType m_retType;
201 wxString m_strName;
202 wxArgumentTypeArray m_args;
203
204 // misc attributes:
205 bool m_bConst;
206 bool m_bStatic;
207 bool m_bVirtual;
208 bool m_bPureVirtual;
209 bool m_bDeprecated;
210
211 // m_nLine can be -1 if no location infos are available
212 int m_nLine;
213
214 // this is a combination of wxPORT_* flags (see wxPortId) or wxPORT_UNKNOWN
215 // if this method should be available for all wxWidgets ports.
216 // NOTE: this is not used for comparing wxMethod objects
217 // (gccXML never gives this kind of info).
218 int m_nAvailability;
219 };
220
221 WX_DECLARE_OBJARRAY(wxMethod, wxMethodArray);
222 WX_DEFINE_ARRAY(const wxMethod*, wxMethodPtrArray);
223
224
225 // ----------------------------------------------------------------------------
226 // Represents a class of the wx API/interface.
227 // ----------------------------------------------------------------------------
228 class wxClass
229 {
230 public:
231 wxClass() {}
232 wxClass(const wxString& name, const wxString& headername)
233 : m_strName(name), m_strHeader(headername) {}
234
235
236 public: // setters
237
238 void SetHeader(const wxString& header)
239 { m_strHeader=header; }
240 void SetName(const wxString& name)
241 { m_strName=name; }
242 void SetAvailability(int nAvail)
243 { m_nAvailability=nAvail; }
244
245
246 public: // getters
247
248 bool IsOk() const
249 { return !m_strName.IsEmpty() && !m_methods.IsEmpty(); }
250
251 bool IsValidCtorForThisClass(const wxMethod& m) const;
252 bool IsValidDtorForThisClass(const wxMethod& m) const;
253
254 wxString GetName() const
255 { return m_strName; }
256 wxString GetHeader() const
257 { return m_strHeader; }
258 wxString GetNameWithoutTemplate() const;
259
260 unsigned int GetMethodCount() const
261 { return m_methods.GetCount(); }
262 wxMethod& GetMethod(unsigned int n) const
263 { return m_methods[n]; }
264 wxMethod& GetLastMethod() const
265 { return m_methods.Last(); }
266
267 int GetAvailability() const
268 { return m_nAvailability; }
269
270 public: // misc
271
272 void AddMethod(const wxMethod& func)
273 { m_methods.Add(func); }
274
275 // returns a single result (the first, which is also the only
276 // one if CheckConsistency() return true)
277 const wxMethod* FindMethod(const wxMethod& m) const;
278
279 // returns an array of pointers to the overloaded methods with the
280 // same given name
281 wxMethodPtrArray FindMethodNamed(const wxString& m) const;
282
283 // dumps all methods to the given output stream
284 void Dump(wxTextOutputStream& stream) const;
285
286 // slow check
287 bool CheckConsistency() const;
288
289 protected:
290 wxString m_strName;
291 wxString m_strHeader;
292 wxMethodArray m_methods;
293
294 // see the wxMethod::m_nAvailability field for more info
295 int m_nAvailability;
296 };
297
298 WX_DECLARE_OBJARRAY(wxClass, wxClassArray);
299 WX_DEFINE_ARRAY(const wxClass*, wxClassPtrArray);
300
301
302
303 // ----------------------------------------------------------------------------
304 // wxXmlInterface
305 // ----------------------------------------------------------------------------
306 class wxXmlInterface
307 {
308 public:
309 wxXmlInterface() {}
310
311 const wxClass* FindClass(const wxString& classname) const
312 {
313 for (unsigned int i=0; i<m_classes.GetCount(); i++)
314 if (m_classes[i].GetName() == classname)
315 return &m_classes[i];
316 return NULL;
317 }
318
319 void Dump(const wxString& filename);
320
321 const wxClassArray& GetClasses() const
322 { return m_classes; }
323
324 unsigned int GetClassesCount() const
325 { return m_classes.GetCount(); }
326
327 unsigned int GetMethodCount() const
328 {
329 unsigned int methods = 0;
330 for (unsigned i=0; i < m_classes.GetCount(); i++)
331 methods += m_classes[i].GetMethodCount();
332 return methods;
333 }
334
335 // pass a full-path header filename:
336 wxClassPtrArray FindClassesDefinedIn(const wxString& headerfile) const;
337
338 void ShowProgress()
339 { /*wxPrint(".");*/ }
340
341 bool CheckParseResults() const;
342
343 protected:
344 wxClassArray m_classes;
345 };
346
347 #if 1
348 // for wxTypeIdHashMap, keys == gccxml IDs and values == associated type strings
349 // e.g. key = "0x123f" and value = "const wxAboutDialogInfo&"
350 WX_DECLARE_HASH_MAP( unsigned long, wxString,
351 wxIntegerHash, wxIntegerEqual,
352 wxTypeIdHashMap );
353
354 WX_DECLARE_STRING_HASH_MAP( wxString, wxStringHashMap );
355 #else
356 #include <map>
357 typedef std::basic_string<char> stlString;
358 typedef std::map<unsigned long, stlString> wxTypeIdHashMap;
359 #endif
360
361
362 // ----------------------------------------------------------------------------
363 // Represents the real interface of wxWidgets
364 // Loads it from the XML produced by gccXML: http://www.gccxml.org
365 // ----------------------------------------------------------------------------
366 class wxXmlGccInterface : public wxXmlInterface
367 {
368 public:
369 wxXmlGccInterface()
370 {
371 // FIXME: we should retrieve this from the XML file!
372 // here we suppose the XML was created for the currently-running port
373 m_portId = wxPlatformInfo::Get().GetPortId();
374 }
375
376 bool Parse(const wxString& filename);
377 bool ParseMethod(const wxXmlNode *p,
378 const wxTypeIdHashMap& types,
379 wxMethod& m);
380
381 wxPortId GetInterfacePort() const
382 { return m_portId; }
383
384 wxString GetInterfacePortName() const
385 { return wxPlatformInfo::GetPortIdName(m_portId, false); }
386
387 protected:
388 // the port for which the gcc XML was generated
389 wxPortId m_portId;
390 };
391
392
393 // ----------------------------------------------------------------------------
394 // Represents the interface of the doxygen headers of wxWidgets
395 // Loads it from the XML produced by Doxygen: http://www.doxygen.org
396 // ----------------------------------------------------------------------------
397 class wxXmlDoxygenInterface : public wxXmlInterface
398 {
399 public:
400 wxXmlDoxygenInterface() {}
401
402 // !!SPEEDUP-TODO!!
403 // Using wxXmlDocument::Load as is, the entire XML file is parsed
404 // and an entire tree of wxXmlNodes is built in memory.
405 // We need however only small portions of the Doxygen-generated XML: to speedup the
406 // processing we could detach the expat callbacks when we detect the beginning of a
407 // node we're not interested about, or just don't create a wxXmlNode for it!
408 // This needs a modification of wxXml API.
409
410 bool Parse(const wxString& filename);
411 bool ParseCompoundDefinition(const wxString& filename);
412 bool ParseMethod(const wxXmlNode*, wxMethod&, wxString& header);
413
414 // this class can take advantage of the preprocessor output to give
415 // a minor number of false positive warnings in the final comparison
416 void AddPreprocessorValue(const wxString& name, const wxString& val)
417 { m_preproc[name]=val; }
418
419 protected:
420 wxStringHashMap m_preproc;
421 };
422
423
424
425 #endif // _XMLPARSER_H_
426