]> git.saurik.com Git - wxWidgets.git/blame - utils/ifacecheck/src/xmlparser.h
Removed dummy wxFont == operator implementation (IIRC was needed to compile with...
[wxWidgets.git] / utils / ifacecheck / src / xmlparser.h
CommitLineData
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>
d2367a0f 18#include <wx/platinfo.h>
5934cda1 19
97f0dbd6
FM
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:
723de43b 30 // ...fix description...
97f0dbd6
FM
31*/
32
33
34
5934cda1 35// helper macros
97f0dbd6
FM
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); }}
5934cda1
FM
39#define wxPrint(str) { wxPrintf(str); fflush(stdout); }
40
97f0dbd6
FM
41// enable/disable logging
42extern bool g_bLogEnabled;
43
44class LogNull
45{
46public:
47 LogNull() { g_bLogEnabled = false; }
48 ~LogNull() { g_bLogEnabled = true; }
49};
50
51
5934cda1
FM
52
53// ----------------------------------------------------------------------------
54// Represents a type with or without const/static/ qualifier
55// and with or without & and * operators
56// ----------------------------------------------------------------------------
57class wxType
58{
59public:
60 wxType() {}
61 wxType(const wxString& type)
f270e1dd 62 { SetTypeFromString(type); }
5934cda1 63
f270e1dd 64 void SetTypeFromString(const wxString& t);
5934cda1
FM
65 wxString GetAsString() const
66 { return m_strType; }
2cb3a02f
FM
67
68 // returns this type _without_ any decoration,
69 // including the & (which indicates this is a reference),
70 // the * (which indicates this is a pointer), etc.
97f0dbd6
FM
71 wxString GetAsCleanString() const
72 { return m_strTypeClean; }
5934cda1 73
5934cda1
FM
74 bool IsConst() const
75 { return m_strType.Contains("const"); }
76 bool IsStatic() const
77 { return m_strType.Contains("static"); }
78 bool IsPointer() const
79 { return m_strType.Contains("*"); }
80 bool IsReference() const
81 { return m_strType.Contains("&"); }
82
83 bool operator==(const wxType& m) const;
84 bool operator!=(const wxType& m) const
85 { return !(*this == m); }
86
87 bool IsOk() const;
88
89protected:
658d9804
FM
90 wxString m_strType,
91 m_strTypeClean; // m_strType "cleaned" of its attributes
92 // (only for internal use)
5934cda1
FM
93};
94
95extern wxType wxEmptyType;
96WX_DECLARE_OBJARRAY(wxType, wxTypeArray);
97
98
f270e1dd
FM
99// ----------------------------------------------------------------------------
100// Represents a type used as argument for some wxMethod
101// ----------------------------------------------------------------------------
102class wxArgumentType : public wxType
103{
104public:
105 wxArgumentType() {}
106 wxArgumentType(const wxString& type, const wxString& defVal,
107 const wxString& argName = wxEmptyString)
108 { SetTypeFromString(type); SetDefaultValue(defVal); m_strArgName = argName; }
109
110 void SetArgumentName(const wxString& name)
111 { m_strArgName=name.Strip(wxString::both); }
112 wxString GetArgumentName() const
113 { return m_strArgName; }
114
2cb3a02f
FM
115 void SetDefaultValue(const wxString& defval,
116 const wxString& defvalForCmp = wxEmptyString);
f270e1dd
FM
117 wxString GetDefaultValue() const
118 { return m_strDefaultValue; }
2cb3a02f
FM
119
120 // returns the default value used for comparisons
97f0dbd6 121 wxString GetDefaultCleanValue() const
2cb3a02f 122 { return m_strDefaultValueForCmp; }
f270e1dd 123
203ba76a
FM
124 bool HasDefaultValue() const
125 { return !m_strDefaultValue.IsEmpty(); }
126
f270e1dd
FM
127 bool operator==(const wxArgumentType& m) const;
128 bool operator!=(const wxArgumentType& m) const
129 { return !(*this == m); }
130
131protected:
132 wxString m_strDefaultValue;
5570107a
FM
133
134 // this string may differ from m_strDefaultValue if there were
2cb3a02f
FM
135 // preprocessor substitutions or other "replacements" done to
136 // avoid false errors.
5570107a
FM
137 wxString m_strDefaultValueForCmp;
138
2cb3a02f
FM
139 // the argument name
140 wxString m_strArgName;
f270e1dd
FM
141};
142
143extern wxArgumentType wxEmptyArgumentType;
144WX_DECLARE_OBJARRAY(wxArgumentType, wxArgumentTypeArray);
145
5934cda1 146
8cd22478
FM
147enum wxMethodAccessSpecifier
148{
149 wxMAS_PUBLIC,
150 wxMAS_PROTECTED,
151 wxMAS_PRIVATE
152};
153
5934cda1
FM
154// ----------------------------------------------------------------------------
155// Represents a single prototype of a class' member.
156// ----------------------------------------------------------------------------
157class wxMethod
158{
159public:
0403e5dc 160 wxMethod()
03d4f7b9 161 { m_bConst=m_bVirtual=m_bPureVirtual=m_bStatic=m_bDeprecated=false;
8cd22478 162 m_nLine=-1; m_nAvailability=wxPORT_UNKNOWN; m_access=wxMAS_PUBLIC; }
0403e5dc 163
5934cda1 164 wxMethod(const wxType& rettype, const wxString& name,
f270e1dd 165 const wxArgumentTypeArray& arguments,
5934cda1
FM
166 bool isConst, bool isStatic, bool isVirtual)
167 : m_retType(rettype), m_strName(name.Strip(wxString::both)),
168 m_bConst(isConst), m_bStatic(isStatic), m_bVirtual(isVirtual)
f270e1dd 169 { SetArgumentTypes(arguments); m_nLine=-1; }
5934cda1
FM
170
171
172public: // getters
173
97f0dbd6 174 // bWithArgumentNames = output argument names?
8cd22478 175 // bCleanDefaultValues = output clean argument default values?
97f0dbd6 176 // bDeprecated = output [deprecated] next to deprecated methods?
8cd22478
FM
177 // bAccessSpec = output [public], [protected] or [private] next to method?
178 //
179 // TODO: convert to readable flags this set of bools
97f0dbd6 180 wxString GetAsString(bool bWithArgumentNames = true,
8cd22478
FM
181 bool bCleanDefaultValues = false,
182 bool bDeprecated = false,
183 bool bAccessSpec = false) const;
5934cda1
FM
184
185 // parser of the prototype:
186 // all these functions return strings with spaces stripped
187 wxType GetReturnType() const
188 { return m_retType; }
189 wxString GetName() const
190 { return m_strName; }
f3998820
FM
191 const wxArgumentTypeArray& GetArgumentTypes() const
192 { return m_args; }
193 wxArgumentTypeArray& GetArgumentTypes()
5934cda1 194 { return m_args; }
5934cda1
FM
195 int GetLocation() const
196 { return m_nLine; }
03d4f7b9
FM
197 int GetAvailability() const
198 { return m_nAvailability; }
8cd22478
FM
199 wxMethodAccessSpecifier GetAccessSpecifier() const
200 { return m_access; }
5934cda1
FM
201
202 bool IsConst() const
203 { return m_bConst; }
204 bool IsStatic() const
205 { return m_bStatic; }
206 bool IsVirtual() const
207 { return m_bVirtual; }
a7be99c8
FM
208 bool IsPureVirtual() const
209 { return m_bPureVirtual; }
5934cda1
FM
210
211 bool IsOk() const;
212 bool IsCtor() const
213 { return m_retType==wxEmptyType && !m_strName.StartsWith("~"); }
214 bool IsDtor() const
215 { return m_retType==wxEmptyType && m_strName.StartsWith("~"); }
216
0403e5dc
FM
217 bool IsDeprecated() const
218 { return m_bDeprecated; }
219
5934cda1
FM
220
221public: // setters
222
223 void SetReturnType(const wxType& t)
224 { m_retType=t; }
225 void SetName(const wxString& name)
226 { m_strName=name; }
f270e1dd
FM
227 void SetArgumentTypes(const wxArgumentTypeArray& arr)
228 { m_args=arr; }
5934cda1
FM
229 void SetConst(bool c = true)
230 { m_bConst=c; }
231 void SetStatic(bool c = true)
232 { m_bStatic=c; }
233 void SetVirtual(bool c = true)
234 { m_bVirtual=c; }
a7be99c8 235 void SetPureVirtual(bool c = true)
d5978709
FM
236 {
237 m_bPureVirtual=c;
238 if (c) m_bVirtual=c; // pure virtual => virtual
239 }
0403e5dc
FM
240 void SetDeprecated(bool c = true)
241 { m_bDeprecated=c; }
5934cda1
FM
242 void SetLocation(int lineNumber)
243 { m_nLine=lineNumber; }
03d4f7b9
FM
244 void SetAvailability(int nAvail)
245 { m_nAvailability=nAvail; }
8cd22478
FM
246 void SetAccessSpecifier(wxMethodAccessSpecifier spec)
247 { m_access=spec; }
5934cda1
FM
248
249public: // misc
250
251 bool operator==(const wxMethod&) const;
252 bool operator!=(const wxMethod& m) const
253 { return !(*this == m); }
254
97f0dbd6
FM
255 // this function works like operator== but tests everything:
256 // - method name
257 // - return type
258 // - argument types
259 // except for the method attributes (const,static,virtual,pureVirtual,deprecated)
260 bool MatchesExceptForAttributes(const wxMethod& m) const;
261
f3998820
FM
262 // returns true if this is a ctor which has default values for all its
263 // argument, thus is able to act also as default ctor
264 bool ActsAsDefaultCtor() const;
265
5934cda1
FM
266 void Dump(wxTextOutputStream& stream) const;
267
268protected:
269 wxType m_retType;
270 wxString m_strName;
f270e1dd 271 wxArgumentTypeArray m_args;
03d4f7b9
FM
272
273 // misc attributes:
5934cda1
FM
274 bool m_bConst;
275 bool m_bStatic;
276 bool m_bVirtual;
a7be99c8 277 bool m_bPureVirtual;
0403e5dc 278 bool m_bDeprecated;
03d4f7b9
FM
279
280 // m_nLine can be -1 if no location infos are available
5934cda1 281 int m_nLine;
03d4f7b9
FM
282
283 // this is a combination of wxPORT_* flags (see wxPortId) or wxPORT_UNKNOWN
284 // if this method should be available for all wxWidgets ports.
285 // NOTE: this is not used for comparing wxMethod objects
286 // (gccXML never gives this kind of info).
287 int m_nAvailability;
8cd22478
FM
288
289 // the access specifier for this method
290 wxMethodAccessSpecifier m_access;
5934cda1
FM
291};
292
293WX_DECLARE_OBJARRAY(wxMethod, wxMethodArray);
294WX_DEFINE_ARRAY(const wxMethod*, wxMethodPtrArray);
295
296
673ae68a
FM
297// we need wxClassPtrArray to be defined _before_ wxClass itself,
298// since wxClass uses wxClassPtrArray.
299class wxClass;
300WX_DEFINE_ARRAY(const wxClass*, wxClassPtrArray);
301
302class wxXmlInterface;
303
304
5934cda1
FM
305// ----------------------------------------------------------------------------
306// Represents a class of the wx API/interface.
307// ----------------------------------------------------------------------------
308class wxClass
309{
310public:
311 wxClass() {}
312 wxClass(const wxString& name, const wxString& headername)
313 : m_strName(name), m_strHeader(headername) {}
314
03d4f7b9
FM
315
316public: // setters
5934cda1
FM
317
318 void SetHeader(const wxString& header)
319 { m_strHeader=header; }
320 void SetName(const wxString& name)
321 { m_strName=name; }
03d4f7b9
FM
322 void SetAvailability(int nAvail)
323 { m_nAvailability=nAvail; }
673ae68a
FM
324 void SetParent(unsigned int k, const wxString& name)
325 { m_parents[k]=name; }
03d4f7b9
FM
326
327public: // getters
5934cda1
FM
328
329 bool IsOk() const
330 { return !m_strName.IsEmpty() && !m_methods.IsEmpty(); }
331
332 bool IsValidCtorForThisClass(const wxMethod& m) const;
333 bool IsValidDtorForThisClass(const wxMethod& m) const;
334
03d4f7b9
FM
335 wxString GetName() const
336 { return m_strName; }
337 wxString GetHeader() const
338 { return m_strHeader; }
339 wxString GetNameWithoutTemplate() const;
340
5934cda1
FM
341 unsigned int GetMethodCount() const
342 { return m_methods.GetCount(); }
343 wxMethod& GetMethod(unsigned int n) const
344 { return m_methods[n]; }
345 wxMethod& GetLastMethod() const
346 { return m_methods.Last(); }
347
03d4f7b9
FM
348 int GetAvailability() const
349 { return m_nAvailability; }
350
673ae68a
FM
351 //const wxClass *GetParent(unsigned int i) const
352 const wxString& GetParent(unsigned int i) const
353 { return m_parents[i]; }
354 unsigned int GetParentCount() const
355 { return m_parents.GetCount(); }
356
03d4f7b9
FM
357public: // misc
358
359 void AddMethod(const wxMethod& func)
360 { m_methods.Add(func); }
361
673ae68a
FM
362 void AddParent(const wxString& parent)//wxClass* parent)
363 { m_parents.Add(parent); }
364
5934cda1
FM
365 // returns a single result (the first, which is also the only
366 // one if CheckConsistency() return true)
367 const wxMethod* FindMethod(const wxMethod& m) const;
368
673ae68a
FM
369 // like FindMethod() but this one searches also recursively in
370 // the parents of this class.
371 const wxMethod* RecursiveUpwardFindMethod(const wxMethod& m,
372 const wxXmlInterface* allclasses) const;
373
5934cda1
FM
374 // returns an array of pointers to the overloaded methods with the
375 // same given name
673ae68a
FM
376 wxMethodPtrArray FindMethodsNamed(const wxString& name) const;
377
378 // like FindMethodsNamed() but this one searches also recursively in
379 // the parents of this class.
380 wxMethodPtrArray RecursiveUpwardFindMethodsNamed(const wxString& name,
381 const wxXmlInterface* allclasses) const;
5934cda1
FM
382
383 // dumps all methods to the given output stream
384 void Dump(wxTextOutputStream& stream) const;
385
386 // slow check
387 bool CheckConsistency() const;
388
389protected:
390 wxString m_strName;
391 wxString m_strHeader;
392 wxMethodArray m_methods;
03d4f7b9 393
673ae68a
FM
394 // name of the base classes: we store the names and not the pointers
395 // because this makes _much_ easier the parsing process!
396 // (basically because when parsing class X which derives from Y,
397 // we may have not parsed yet class Y!)
398 wxArrayString m_parents;
399
03d4f7b9
FM
400 // see the wxMethod::m_nAvailability field for more info
401 int m_nAvailability;
5934cda1
FM
402};
403
404WX_DECLARE_OBJARRAY(wxClass, wxClassArray);
5934cda1
FM
405
406
407
408// ----------------------------------------------------------------------------
409// wxXmlInterface
410// ----------------------------------------------------------------------------
411class wxXmlInterface
412{
413public:
414 wxXmlInterface() {}
415
416 const wxClass* FindClass(const wxString& classname) const
417 {
418 for (unsigned int i=0; i<m_classes.GetCount(); i++)
419 if (m_classes[i].GetName() == classname)
420 return &m_classes[i];
421 return NULL;
422 }
423
424 void Dump(const wxString& filename);
425
426 const wxClassArray& GetClasses() const
427 { return m_classes; }
428
429 unsigned int GetClassesCount() const
430 { return m_classes.GetCount(); }
431
432 unsigned int GetMethodCount() const
433 {
434 unsigned int methods = 0;
435 for (unsigned i=0; i < m_classes.GetCount(); i++)
436 methods += m_classes[i].GetMethodCount();
437 return methods;
438 }
439
7fbadf87
FM
440 // pass a full-path header filename:
441 wxClassPtrArray FindClassesDefinedIn(const wxString& headerfile) const;
442
5934cda1
FM
443 void ShowProgress()
444 { /*wxPrint(".");*/ }
445
446 bool CheckParseResults() const;
447
448protected:
449 wxClassArray m_classes;
450};
451
452#if 1
74bda203
FM
453// for wxTypeIdHashMap, keys == gccxml IDs and values == associated type strings
454// e.g. key = "0x123f" and value = "const wxAboutDialogInfo&"
fdd4a897
FM
455WX_DECLARE_HASH_MAP( unsigned long, wxString,
456 wxIntegerHash, wxIntegerEqual,
457 wxTypeIdHashMap );
5570107a
FM
458
459WX_DECLARE_STRING_HASH_MAP( wxString, wxStringHashMap );
5934cda1
FM
460#else
461#include <map>
462typedef std::basic_string<char> stlString;
fdd4a897 463typedef std::map<unsigned long, stlString> wxTypeIdHashMap;
5934cda1
FM
464#endif
465
466
467// ----------------------------------------------------------------------------
468// Represents the real interface of wxWidgets
469// Loads it from the XML produced by gccXML: http://www.gccxml.org
470// ----------------------------------------------------------------------------
471class wxXmlGccInterface : public wxXmlInterface
472{
473public:
03d4f7b9
FM
474 wxXmlGccInterface()
475 {
476 // FIXME: we should retrieve this from the XML file!
477 // here we suppose the XML was created for the currently-running port
478 m_portId = wxPlatformInfo::Get().GetPortId();
479 }
5934cda1 480
5934cda1
FM
481 bool Parse(const wxString& filename);
482 bool ParseMethod(const wxXmlNode *p,
fdd4a897 483 const wxTypeIdHashMap& types,
5934cda1 484 wxMethod& m);
03d4f7b9
FM
485
486 wxPortId GetInterfacePort() const
487 { return m_portId; }
488
489 wxString GetInterfacePortName() const
490 { return wxPlatformInfo::GetPortIdName(m_portId, false); }
491
492protected:
493 // the port for which the gcc XML was generated
494 wxPortId m_portId;
5934cda1
FM
495};
496
497
498// ----------------------------------------------------------------------------
499// Represents the interface of the doxygen headers of wxWidgets
500// Loads it from the XML produced by Doxygen: http://www.doxygen.org
501// ----------------------------------------------------------------------------
502class wxXmlDoxygenInterface : public wxXmlInterface
503{
504public:
505 wxXmlDoxygenInterface() {}
506
507 // !!SPEEDUP-TODO!!
508 // Using wxXmlDocument::Load as is, the entire XML file is parsed
509 // and an entire tree of wxXmlNodes is built in memory.
510 // We need however only small portions of the Doxygen-generated XML: to speedup the
511 // processing we could detach the expat callbacks when we detect the beginning of a
512 // node we're not interested about, or just don't create a wxXmlNode for it!
513 // This needs a modification of wxXml API.
514
515 bool Parse(const wxString& filename);
516 bool ParseCompoundDefinition(const wxString& filename);
517 bool ParseMethod(const wxXmlNode*, wxMethod&, wxString& header);
5570107a
FM
518
519 // this class can take advantage of the preprocessor output to give
520 // a minor number of false positive warnings in the final comparison
521 void AddPreprocessorValue(const wxString& name, const wxString& val)
522 { m_preproc[name]=val; }
523
524protected:
525 wxStringHashMap m_preproc;
5934cda1
FM
526};
527
528
529
530#endif // _XMLPARSER_H_
531