1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: Parser of the API/interface XML files
4 // Author: Francesco Montorsi
7 // Copyright: (c) 2008 Francesco Montorsi
8 // Licence: wxWindows licence
9 /////////////////////////////////////////////////////////////////////////////
15 #include <wx/txtstrm.h>
16 #include <wx/dynarray.h>
17 #include <wx/xml/xml.h>
18 #include <wx/platinfo.h>
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:
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); }
41 // enable/disable logging
42 extern bool g_bLogEnabled
;
47 LogNull() { g_bLogEnabled
= false; }
48 ~LogNull() { g_bLogEnabled
= true; }
53 // ----------------------------------------------------------------------------
54 // Represents a type with or without const/static/ qualifier
55 // and with or without & and * operators
56 // ----------------------------------------------------------------------------
61 wxType(const wxString
& type
)
62 { SetTypeFromString(type
); }
64 void SetTypeFromString(const wxString
& t
);
65 wxString
GetAsString() const
67 wxString
GetAsCleanString() const
68 { return m_strTypeClean
; }
71 { return m_strType
.Contains("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("&"); }
79 bool operator==(const wxType
& m
) const;
80 bool operator!=(const wxType
& m
) const
81 { return !(*this == m
); }
87 m_strTypeClean
; // m_strType "cleaned" of its attributes
88 // (only for internal use)
91 extern wxType wxEmptyType
;
92 WX_DECLARE_OBJARRAY(wxType
, wxTypeArray
);
95 // ----------------------------------------------------------------------------
96 // Represents a type used as argument for some wxMethod
97 // ----------------------------------------------------------------------------
98 class wxArgumentType
: public wxType
102 wxArgumentType(const wxString
& type
, const wxString
& defVal
,
103 const wxString
& argName
= wxEmptyString
)
104 { SetTypeFromString(type
); SetDefaultValue(defVal
); m_strArgName
= argName
; }
106 void SetArgumentName(const wxString
& name
)
107 { m_strArgName
=name
.Strip(wxString::both
); }
108 wxString
GetArgumentName() const
109 { return m_strArgName
; }
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
; }
117 bool HasDefaultValue() const
118 { return !m_strDefaultValue
.IsEmpty(); }
120 bool operator==(const wxArgumentType
& m
) const;
121 bool operator!=(const wxArgumentType
& m
) const
122 { return !(*this == m
); }
125 wxString m_strDefaultValue
;
127 // this string may differ from m_strDefaultValue if there were
128 // preprocessor substitutions; can be wxEmptyString.
129 wxString m_strDefaultValueForCmp
;
131 wxString m_strArgName
; // this one only makes sense when this wxType is
132 // used as argument type (and not as return type)
136 extern wxArgumentType wxEmptyArgumentType
;
137 WX_DECLARE_OBJARRAY(wxArgumentType
, wxArgumentTypeArray
);
140 // ----------------------------------------------------------------------------
141 // Represents a single prototype of a class' member.
142 // ----------------------------------------------------------------------------
147 { m_bConst
=m_bVirtual
=m_bPureVirtual
=m_bStatic
=m_bDeprecated
=false;
148 m_nLine
=-1; m_nAvailability
=wxPORT_UNKNOWN
; }
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; }
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,
165 bool bDeprecated
= false) const;
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
175 int GetLocation() const
177 int GetAvailability() const
178 { return m_nAvailability
; }
182 bool IsStatic() const
183 { return m_bStatic
; }
184 bool IsVirtual() const
185 { return m_bVirtual
; }
186 bool IsPureVirtual() const
187 { return m_bPureVirtual
; }
191 { return m_retType
==wxEmptyType
&& !m_strName
.StartsWith("~"); }
193 { return m_retType
==wxEmptyType
&& m_strName
.StartsWith("~"); }
195 bool IsDeprecated() const
196 { return m_bDeprecated
; }
201 void SetReturnType(const wxType
& t
)
203 void SetName(const wxString
& name
)
205 void SetArgumentTypes(const wxArgumentTypeArray
& arr
)
207 void SetConst(bool c
= true)
209 void SetStatic(bool c
= true)
211 void SetVirtual(bool c
= true)
213 void SetPureVirtual(bool c
= true)
216 if (c
) m_bVirtual
=c
; // pure virtual => virtual
218 void SetDeprecated(bool c
= true)
220 void SetLocation(int lineNumber
)
221 { m_nLine
=lineNumber
; }
222 void SetAvailability(int nAvail
)
223 { m_nAvailability
=nAvail
; }
227 bool operator==(const wxMethod
&) const;
228 bool operator!=(const wxMethod
& m
) const
229 { return !(*this == m
); }
231 // this function works like operator== but tests everything:
235 // except for the method attributes (const,static,virtual,pureVirtual,deprecated)
236 bool MatchesExceptForAttributes(const wxMethod
& m
) const;
238 void Dump(wxTextOutputStream
& stream
) const;
243 wxArgumentTypeArray m_args
;
252 // m_nLine can be -1 if no location infos are available
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).
262 WX_DECLARE_OBJARRAY(wxMethod
, wxMethodArray
);
263 WX_DEFINE_ARRAY(const wxMethod
*, wxMethodPtrArray
);
266 // ----------------------------------------------------------------------------
267 // Represents a class of the wx API/interface.
268 // ----------------------------------------------------------------------------
273 wxClass(const wxString
& name
, const wxString
& headername
)
274 : m_strName(name
), m_strHeader(headername
) {}
279 void SetHeader(const wxString
& header
)
280 { m_strHeader
=header
; }
281 void SetName(const wxString
& name
)
283 void SetAvailability(int nAvail
)
284 { m_nAvailability
=nAvail
; }
290 { return !m_strName
.IsEmpty() && !m_methods
.IsEmpty(); }
292 bool IsValidCtorForThisClass(const wxMethod
& m
) const;
293 bool IsValidDtorForThisClass(const wxMethod
& m
) const;
295 wxString
GetName() const
296 { return m_strName
; }
297 wxString
GetHeader() const
298 { return m_strHeader
; }
299 wxString
GetNameWithoutTemplate() const;
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(); }
308 int GetAvailability() const
309 { return m_nAvailability
; }
313 void AddMethod(const wxMethod
& func
)
314 { m_methods
.Add(func
); }
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;
320 // returns an array of pointers to the overloaded methods with the
322 wxMethodPtrArray
FindMethodsNamed(const wxString
& m
) const;
324 // dumps all methods to the given output stream
325 void Dump(wxTextOutputStream
& stream
) const;
328 bool CheckConsistency() const;
332 wxString m_strHeader
;
333 wxMethodArray m_methods
;
335 // see the wxMethod::m_nAvailability field for more info
339 WX_DECLARE_OBJARRAY(wxClass
, wxClassArray
);
340 WX_DEFINE_ARRAY(const wxClass
*, wxClassPtrArray
);
344 // ----------------------------------------------------------------------------
346 // ----------------------------------------------------------------------------
352 const wxClass
* FindClass(const wxString
& classname
) const
354 for (unsigned int i
=0; i
<m_classes
.GetCount(); i
++)
355 if (m_classes
[i
].GetName() == classname
)
356 return &m_classes
[i
];
360 void Dump(const wxString
& filename
);
362 const wxClassArray
& GetClasses() const
363 { return m_classes
; }
365 unsigned int GetClassesCount() const
366 { return m_classes
.GetCount(); }
368 unsigned int GetMethodCount() const
370 unsigned int methods
= 0;
371 for (unsigned i
=0; i
< m_classes
.GetCount(); i
++)
372 methods
+= m_classes
[i
].GetMethodCount();
376 // pass a full-path header filename:
377 wxClassPtrArray
FindClassesDefinedIn(const wxString
& headerfile
) const;
380 { /*wxPrint(".");*/ }
382 bool CheckParseResults() const;
385 wxClassArray m_classes
;
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
,
395 WX_DECLARE_STRING_HASH_MAP( wxString
, wxStringHashMap
);
398 typedef std::basic_string
<char> stlString
;
399 typedef std::map
<unsigned long, stlString
> wxTypeIdHashMap
;
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
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();
417 bool Parse(const wxString
& filename
);
418 bool ParseMethod(const wxXmlNode
*p
,
419 const wxTypeIdHashMap
& types
,
422 wxPortId
GetInterfacePort() const
425 wxString
GetInterfacePortName() const
426 { return wxPlatformInfo::GetPortIdName(m_portId
, false); }
429 // the port for which the gcc XML was generated
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
441 wxXmlDoxygenInterface() {}
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.
451 bool Parse(const wxString
& filename
);
452 bool ParseCompoundDefinition(const wxString
& filename
);
453 bool ParseMethod(const wxXmlNode
*, wxMethod
&, wxString
& header
);
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
; }
461 wxStringHashMap m_preproc
;
466 #endif // _XMLPARSER_H_