This keyword is not expanded by Git which means it's not replaced with the correct revision value in the releases made using git-based scripts and it's confusing to have lines with unexpanded "$Id$" in the released files. As expanding them with Git is not that simple (it could be done with git archive and export-subst attribute) and there are not many benefits in having them in the first place, just remove all these lines. If nothing else, this will make an eventual transition to Git simpler. Closes #14487. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@74602 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
521 lines
16 KiB
C++
521 lines
16 KiB
C++
/////////////////////////////////////////////////////////////////////////////
|
|
// Name: xmlparser.h
|
|
// Purpose: Parser of the API/interface XML files
|
|
// Author: Francesco Montorsi
|
|
// Created: 2008/03/17
|
|
// Copyright: (c) 2008 Francesco Montorsi
|
|
// Licence: wxWindows licence
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
#ifndef _XMLPARSER_H_
|
|
#define _XMLPARSER_H_
|
|
|
|
#include <wx/txtstrm.h>
|
|
#include <wx/dynarray.h>
|
|
#include <wx/xml/xml.h>
|
|
#include <wx/platinfo.h>
|
|
#include <wx/log.h>
|
|
|
|
|
|
/*
|
|
IMPORTANT
|
|
=========
|
|
|
|
Any fix aimed to reduce "false positives" which involves
|
|
references to a specific wxWidgets class is marked in
|
|
ifacecheck sources with the string:
|
|
|
|
// ADHOC-FIX:
|
|
// ...fix description...
|
|
*/
|
|
|
|
// NOTE: all messages in this way are printed on the stderr
|
|
//#define wxLogWarning wxLogMessage
|
|
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// Represents a type with or without const/static/ qualifier
|
|
// and with or without & and * operators
|
|
// ----------------------------------------------------------------------------
|
|
class wxType
|
|
{
|
|
public:
|
|
wxType() {}
|
|
wxType(const wxString& type)
|
|
{ SetTypeFromString(type); }
|
|
|
|
void SetTypeFromString(const wxString& t);
|
|
wxString GetAsString() const
|
|
{ return m_strType; }
|
|
|
|
// returns this type _without_ any decoration,
|
|
// including the & (which indicates this is a reference),
|
|
// the * (which indicates this is a pointer), etc.
|
|
wxString GetAsCleanString() const
|
|
{ return m_strTypeClean; }
|
|
|
|
bool IsConst() const
|
|
{ return m_strType.Contains("const"); }
|
|
bool IsStatic() const
|
|
{ return m_strType.Contains("static"); }
|
|
bool IsPointer() const
|
|
{ return m_strType.Contains("*"); }
|
|
bool IsReference() const
|
|
{ return m_strType.Contains("&"); }
|
|
|
|
bool operator==(const wxType& m) const;
|
|
bool operator!=(const wxType& m) const
|
|
{ return !(*this == m); }
|
|
|
|
bool IsOk() const;
|
|
|
|
protected:
|
|
wxString m_strType,
|
|
m_strTypeClean; // m_strType "cleaned" of its attributes
|
|
// (only for internal use)
|
|
};
|
|
|
|
extern wxType wxEmptyType;
|
|
WX_DECLARE_OBJARRAY(wxType, wxTypeArray);
|
|
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// Represents a type used as argument for some wxMethod
|
|
// ----------------------------------------------------------------------------
|
|
class wxArgumentType : public wxType
|
|
{
|
|
public:
|
|
wxArgumentType() {}
|
|
wxArgumentType(const wxString& type, const wxString& defVal,
|
|
const wxString& argName = wxEmptyString)
|
|
{ SetTypeFromString(type); SetDefaultValue(defVal); m_strArgName = argName; }
|
|
|
|
void SetArgumentName(const wxString& name)
|
|
{ m_strArgName=name.Strip(wxString::both); }
|
|
wxString GetArgumentName() const
|
|
{ return m_strArgName; }
|
|
|
|
void SetDefaultValue(const wxString& defval,
|
|
const wxString& defvalForCmp = wxEmptyString);
|
|
wxString GetDefaultValue() const
|
|
{ return m_strDefaultValue; }
|
|
|
|
// returns the default value used for comparisons
|
|
wxString GetDefaultCleanValue() const
|
|
{ return m_strDefaultValueForCmp; }
|
|
|
|
bool HasDefaultValue() const
|
|
{ return !m_strDefaultValue.IsEmpty(); }
|
|
|
|
bool operator==(const wxArgumentType& m) const;
|
|
bool operator!=(const wxArgumentType& m) const
|
|
{ return !(*this == m); }
|
|
|
|
protected:
|
|
wxString m_strDefaultValue;
|
|
|
|
// this string may differ from m_strDefaultValue if there were
|
|
// preprocessor substitutions or other "replacements" done to
|
|
// avoid false errors.
|
|
wxString m_strDefaultValueForCmp;
|
|
|
|
// the argument name
|
|
wxString m_strArgName;
|
|
};
|
|
|
|
extern wxArgumentType wxEmptyArgumentType;
|
|
WX_DECLARE_OBJARRAY(wxArgumentType, wxArgumentTypeArray);
|
|
|
|
|
|
enum wxMethodAccessSpecifier
|
|
{
|
|
wxMAS_PUBLIC,
|
|
wxMAS_PROTECTED,
|
|
wxMAS_PRIVATE
|
|
};
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// Represents a single prototype of a class' member.
|
|
// ----------------------------------------------------------------------------
|
|
class wxMethod
|
|
{
|
|
public:
|
|
wxMethod()
|
|
{ m_bConst=m_bVirtual=m_bPureVirtual=m_bStatic=m_bDeprecated=false;
|
|
m_nLine=-1; m_nAvailability=wxPORT_UNKNOWN; m_access=wxMAS_PUBLIC; }
|
|
|
|
wxMethod(const wxType& rettype, const wxString& name,
|
|
const wxArgumentTypeArray& arguments,
|
|
bool isConst, bool isStatic, bool isVirtual)
|
|
: m_retType(rettype), m_strName(name.Strip(wxString::both)),
|
|
m_bConst(isConst), m_bStatic(isStatic), m_bVirtual(isVirtual)
|
|
{ SetArgumentTypes(arguments); m_nLine=-1; }
|
|
|
|
|
|
public: // getters
|
|
|
|
// bWithArgumentNames = output argument names?
|
|
// bCleanDefaultValues = output clean argument default values?
|
|
// bDeprecated = output [deprecated] next to deprecated methods?
|
|
// bAccessSpec = output [public], [protected] or [private] next to method?
|
|
//
|
|
// TODO: convert to readable flags this set of bools
|
|
wxString GetAsString(bool bWithArgumentNames = true,
|
|
bool bCleanDefaultValues = false,
|
|
bool bDeprecated = false,
|
|
bool bAccessSpec = false) const;
|
|
|
|
// parser of the prototype:
|
|
// all these functions return strings with spaces stripped
|
|
wxType GetReturnType() const
|
|
{ return m_retType; }
|
|
wxString GetName() const
|
|
{ return m_strName; }
|
|
const wxArgumentTypeArray& GetArgumentTypes() const
|
|
{ return m_args; }
|
|
wxArgumentTypeArray& GetArgumentTypes()
|
|
{ return m_args; }
|
|
int GetLocation() const
|
|
{ return m_nLine; }
|
|
int GetAvailability() const
|
|
{ return m_nAvailability; }
|
|
wxMethodAccessSpecifier GetAccessSpecifier() const
|
|
{ return m_access; }
|
|
|
|
bool IsConst() const
|
|
{ return m_bConst; }
|
|
bool IsStatic() const
|
|
{ return m_bStatic; }
|
|
bool IsVirtual() const
|
|
{ return m_bVirtual; }
|
|
bool IsPureVirtual() const
|
|
{ return m_bPureVirtual; }
|
|
|
|
bool IsOk() const;
|
|
bool IsCtor() const
|
|
{ return m_retType==wxEmptyType && !m_strName.StartsWith("~"); }
|
|
bool IsDtor() const
|
|
{ return m_retType==wxEmptyType && m_strName.StartsWith("~"); }
|
|
bool IsOperator() const
|
|
{ return m_strName.StartsWith("operator"); }
|
|
|
|
bool IsDeprecated() const
|
|
{ return m_bDeprecated; }
|
|
|
|
|
|
|
|
public: // setters
|
|
|
|
void SetReturnType(const wxType& t)
|
|
{ m_retType=t; }
|
|
void SetName(const wxString& name)
|
|
{ m_strName=name; }
|
|
void SetArgumentTypes(const wxArgumentTypeArray& arr)
|
|
{ m_args=arr; }
|
|
void SetConst(bool c = true)
|
|
{ m_bConst=c; }
|
|
void SetStatic(bool c = true)
|
|
{ m_bStatic=c; }
|
|
void SetVirtual(bool c = true)
|
|
{ m_bVirtual=c; }
|
|
void SetPureVirtual(bool c = true)
|
|
{
|
|
m_bPureVirtual=c;
|
|
if (c) m_bVirtual=c; // pure virtual => virtual
|
|
}
|
|
void SetDeprecated(bool c = true)
|
|
{ m_bDeprecated=c; }
|
|
void SetLocation(int lineNumber)
|
|
{ m_nLine=lineNumber; }
|
|
void SetAvailability(int nAvail)
|
|
{ m_nAvailability=nAvail; }
|
|
void SetAccessSpecifier(wxMethodAccessSpecifier spec)
|
|
{ m_access=spec; }
|
|
|
|
public: // misc
|
|
|
|
bool operator==(const wxMethod&) const;
|
|
bool operator!=(const wxMethod& m) const
|
|
{ return !(*this == m); }
|
|
|
|
// this function works like operator== but tests everything:
|
|
// - method name
|
|
// - return type
|
|
// - argument types
|
|
// except for the method attributes (const,static,virtual,pureVirtual,deprecated)
|
|
bool MatchesExceptForAttributes(const wxMethod& m) const;
|
|
|
|
// returns true if this is a ctor which has default values for all its
|
|
// argument, thus is able to act also as default ctor
|
|
bool ActsAsDefaultCtor() const;
|
|
|
|
// dumps the contents of this class in the given stream
|
|
void Dump(wxTextOutputStream& stream) const;
|
|
|
|
protected:
|
|
wxType m_retType;
|
|
wxString m_strName;
|
|
wxArgumentTypeArray m_args;
|
|
|
|
// misc attributes:
|
|
bool m_bConst;
|
|
bool m_bStatic;
|
|
bool m_bVirtual;
|
|
bool m_bPureVirtual;
|
|
bool m_bDeprecated;
|
|
|
|
// m_nLine can be -1 if no location infos are available
|
|
int m_nLine;
|
|
|
|
// this is a combination of wxPORT_* flags (see wxPortId) or wxPORT_UNKNOWN
|
|
// if this method should be available for all wxWidgets ports.
|
|
// NOTE: this is not used for comparing wxMethod objects
|
|
// (gccXML never gives this kind of info).
|
|
int m_nAvailability;
|
|
|
|
// the access specifier for this method
|
|
wxMethodAccessSpecifier m_access;
|
|
};
|
|
|
|
WX_DECLARE_OBJARRAY(wxMethod, wxMethodArray);
|
|
WX_DEFINE_ARRAY(const wxMethod*, wxMethodPtrArray);
|
|
|
|
|
|
// we need wxClassPtrArray to be defined _before_ wxClass itself,
|
|
// since wxClass uses wxClassPtrArray.
|
|
class wxClass;
|
|
WX_DEFINE_ARRAY(const wxClass*, wxClassPtrArray);
|
|
|
|
class wxXmlInterface;
|
|
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// Represents a class of the wx API/interface.
|
|
// ----------------------------------------------------------------------------
|
|
class wxClass
|
|
{
|
|
public:
|
|
wxClass() {}
|
|
wxClass(const wxString& name, const wxString& headername)
|
|
: m_strName(name), m_strHeader(headername) {}
|
|
|
|
|
|
public: // setters
|
|
|
|
void SetHeader(const wxString& header)
|
|
{ m_strHeader=header; }
|
|
void SetName(const wxString& name)
|
|
{ m_strName=name; }
|
|
void SetAvailability(int nAvail)
|
|
{ m_nAvailability=nAvail; }
|
|
void SetParent(unsigned int k, const wxString& name)
|
|
{ m_parents[k]=name; }
|
|
|
|
public: // getters
|
|
|
|
bool IsOk() const
|
|
{ return !m_strName.IsEmpty() && !m_methods.IsEmpty(); }
|
|
|
|
bool IsValidCtorForThisClass(const wxMethod& m) const;
|
|
bool IsValidDtorForThisClass(const wxMethod& m) const;
|
|
|
|
wxString GetName() const
|
|
{ return m_strName; }
|
|
wxString GetHeader() const
|
|
{ return m_strHeader; }
|
|
wxString GetNameWithoutTemplate() const;
|
|
|
|
unsigned int GetMethodCount() const
|
|
{ return m_methods.GetCount(); }
|
|
wxMethod& GetMethod(unsigned int n) const
|
|
{ return m_methods[n]; }
|
|
wxMethod& GetLastMethod() const
|
|
{ return m_methods.Last(); }
|
|
|
|
int GetAvailability() const
|
|
{ return m_nAvailability; }
|
|
|
|
//const wxClass *GetParent(unsigned int i) const
|
|
const wxString& GetParent(unsigned int i) const
|
|
{ return m_parents[i]; }
|
|
unsigned int GetParentCount() const
|
|
{ return m_parents.GetCount(); }
|
|
|
|
public: // misc
|
|
|
|
void AddMethod(const wxMethod& func)
|
|
{ m_methods.Add(func); }
|
|
|
|
void AddParent(const wxString& parent)//wxClass* parent)
|
|
{ m_parents.Add(parent); }
|
|
|
|
// returns a single result (the first, which is also the only
|
|
// one if CheckConsistency() return true)
|
|
const wxMethod* FindMethod(const wxMethod& m) const;
|
|
|
|
// like FindMethod() but this one searches also recursively in
|
|
// the parents of this class.
|
|
const wxMethod* RecursiveUpwardFindMethod(const wxMethod& m,
|
|
const wxXmlInterface* allclasses) const;
|
|
|
|
// returns an array of pointers to the overloaded methods with the
|
|
// same given name
|
|
wxMethodPtrArray FindMethodsNamed(const wxString& name) const;
|
|
|
|
// like FindMethodsNamed() but this one searches also recursively in
|
|
// the parents of this class.
|
|
wxMethodPtrArray RecursiveUpwardFindMethodsNamed(const wxString& name,
|
|
const wxXmlInterface* allclasses) const;
|
|
|
|
// dumps all methods to the given output stream
|
|
void Dump(wxTextOutputStream& stream) const;
|
|
|
|
// slow check
|
|
bool CheckConsistency() const;
|
|
|
|
protected:
|
|
wxString m_strName;
|
|
wxString m_strHeader;
|
|
wxMethodArray m_methods;
|
|
|
|
// name of the base classes: we store the names and not the pointers
|
|
// because this makes _much_ easier the parsing process!
|
|
// (basically because when parsing class X which derives from Y,
|
|
// we may have not parsed yet class Y!)
|
|
wxArrayString m_parents;
|
|
|
|
// see the wxMethod::m_nAvailability field for more info
|
|
int m_nAvailability;
|
|
};
|
|
|
|
WX_DECLARE_OBJARRAY(wxClass, wxClassArray);
|
|
|
|
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// wxXmlInterface
|
|
// ----------------------------------------------------------------------------
|
|
class wxXmlInterface
|
|
{
|
|
public:
|
|
wxXmlInterface() {}
|
|
|
|
const wxClass* FindClass(const wxString& classname) const
|
|
{
|
|
for (unsigned int i=0; i<m_classes.GetCount(); i++)
|
|
if (m_classes[i].GetName() == classname)
|
|
return &m_classes[i];
|
|
return NULL;
|
|
}
|
|
|
|
void Dump(const wxString& filename);
|
|
|
|
const wxClassArray& GetClasses() const
|
|
{ return m_classes; }
|
|
|
|
unsigned int GetClassesCount() const
|
|
{ return m_classes.GetCount(); }
|
|
|
|
unsigned int GetMethodCount() const
|
|
{
|
|
unsigned int methods = 0;
|
|
for (unsigned i=0; i < m_classes.GetCount(); i++)
|
|
methods += m_classes[i].GetMethodCount();
|
|
return methods;
|
|
}
|
|
|
|
// pass a full-path header filename:
|
|
wxClassPtrArray FindClassesDefinedIn(const wxString& headerfile) const;
|
|
|
|
void ShowProgress()
|
|
{ /*wxFprintf(stderr, ".");*/ }
|
|
|
|
// is this interface coherent?
|
|
bool CheckConsistency() const;
|
|
|
|
protected:
|
|
wxClassArray m_classes;
|
|
};
|
|
|
|
#if 1
|
|
// for wxTypeIdHashMap, keys == gccxml IDs and values == associated type strings
|
|
// e.g. key = "0x123f" and value = "const wxAboutDialogInfo&"
|
|
WX_DECLARE_HASH_MAP( unsigned long, wxString,
|
|
wxIntegerHash, wxIntegerEqual,
|
|
wxTypeIdHashMap );
|
|
|
|
WX_DECLARE_STRING_HASH_MAP( wxString, wxStringHashMap );
|
|
#else
|
|
#include <map>
|
|
typedef std::basic_string<char> stlString;
|
|
typedef std::map<unsigned long, stlString> wxTypeIdHashMap;
|
|
#endif
|
|
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// Represents the real interface of wxWidgets
|
|
// Loads it from the XML produced by gccXML: http://www.gccxml.org
|
|
// ----------------------------------------------------------------------------
|
|
class wxXmlGccInterface : public wxXmlInterface
|
|
{
|
|
public:
|
|
wxXmlGccInterface()
|
|
{
|
|
// FIXME: we should retrieve this from the XML file!
|
|
// here we suppose the XML was created for the currently-running port
|
|
m_portId = wxPlatformInfo::Get().GetPortId();
|
|
}
|
|
|
|
bool Parse(const wxString& filename);
|
|
bool ParseMethod(const wxXmlNode *p,
|
|
const wxTypeIdHashMap& types,
|
|
wxMethod& m);
|
|
|
|
wxPortId GetInterfacePort() const
|
|
{ return m_portId; }
|
|
|
|
wxString GetInterfacePortName() const
|
|
{ return wxPlatformInfo::GetPortIdName(m_portId, false); }
|
|
|
|
protected:
|
|
// the port for which the gcc XML was generated
|
|
wxPortId m_portId;
|
|
};
|
|
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// Represents the interface of the doxygen headers of wxWidgets
|
|
// Loads it from the XML produced by Doxygen: http://www.doxygen.org
|
|
// ----------------------------------------------------------------------------
|
|
class wxXmlDoxygenInterface : public wxXmlInterface
|
|
{
|
|
public:
|
|
wxXmlDoxygenInterface() {}
|
|
|
|
// !!SPEEDUP-TODO!!
|
|
// Using wxXmlDocument::Load as is, the entire XML file is parsed
|
|
// and an entire tree of wxXmlNodes is built in memory.
|
|
// We need however only small portions of the Doxygen-generated XML: to speedup the
|
|
// processing we could detach the expat callbacks when we detect the beginning of a
|
|
// node we're not interested about, or just don't create a wxXmlNode for it!
|
|
// This needs a modification of wxXml API.
|
|
|
|
bool Parse(const wxString& filename);
|
|
bool ParseCompoundDefinition(const wxString& filename);
|
|
bool ParseMethod(const wxXmlNode*, wxMethod&, wxString& header);
|
|
|
|
// this class can take advantage of the preprocessor output to give
|
|
// a minor number of false positive warnings in the final comparison
|
|
void AddPreprocessorValue(const wxString& name, const wxString& val)
|
|
{ m_preproc[name]=val; }
|
|
|
|
protected:
|
|
wxStringHashMap m_preproc;
|
|
};
|
|
|
|
|
|
|
|
#endif // _XMLPARSER_H_
|
|
|