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