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>
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); }
27 // ----------------------------------------------------------------------------
28 // Represents a type with or without const/static/ qualifier
29 // and with or without & and * operators
30 // ----------------------------------------------------------------------------
35 wxType(const wxString
& type
)
36 { SetTypeFromString(type
); }
38 void SetTypeFromString(const wxString
& t
);
39 wxString
GetAsString() const
43 { return m_strType
.Contains("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("&"); }
51 bool operator==(const wxType
& m
) const;
52 bool operator!=(const wxType
& m
) const
53 { return !(*this == m
); }
60 // utility for doing comparisons
61 wxString
GetClean() const;
64 extern wxType wxEmptyType
;
65 WX_DECLARE_OBJARRAY(wxType
, wxTypeArray
);
68 // ----------------------------------------------------------------------------
69 // Represents a type used as argument for some wxMethod
70 // ----------------------------------------------------------------------------
71 class wxArgumentType
: public wxType
75 wxArgumentType(const wxString
& type
, const wxString
& defVal
,
76 const wxString
& argName
= wxEmptyString
)
77 { SetTypeFromString(type
); SetDefaultValue(defVal
); m_strArgName
= argName
; }
79 void SetArgumentName(const wxString
& name
)
80 { m_strArgName
=name
.Strip(wxString::both
); }
81 wxString
GetArgumentName() const
82 { return m_strArgName
; }
84 void SetDefaultValue(const wxString
& defval
, const wxString
& defvalForCmp
= wxEmptyString
);
85 wxString
GetDefaultValue() const
86 { return m_strDefaultValue
; }
88 bool HasDefaultValue() const
89 { return !m_strDefaultValue
.IsEmpty(); }
91 bool operator==(const wxArgumentType
& m
) const;
92 bool operator!=(const wxArgumentType
& m
) const
93 { return !(*this == m
); }
96 wxString m_strDefaultValue
;
98 // this string may differ from m_strDefaultValue if there were
99 // preprocessor substitutions; can be wxEmptyString.
100 wxString m_strDefaultValueForCmp
;
102 wxString m_strArgName
; // this one only makes sense when this wxType is
103 // used as argument type (and not as return type)
107 extern wxArgumentType wxEmptyArgumentType
;
108 WX_DECLARE_OBJARRAY(wxArgumentType
, wxArgumentTypeArray
);
111 // ----------------------------------------------------------------------------
112 // Represents a single prototype of a class' member.
113 // ----------------------------------------------------------------------------
118 { m_bConst
=m_bVirtual
=m_bPureVirtual
=m_bStatic
=m_bDeprecated
=false;
119 m_nLine
=-1; m_nAvailability
=wxPORT_UNKNOWN
; }
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; }
131 wxString
GetAsString(bool bWithArgumentNames
= true) const;
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
141 int GetLocation() const
143 int GetAvailability() const
144 { return m_nAvailability
; }
148 bool IsStatic() const
149 { return m_bStatic
; }
150 bool IsVirtual() const
151 { return m_bVirtual
; }
152 bool IsPureVirtual() const
153 { return m_bPureVirtual
; }
157 { return m_retType
==wxEmptyType
&& !m_strName
.StartsWith("~"); }
159 { return m_retType
==wxEmptyType
&& m_strName
.StartsWith("~"); }
161 bool IsDeprecated() const
162 { return m_bDeprecated
; }
167 void SetReturnType(const wxType
& t
)
169 void SetName(const wxString
& name
)
171 void SetArgumentTypes(const wxArgumentTypeArray
& arr
)
173 void SetConst(bool c
= true)
175 void SetStatic(bool c
= true)
177 void SetVirtual(bool c
= true)
179 void SetPureVirtual(bool c
= true)
182 if (c
) m_bVirtual
=c
; // pure virtual => virtual
184 void SetDeprecated(bool c
= true)
186 void SetLocation(int lineNumber
)
187 { m_nLine
=lineNumber
; }
188 void SetAvailability(int nAvail
)
189 { m_nAvailability
=nAvail
; }
193 bool operator==(const wxMethod
&) const;
194 bool operator!=(const wxMethod
& m
) const
195 { return !(*this == m
); }
197 void Dump(wxTextOutputStream
& stream
) const;
202 wxArgumentTypeArray m_args
;
211 // m_nLine can be -1 if no location infos are available
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).
221 WX_DECLARE_OBJARRAY(wxMethod
, wxMethodArray
);
222 WX_DEFINE_ARRAY(const wxMethod
*, wxMethodPtrArray
);
225 // ----------------------------------------------------------------------------
226 // Represents a class of the wx API/interface.
227 // ----------------------------------------------------------------------------
232 wxClass(const wxString
& name
, const wxString
& headername
)
233 : m_strName(name
), m_strHeader(headername
) {}
238 void SetHeader(const wxString
& header
)
239 { m_strHeader
=header
; }
240 void SetName(const wxString
& name
)
242 void SetAvailability(int nAvail
)
243 { m_nAvailability
=nAvail
; }
249 { return !m_strName
.IsEmpty() && !m_methods
.IsEmpty(); }
251 bool IsValidCtorForThisClass(const wxMethod
& m
) const;
252 bool IsValidDtorForThisClass(const wxMethod
& m
) const;
254 wxString
GetName() const
255 { return m_strName
; }
256 wxString
GetHeader() const
257 { return m_strHeader
; }
258 wxString
GetNameWithoutTemplate() const;
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(); }
267 int GetAvailability() const
268 { return m_nAvailability
; }
272 void AddMethod(const wxMethod
& func
)
273 { m_methods
.Add(func
); }
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;
279 // returns an array of pointers to the overloaded methods with the
281 wxMethodPtrArray
FindMethodNamed(const wxString
& m
) const;
283 // dumps all methods to the given output stream
284 void Dump(wxTextOutputStream
& stream
) const;
287 bool CheckConsistency() const;
291 wxString m_strHeader
;
292 wxMethodArray m_methods
;
294 // see the wxMethod::m_nAvailability field for more info
298 WX_DECLARE_OBJARRAY(wxClass
, wxClassArray
);
299 WX_DEFINE_ARRAY(const wxClass
*, wxClassPtrArray
);
303 // ----------------------------------------------------------------------------
305 // ----------------------------------------------------------------------------
311 const wxClass
* FindClass(const wxString
& classname
) const
313 for (unsigned int i
=0; i
<m_classes
.GetCount(); i
++)
314 if (m_classes
[i
].GetName() == classname
)
315 return &m_classes
[i
];
319 void Dump(const wxString
& filename
);
321 const wxClassArray
& GetClasses() const
322 { return m_classes
; }
324 unsigned int GetClassesCount() const
325 { return m_classes
.GetCount(); }
327 unsigned int GetMethodCount() const
329 unsigned int methods
= 0;
330 for (unsigned i
=0; i
< m_classes
.GetCount(); i
++)
331 methods
+= m_classes
[i
].GetMethodCount();
335 // pass a full-path header filename:
336 wxClassPtrArray
FindClassesDefinedIn(const wxString
& headerfile
) const;
339 { /*wxPrint(".");*/ }
341 bool CheckParseResults() const;
344 wxClassArray m_classes
;
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
,
354 WX_DECLARE_STRING_HASH_MAP( wxString
, wxStringHashMap
);
357 typedef std::basic_string
<char> stlString
;
358 typedef std::map
<unsigned long, stlString
> wxTypeIdHashMap
;
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
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();
376 bool Parse(const wxString
& filename
);
377 bool ParseMethod(const wxXmlNode
*p
,
378 const wxTypeIdHashMap
& types
,
381 wxPortId
GetInterfacePort() const
384 wxString
GetInterfacePortName() const
385 { return wxPlatformInfo::GetPortIdName(m_portId
, false); }
388 // the port for which the gcc XML was generated
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
400 wxXmlDoxygenInterface() {}
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.
410 bool Parse(const wxString
& filename
);
411 bool ParseCompoundDefinition(const wxString
& filename
);
412 bool ParseMethod(const wxXmlNode
*, wxMethod
&, wxString
& header
);
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
; }
420 wxStringHashMap m_preproc
;
425 #endif // _XMLPARSER_H_