]> git.saurik.com Git - wxWidgets.git/blobdiff - utils/ifacecheck/src/xmlparser.cpp
Forgot to commit
[wxWidgets.git] / utils / ifacecheck / src / xmlparser.cpp
index 018a4045bba42cfb94875f12f24ca0122487f535..e0d5803c4c5b64d9c29d913a2001d90186424abf 100644 (file)
@@ -97,6 +97,7 @@ void wxType::SetTypeFromString(const wxString& t)
     // fix this to avoid false positives
     m_strTypeClean.Replace("wxDateTime::", "");
     m_strTypeClean.Replace("wxStockGDI::", "");     // same story for some other classes
     // fix this to avoid false positives
     m_strTypeClean.Replace("wxDateTime::", "");
     m_strTypeClean.Replace("wxStockGDI::", "");     // same story for some other classes
+    m_strTypeClean.Replace("wxHelpEvent::", "");
 }
 
 bool wxType::IsOk() const
 }
 
 bool wxType::IsOk() const
@@ -145,6 +146,22 @@ void wxArgumentType::SetDefaultValue(const wxString& defval, const wxString& def
     // to a single form:
     if (m_strDefaultValueForCmp == "0u")
         m_strDefaultValueForCmp = "0";
     // to a single form:
     if (m_strDefaultValueForCmp == "0u")
         m_strDefaultValueForCmp = "0";
+
+    m_strDefaultValue.Replace("0x000000001", "1");
+    m_strDefaultValueForCmp.Replace("0x000000001", "1");
+
+    // fix for unicode strings:
+    m_strDefaultValue.Replace("\\000\\000\\000", "");
+    m_strDefaultValueForCmp.Replace("\\000\\000\\000", "");
+
+    if (m_strDefaultValueForCmp.StartsWith("wxT(") &&
+        m_strDefaultValueForCmp.EndsWith(")"))
+    {
+        // get rid of the wxT() part
+        unsigned int len = m_strDefaultValueForCmp.Len();
+        m_strDefaultValueForCmp = m_strDefaultValueForCmp.Mid(4,len-5);
+    }
+
 /*
     if (IsPointer())
         m_strDefaultValueForCmp.Replace("0", "NULL");
 /*
     if (IsPointer())
         m_strDefaultValueForCmp.Replace("0", "NULL");
@@ -156,6 +173,11 @@ void wxArgumentType::SetDefaultValue(const wxString& defval, const wxString& def
     // fix this to avoid false positives
     m_strDefaultValueForCmp.Replace("wxDateTime::", "");
     m_strDefaultValueForCmp.Replace("wxStockGDI::", "");     // same story for some other classes
     // fix this to avoid false positives
     m_strDefaultValueForCmp.Replace("wxDateTime::", "");
     m_strDefaultValueForCmp.Replace("wxStockGDI::", "");     // same story for some other classes
+    m_strDefaultValueForCmp.Replace("wxHelpEvent::", "");    // same story for some other classes
+
+    m_strDefaultValueForCmp.Replace("wxGet_wxConvLocal()", "wxConvLocal");
+
+    m_strDefaultValueForCmp.Replace("* GetColour(COLOUR_BLACK)", "*wxBLACK");
 
     // ADHOC-FIX:
     if (m_strDefaultValueForCmp.Contains("wxGetTranslation"))
 
     // ADHOC-FIX:
     if (m_strDefaultValueForCmp.Contains("wxGetTranslation"))
@@ -174,6 +196,21 @@ bool wxArgumentType::operator==(const wxArgumentType& m) const
         (m_strDefaultValueForCmp.IsNumber() || m.m_strDefaultValueForCmp.IsNumber()))
         return true;
 
         (m_strDefaultValueForCmp.IsNumber() || m.m_strDefaultValueForCmp.IsNumber()))
         return true;
 
+    // fix for default values which were replaced by gcc-xml with their numeric values
+    // (at this point we know that m_strTypeClean == m.m_strTypeClean):
+    if (m_strTypeClean == "long" || m_strTypeClean == "int")
+    {
+        if ((m_strDefaultValueForCmp.IsNumber() && m.m_strDefaultValueForCmp.StartsWith("wx")) ||
+            (m.m_strDefaultValueForCmp.IsNumber() && m_strDefaultValueForCmp.StartsWith("wx")))
+        {
+            if (g_verbose)
+                LogMessage("Supposing '%s'  default value to be the same of '%s'...",
+                           m_strDefaultValueForCmp, m.m_strDefaultValueForCmp);
+
+            return true;
+        }
+    }
+
     if (m_strDefaultValueForCmp != m.m_strDefaultValueForCmp)
     {
         // maybe the default values are numbers.
     if (m_strDefaultValueForCmp != m.m_strDefaultValueForCmp)
     {
         // maybe the default values are numbers.
@@ -280,14 +317,16 @@ bool wxMethod::operator==(const wxMethod& m) const
         IsStatic() != m.IsStatic() ||
         IsVirtual() != m.IsVirtual() ||
         IsPureVirtual() != m.IsPureVirtual() ||
         IsStatic() != m.IsStatic() ||
         IsVirtual() != m.IsVirtual() ||
         IsPureVirtual() != m.IsPureVirtual() ||
-        IsDeprecated() != m.IsDeprecated())
+        IsDeprecated() != m.IsDeprecated() ||
+        GetAccessSpecifier() != m.GetAccessSpecifier())
         return false;
 
     // check everything else
     return MatchesExceptForAttributes(m);
 }
 
         return false;
 
     // check everything else
     return MatchesExceptForAttributes(m);
 }
 
-wxString wxMethod::GetAsString(bool bWithArgumentNames, bool bClean, bool bDeprecated) const
+wxString wxMethod::GetAsString(bool bWithArgumentNames, bool bCleanDefaultValues,
+                               bool bDeprecated, bool bAccessSpec) const
 {
     wxString ret;
 
 {
     wxString ret;
 
@@ -308,7 +347,7 @@ wxString wxMethod::GetAsString(bool bWithArgumentNames, bool bClean, bool bDepre
         if (bWithArgumentNames && !name.IsEmpty())
             ret += " " + name;
 
         if (bWithArgumentNames && !name.IsEmpty())
             ret += " " + name;
 
-        const wxString& def = bClean ?
+        const wxString& def = bCleanDefaultValues ?
             m_args[i].GetDefaultCleanValue() : m_args[i].GetDefaultValue();
         if (!def.IsEmpty())
             ret += " = " + def;
             m_args[i].GetDefaultCleanValue() : m_args[i].GetDefaultValue();
         if (!def.IsEmpty())
             ret += " = " + def;
@@ -332,6 +371,22 @@ wxString wxMethod::GetAsString(bool bWithArgumentNames, bool bClean, bool bDepre
     if (m_bDeprecated && bDeprecated)
         ret += " [deprecated]";
 
     if (m_bDeprecated && bDeprecated)
         ret += " [deprecated]";
 
+    if (bAccessSpec)
+    {
+        switch (m_access)
+        {
+        case wxMAS_PUBLIC:
+            ret += " [public]";
+            break;
+        case wxMAS_PROTECTED:
+            ret += " [protected]";
+            break;
+        case wxMAS_PRIVATE:
+            ret += " [private]";
+            break;
+        }
+    }
+
     return ret;
 }
 
     return ret;
 }
 
@@ -429,6 +484,38 @@ const wxMethod* wxClass::FindMethod(const wxMethod& m) const
     return NULL;
 }
 
     return NULL;
 }
 
+const wxMethod* wxClass::RecursiveUpwardFindMethod(const wxMethod& m,
+                                                   const wxXmlInterface* allclasses) const
+{
+    // first, search into *this
+    const wxMethod* ret = FindMethod(m);
+    if (ret)
+        return ret;
+
+    // then, search into its parents
+    for (unsigned int i=0; i<m_parents.GetCount(); i++)
+    {
+        // ignore non-wx-classes parents
+        // AD-HOC FIX: discard wxScrolledT_Helper parent as it always gives errors
+        if (m_parents[i].StartsWith("wx") && m_parents[i] != "wxScrolledT_Helper")
+        {
+            const wxClass *parent = allclasses->FindClass(m_parents[i]);
+            if (!parent) {
+                LogError("Could not find parent '%s' of class '%s'...",
+                         m_parents[i], GetName());
+                return false;
+            }
+
+            const wxMethod *parentMethod = parent->RecursiveUpwardFindMethod(m, allclasses);
+            if (parentMethod)
+                return parentMethod;
+        }
+    }
+
+    // could not find anything even in parent classes...
+    return NULL;
+}
+
 wxMethodPtrArray wxClass::FindMethodsNamed(const wxString& name) const
 {
     wxMethodPtrArray ret;
 wxMethodPtrArray wxClass::FindMethodsNamed(const wxString& name) const
 {
     wxMethodPtrArray ret;
@@ -441,6 +528,37 @@ wxMethodPtrArray wxClass::FindMethodsNamed(const wxString& name) const
 }
 
 
 }
 
 
+wxMethodPtrArray wxClass::RecursiveUpwardFindMethodsNamed(const wxString& name,
+                                                          const wxXmlInterface* allclasses) const
+{
+    // first, search into *this
+    wxMethodPtrArray ret = FindMethodsNamed(name);
+    if (ret.GetCount()>0)
+        return ret;         // stop here, don't look upward in the parents
+
+    // then, search into parents of this class
+    for (unsigned int i=0; i<m_parents.GetCount(); i++)
+    {
+        // AD-HOC FIX: discard wxScrolledT_Helper parent as it always gives errors
+        if (m_parents[i].StartsWith("wx") && m_parents[i] != "wxScrolledT_Helper")
+        {
+            const wxClass *parent = allclasses->FindClass(m_parents[i]);
+            if (!parent) {
+                LogError("Could not find parent '%s' of class '%s'...",
+                         m_parents[i], GetName());
+                return false;
+            }
+
+            wxMethodPtrArray temp = parent->RecursiveUpwardFindMethodsNamed(name, allclasses);
+            WX_APPEND_ARRAY(ret, temp);
+        }
+    }
+
+    return ret;
+}
+
+
+
 // ----------------------------------------------------------------------------
 // wxXmlInterface
 // ----------------------------------------------------------------------------
 // ----------------------------------------------------------------------------
 // wxXmlInterface
 // ----------------------------------------------------------------------------
@@ -503,6 +621,10 @@ wxClassPtrArray wxXmlInterface::FindClassesDefinedIn(const wxString& headerfile)
 #define ATTRIB_POINTER      4
 #define ATTRIB_ARRAY        8
 
 #define ATTRIB_POINTER      4
 #define ATTRIB_ARRAY        8
 
+// it may sound strange but gccxml, in order to produce shorter ID names
+// uses (after the underscore) characters in range 0-9 and a-z in the ID names;
+// in order to be able to translate such strings into numbers using strtoul()
+// we use as base 10 (possible digits) + 25 (possible characters) = 35
 #define GCCXML_BASE         35
 
 class toResolveTypeItem
 #define GCCXML_BASE         35
 
 class toResolveTypeItem
@@ -527,6 +649,7 @@ WX_DECLARE_HASH_MAP( unsigned long, toResolveTypeItem,
 WX_DECLARE_HASH_MAP( unsigned long, wxClass*,
                      wxIntegerHash, wxIntegerEqual,
                      wxClassMemberIdHashMap );
 WX_DECLARE_HASH_MAP( unsigned long, wxClass*,
                      wxIntegerHash, wxIntegerEqual,
                      wxClassMemberIdHashMap );
+
 #else
 #include <map>
 typedef std::map<unsigned long, toResolveTypeItem> wxToResolveTypeHashMap;
 #else
 #include <map>
 typedef std::map<unsigned long, toResolveTypeItem> wxToResolveTypeHashMap;
@@ -681,6 +804,21 @@ bool wxXmlGccInterface::Parse(const wxString& filename)
                 // NB: "file" attribute contains an ID value that we'll resolve later
                 m_classes.Add(wxClass(cname, child->GetAttribute("file")));
 
                 // NB: "file" attribute contains an ID value that we'll resolve later
                 m_classes.Add(wxClass(cname, child->GetAttribute("file")));
 
+                // the just-inserted class:
+                wxClass *newClass = &m_classes.Last();
+
+                // now get a list of the base classes:
+                wxXmlNode *baseNode = child->GetChildren();
+                while (baseNode)
+                {
+                    // for now we store as "parents" only the parent IDs...
+                    // later we will resolve them into full class names
+                    if (baseNode->GetName() == "Base")
+                        newClass->AddParent(baseNode->GetAttribute("type"));
+
+                    baseNode = baseNode->GetNext();
+                }
+
                 const wxString& ids = child->GetAttribute("members");
                 if (ids.IsEmpty())
                 {
                 const wxString& ids = child->GetAttribute("members");
                 if (ids.IsEmpty())
                 {
@@ -695,7 +833,7 @@ bool wxXmlGccInterface::Parse(const wxString& filename)
                 else
                 {
                     // decode the non-empty list of IDs:
                 else
                 {
                     // decode the non-empty list of IDs:
-                    if (!getMemberIDs(&members, &m_classes.Last(), ids)) {
+                    if (!getMemberIDs(&members, newClass, ids)) {
                         LogError("Invalid member IDs for '%s' class node: %s",
                                 cname, child->GetAttribute("id"));
                         return false;
                         LogError("Invalid member IDs for '%s' class node: %s",
                                 cname, child->GetAttribute("id"));
                         return false;
@@ -899,14 +1037,38 @@ bool wxXmlGccInterface::Parse(const wxString& filename)
             m_classes[i].SetHeader(idx->second);
     }
 
             m_classes[i].SetHeader(idx->second);
     }
 
+    // resolve parent names
+    for (unsigned int i=0; i<m_classes.GetCount(); i++)
+    {
+        for (unsigned int k=0; k<m_classes[i].GetParentCount(); k++)
+        {
+            unsigned long id;
+
+            if (!getID(&id, m_classes[i].GetParent(k))) {
+                LogError("invalid parent class ID for '%s'", m_classes[i].GetName());
+                return false;
+            }
+
+            wxTypeIdHashMap::const_iterator idx = types.find(id);
+            if (idx == types.end())
+            {
+                // this is an error!
+                LogError("couldn't find parent class ID '%d'", id);
+            }
+            else
+                // replace k-th parent with its true name:
+                m_classes[i].SetParent(k, idx->second);
+        }
+    }
+
     // build the list of the wx methods
     child = doc.GetRoot()->GetChildren();
     while (child)
     {
     // build the list of the wx methods
     child = doc.GetRoot()->GetChildren();
     while (child)
     {
-        wxString n = child->GetName();
+        wxString n = child->GetName(), acc = child->GetAttribute("access");
 
 
-        // only register public methods
-        if (child->GetAttribute("access") == "public" &&
+        // only register public&protected methods
+        if ((acc == "public" || acc == "protected") &&
             (n == "Method" || n == "Constructor" || n == "Destructor" || n == "OperatorMethod"))
         {
             unsigned long id = 0;
             (n == "Method" || n == "Constructor" || n == "Destructor" || n == "OperatorMethod"))
         {
             unsigned long id = 0;
@@ -928,6 +1090,8 @@ bool wxXmlGccInterface::Parse(const wxString& filename)
                     return false;
                 }
 
                     return false;
                 }
 
+                // do some additional check that we can do only here:
+
                 if (newfunc.IsCtor() && !p->IsValidCtorForThisClass(newfunc)) {
                     LogError("The method '%s' does not seem to be a ctor for '%s'",
                              newfunc.GetName(), p->GetName());
                 if (newfunc.IsCtor() && !p->IsValidCtorForThisClass(newfunc)) {
                     LogError("The method '%s' does not seem to be a ctor for '%s'",
                              newfunc.GetName(), p->GetName());
@@ -1036,6 +1200,14 @@ bool wxXmlGccInterface::ParseMethod(const wxXmlNode *p,
     m.SetPureVirtual(p->GetAttribute("pure_virtual") == "1");
     m.SetDeprecated(p->GetAttribute("attributes") == "deprecated");
 
     m.SetPureVirtual(p->GetAttribute("pure_virtual") == "1");
     m.SetDeprecated(p->GetAttribute("attributes") == "deprecated");
 
+    // decode access specifier
+    if (p->GetAttribute("access") == "public")
+        m.SetAccessSpecifier(wxMAS_PUBLIC);
+    else if (p->GetAttribute("access") == "protected")
+        m.SetAccessSpecifier(wxMAS_PROTECTED);
+    else if (p->GetAttribute("access") == "private")
+        m.SetAccessSpecifier(wxMAS_PRIVATE);
+
     if (!m.IsOk()) {
         LogError("The prototype '%s' is not valid!", m.GetAsString());
         return false;
     if (!m.IsOk()) {
         LogError("The prototype '%s' is not valid!", m.GetAsString());
         return false;
@@ -1217,6 +1389,7 @@ bool wxXmlDoxygenInterface::Parse(const wxString& filename)
 
 bool wxXmlDoxygenInterface::ParseCompoundDefinition(const wxString& filename)
 {
 
 bool wxXmlDoxygenInterface::ParseCompoundDefinition(const wxString& filename)
 {
+    wxClassMemberIdHashMap parents;
     wxXmlDocument doc;
     wxXmlNode *child;
     int nodes = 0;
     wxXmlDocument doc;
     wxXmlNode *child;
     int nodes = 0;
@@ -1249,8 +1422,11 @@ bool wxXmlDoxygenInterface::ParseCompoundDefinition(const wxString& filename)
             wxXmlNode *subchild = child->GetChildren();
             while (subchild)
             {
             wxXmlNode *subchild = child->GetChildren();
             while (subchild)
             {
+                wxString kind = subchild->GetAttribute("kind");
+
+                // parse only public&protected functions:
                 if (subchild->GetName() == "sectiondef" &&
                 if (subchild->GetName() == "sectiondef" &&
-                    subchild->GetAttribute("kind") == "public-func")
+                    (kind == "public-func" || kind == "protected-func"))
                 {
 
                     wxXmlNode *membernode = subchild->GetChildren();
                 {
 
                     wxXmlNode *membernode = subchild->GetChildren();
@@ -1267,6 +1443,13 @@ bool wxXmlDoxygenInterface::ParseCompoundDefinition(const wxString& filename)
                                 return false;
                             }
 
                                 return false;
                             }
 
+                            if (kind == "public-func")
+                                m.SetAccessSpecifier(wxMAS_PUBLIC);
+                            else if (kind == "protected-func")
+                                m.SetAccessSpecifier(wxMAS_PROTECTED);
+                            else if (kind == "private-func")
+                                m.SetAccessSpecifier(wxMAS_PRIVATE);
+
                             if (absoluteFile.IsEmpty())
                                 absoluteFile = header;
                             else if (header != absoluteFile)
                             if (absoluteFile.IsEmpty())
                                 absoluteFile = header;
                             else if (header != absoluteFile)
@@ -1304,6 +1487,11 @@ bool wxXmlDoxygenInterface::ParseCompoundDefinition(const wxString& filename)
                     // identify <onlyfor> custom XML tags
                     klass.SetAvailability(GetAvailabilityFor(subchild));
                 }
                     // identify <onlyfor> custom XML tags
                     klass.SetAvailability(GetAvailabilityFor(subchild));
                 }
+                else if (subchild->GetName() == "basecompoundref")
+                {
+                    // add the name of this parent to the list of klass' parents
+                    klass.AddParent(subchild->GetNodeContent());
+                }
 
                 subchild = subchild->GetNext();
             }
 
                 subchild = subchild->GetNext();
             }