]> git.saurik.com Git - wxWidgets.git/blobdiff - utils/ifacecheck/src/xmlparser.h
Fix a crash in wxExecute() in wxMSW too.
[wxWidgets.git] / utils / ifacecheck / src / xmlparser.h
index 648c121bf1f2ef936366120a75370140752cb6dc..f491bf0b0824e93480532f352bf11be83c4a47d3 100644 (file)
 #include <wx/txtstrm.h>
 #include <wx/dynarray.h>
 #include <wx/xml/xml.h>
+#include <wx/platinfo.h>
+#include <wx/log.h>
 
-// helper macros
-#define LogMessage(fmt, ...)   { wxPrintf(fmt "\n", __VA_ARGS__); fflush(stdout); }
-#define LogWarning(fmt, ...)   { wxPrintf("WARNING: " fmt "\n", __VA_ARGS__); fflush(stdout); }
-#define LogError(fmt, ...)     { wxPrintf("ERROR: " fmt "\n", __VA_ARGS__); fflush(stdout); }
-#define wxPrint(str)           { wxPrintf(str); fflush(stdout); }
+
+/*
+    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
 
 
 // ----------------------------------------------------------------------------
@@ -32,13 +44,17 @@ class wxType
 public:
     wxType() {}
     wxType(const wxString& type)
-        { SetFromString(type); }
+        { SetTypeFromString(type); }
 
-    void SetFromString(const wxString& t);
+    void SetTypeFromString(const wxString& t);
     wxString GetAsString() const
         { return m_strType; }
 
-    wxString GetClean() const;
+    // 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"); }
@@ -56,13 +72,69 @@ public:
     bool IsOk() const;
 
 protected:
-    wxString m_strType;
+    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.
@@ -70,19 +142,30 @@ WX_DECLARE_OBJARRAY(wxType, wxTypeArray);
 class wxMethod
 {
 public:
-    wxMethod() { m_bConst=m_bVirtual=m_bStatic=false; m_nLine=-1; }
+    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 wxTypeArray& arguments, const wxArrayString& defaults,
+             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,defaults); m_nLine=-1; }
+        { SetArgumentTypes(arguments); m_nLine=-1; }
 
 
 public:     // getters
 
-    //void SetFromString(const wxString& proto);
-    wxString GetAsString() const;
+    // 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
@@ -90,12 +173,16 @@ public:     // getters
         { return m_retType; }
     wxString GetName() const
         { return m_strName; }
-    wxTypeArray GetArgumentTypes() const
+    const wxArgumentTypeArray& GetArgumentTypes() const
+        { return m_args; }
+    wxArgumentTypeArray& GetArgumentTypes()
         { return m_args; }
-    wxArrayString GetArgumentDefaults() const
-        { return m_argDefaults; }
     int GetLocation() const
         { return m_nLine; }
+    int GetAvailability() const
+        { return m_nAvailability; }
+    wxMethodAccessSpecifier GetAccessSpecifier() const
+        { return m_access; }
 
     bool IsConst() const
         { return m_bConst; }
@@ -103,12 +190,20 @@ public:     // getters
         { 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
@@ -117,15 +212,27 @@ public:     // setters
         { m_retType=t; }
     void SetName(const wxString& name)
         { m_strName=name; }
-    void SetArgumentTypes(const wxTypeArray& arr, const wxArrayString& defaults);
+    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
 
@@ -133,23 +240,57 @@ public:     // misc
     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;
-    wxTypeArray m_args;
-    wxArrayString m_argDefaults;
+    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.
 // ----------------------------------------------------------------------------
@@ -160,18 +301,19 @@ public:
     wxClass(const wxString& name, const wxString& headername)
         : m_strName(name), m_strHeader(headername) {}
 
-    void AddMethod(const wxMethod& func)
-        { m_methods.Add(func); }
+
+public:     // setters
 
     void SetHeader(const wxString& header)
         { m_strHeader=header; }
     void SetName(const wxString& name)
         { m_strName=name; }
-    wxString GetName() const
-        { return m_strName; }
-    wxString GetHeader() const
-        { return m_strHeader; }
-    wxString GetNameWithoutTemplate() const;
+    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(); }
@@ -179,6 +321,12 @@ public:
     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
@@ -186,13 +334,40 @@ public:
     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 FindMethodNamed(const wxString& m) const;
+    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;
@@ -204,10 +379,18 @@ 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);
-WX_DEFINE_ARRAY(const wxClass*, wxClassPtrArray);
 
 
 
@@ -243,21 +426,31 @@ public:
             return methods;
         }
 
+    // pass a full-path header filename:
+    wxClassPtrArray FindClassesDefinedIn(const wxString& headerfile) const;
+
     void ShowProgress()
-        { /*wxPrint(".");*/ }
+        { /*wxFprintf(stderr, ".");*/ }
 
-    bool CheckParseResults() const;
+    // 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<stlString, stlString> wxStringHashMap;
+typedef std::map<unsigned long, stlString> wxTypeIdHashMap;
 #endif
 
 
@@ -268,20 +461,27 @@ typedef std::map<stlString, stlString> wxStringHashMap;
 class wxXmlGccInterface : public wxXmlInterface
 {
 public:
-    wxXmlGccInterface() {}
-
-    // !!SPEEDUP-TODO!!
-    // Using wxXmlDocument::Load as is, all the types contained in the
-    // the entire gccXML file are stored in memory while parsing;
-    // however we are only interested to wx's own structs/classes/funcs/etc
-    // so that we could use the file IDs to avoid loading stuff which does
-    // not belong to wx. See the very end of the gccXML file: it contains
-    // a set of <File> nodes referenced by all nodes above.
+    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 wxStringHashMap& types,
+                     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;
 };
 
 
@@ -305,6 +505,14 @@ public:
     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;
 };