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