]> git.saurik.com Git - wxWidgets.git/commitdiff
BIG CHANGES:
authorFrancesco Montorsi <f18m_cpp217828@yahoo.it>
Mon, 22 Sep 2008 21:55:38 +0000 (21:55 +0000)
committerFrancesco Montorsi <f18m_cpp217828@yahoo.it>
Mon, 22 Sep 2008 21:55:38 +0000 (21:55 +0000)
- removed fix from the rungccxml.sh.in; not only it was unnecessary
  but it's also better to keep all references to specific wxWidgets
  classes in a single place: the ifacecheck sources;
- added g_bLogEnabled and LogNull class;
- added an HACK_TO_AUTO_CORRECT_ONLY_VIRTUAL_AND_CONST_ATTRIBUTES
  mode for fixing virtualness and constness of interface headers
  in an automated way
- added options to wxMethod::GetAsString to provide an easier way
  to debug ifacecheck comparisons between wxMethods
- fixed wxMethod::FixMethod for single-line prototypes and added
  a boolean return value from it

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@55809 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

utils/ifacecheck/rungccxml.sh.in
utils/ifacecheck/src/ifacecheck.cpp
utils/ifacecheck/src/xmlparser.cpp
utils/ifacecheck/src/xmlparser.h

index 86f6b4885fdb56e464f6ffc4aefeeff58507c4d0..d50c4189ea1d0445ad70fb887d37b7cba7690e48 100755 (executable)
@@ -79,14 +79,5 @@ if [[ $? != 0 ]]; then
     exit
 fi
 
-# FIX for IFACECHECK
-# ==================
-
-# these fixes are needed to avoid false warnings/errors by ifacecheck
-
-if [[ "@TOOLKIT@" == "GTK" ]]; then
-    sed -i -e 's/default="wxBITMAP_TYPE_XPM"/default="wxBITMAP_DEFAULT_TYPE"/g' $gccxmloutput
-fi
-
 # cleanup
 rm $allheaders
index 99054195e7d7dddcf7335adf1604867ff0023c01..778a70f5f611c490de9bece6d5edc7a32bf11d6c 100644 (file)
@@ -80,7 +80,7 @@ public:
 
     bool Compare();
     int CompareClasses(const wxClass* iface, const wxClassPtrArray& api);
-    void FixMethod(const wxString& header, const wxMethod* iface, const wxMethod* api);
+    bool FixMethod(const wxString& header, const wxMethod* iface, const wxMethod* api);
 
     void ShowProgress();
     void PrintStatistics(long secs);
@@ -135,12 +135,16 @@ int IfaceCheckApp::OnRun()
             // in any case set basic std preprocessor #defines:
             m_doxyInterface.AddPreprocessorValue("NULL", "0");
 
+            g_bLogEnabled = false;
+
             // parse the two XML files which contain the real and the doxygen interfaces
             // for wxWidgets API:
             if (!m_gccInterface.Parse(parser.GetParam(0)) ||
                 !m_doxyInterface.Parse(parser.GetParam(1)))
                 return 1;
 
+            g_bLogEnabled = true;
+
             if (parser.Found(DUMP_SWITCH))
             {
                 LogMessage("Dumping real API to '%s'...", API_DUMP_FILE);
@@ -163,6 +167,7 @@ int IfaceCheckApp::OnRun()
                         m_strToMatch = m_strToMatch.Mid(1, len-2);
                 }
 
+
                 ok = Compare();
             }
 
@@ -311,6 +316,7 @@ int IfaceCheckApp::CompareClasses(const wxClass* iface, const wxClassPtrArray& a
 
         if (matches == 0)
         {
+            bool exit = false;
             wxMethodPtrArray overloads;
 
             // try searching for methods with the same name but with
@@ -321,8 +327,36 @@ int IfaceCheckApp::CompareClasses(const wxClass* iface, const wxClassPtrArray& a
 
                 // append "results" array to "overloads"
                 WX_APPEND_ARRAY(overloads, results);
+
+
+#define HACK_TO_AUTO_CORRECT_ONLY_VIRTUAL_AND_CONST_ATTRIBUTES        1
+#if HACK_TO_AUTO_CORRECT_ONLY_VIRTUAL_AND_CONST_ATTRIBUTES
+                for (unsigned int k=0; k<results.GetCount(); k++)
+                    if (results[k]->MatchesExceptForAttributes(m) &&
+                        results[k]->IsPureVirtual() == m.IsPureVirtual())
+                    {
+                        // fix default values of results[k]:
+                        wxMethod tmp(*results[k]);
+                        tmp.SetArgumentTypes(m.GetArgumentTypes());
+
+                        // modify interface header
+                        if (FixMethod(iface->GetHeader(), &m, &tmp))
+                            wxLogMessage("Adjusted attributes of '%s' method", m.GetAsString());
+
+                        exit = true;
+                        break;
+                    }
+
+                if (exit)
+                    break;
+#endif
             }
 
+#if HACK_TO_AUTO_CORRECT_ONLY_VIRTUAL_AND_CONST_ATTRIBUTES
+            if (!exit)
+            {
+#endif
+
             if (overloads.GetCount()==0)
             {
                 /*
@@ -349,9 +383,10 @@ int IfaceCheckApp::CompareClasses(const wxClass* iface, const wxClassPtrArray& a
                                                 " but has different signature:\n",
                                                 m.GetName(), searchedclasses);
 
-                warning += "\tdoxy header: " + m.GetAsString();
+                // get a list of the prototypes with _all_ possible attributes:
+                warning += "\tdoxy header: " + m.GetAsString(true, true, true);
                 for (unsigned int j=0; j<overloads.GetCount(); j++)
-                    warning += "\n\treal header: " + overloads[j]->GetAsString();
+                    warning += "\n\treal header: " + overloads[j]->GetAsString(true, true, true);
 
                 wxPrint(warning + "\n");
                 count++;
@@ -378,20 +413,24 @@ int IfaceCheckApp::CompareClasses(const wxClass* iface, const wxClassPtrArray& a
             }
 
             count++;
+
+#if HACK_TO_AUTO_CORRECT_ONLY_VIRTUAL_AND_CONST_ATTRIBUTES
+            }
+#endif
         }
     }
 
     return count;
 }
 
-void IfaceCheckApp::FixMethod(const wxString& header, const wxMethod* iface, const wxMethod* api)
+bool IfaceCheckApp::FixMethod(const wxString& header, const wxMethod* iface, const wxMethod* api)
 {
     wxASSERT(iface && api);
 
     wxTextFile file;
     if (!file.Open(header)) {
         LogError("\tcan't open the '%s' header file.", header);
-        return;
+        return false;
     }
 
     // GetLocation() returns the line where the last part of the prototype is placed:
@@ -399,38 +438,50 @@ void IfaceCheckApp::FixMethod(const wxString& header, const wxMethod* iface, con
     if (end <= 0 || end >= (int)file.GetLineCount()) {
         LogWarning("\tinvalid location info for method '%s': %d.",
                    iface->GetAsString(), iface->GetLocation());
-        return;
+        return false;
     }
 
     if (!file.GetLine(end).Contains(";")) {
         LogWarning("\tinvalid location info for method '%s': %d.",
                    iface->GetAsString(), iface->GetLocation());
-        return;
+        return false;
     }
 
-    // find the start point of this prototype declaration:
-    int start = end-1;
+    // is this a one-line prototype declaration?
     bool founddecl = false;
-    while (start > 0 &&
-           !file.GetLine(start).Contains(";") &&
-           !file.GetLine(start).Contains("*/"))
+    int start;
+    if (file.GetLine(end).Contains(iface->GetName()))
     {
-        start--;
+        // yes, this prototype is all on this line:
+        start = end;
+        founddecl = true;
+    }
+    else
+    {
+        start = end-1;
+
+        // find the start point of this prototype declaration:
+        while (start > 0 &&
+            !file.GetLine(start).Contains(";") &&
+            !file.GetLine(start).Contains("*/"))
+        {
+            start--;
 
-        founddecl |= file.GetLine(start).Contains(iface->GetName());
+            founddecl |= file.GetLine(start).Contains(iface->GetName());
+        }
+
+        // start-th line contains either the declaration of another prototype
+        // or the closing tag */ of a doxygen comment; start one line below
+        start++;
     }
 
     if (start <= 0 || !founddecl)
     {
-        LogError("\tcan't find the beginning of the declaration of '%s' method in '%s' header",
-                    iface->GetAsString(), header);
-        return;
+        LogError("\tcan't find the beginning of the declaration of '%s' method in '%s' header looking backwards from line %d",
+                    iface->GetAsString(), header, end);
+        return false;
     }
 
-    // start-th line contains either the declaration of another prototype
-    // or the closing tag */ of a doxygen comment; start one line below
-    start++;
-
     // remove the old prototype
     for (int i=start; i<=end; i++)
         file.RemoveLine(start);     // remove (end-start)-nth times the start-th line
@@ -500,13 +551,13 @@ void IfaceCheckApp::FixMethod(const wxString& header, const wxMethod* iface, con
     // now save the modification
     if (!file.Write()) {
         LogError("\tcan't save the '%s' header file.", header);
-        return;
+        return false;
     }
 
     // how many lines did we add/remove in total?
     int nOffset = toinsert.GetCount() + deprecationOffset - (end-start+1);
     if (nOffset == 0)
-        return;
+        return false;
 
     if (g_verbose)
         LogMessage("\tthe final row offset for following methods is %d lines.", nOffset);
@@ -526,6 +577,8 @@ void IfaceCheckApp::FixMethod(const wxString& header, const wxMethod* iface, con
             }
         }
     }
+
+    return true;
 }
 
 bool IfaceCheckApp::ParsePreprocessorOutput(const wxString& filename)
index 142ca3c4b45a303a7debfc007e9e0c9333ae24af..b4a0c33f26a7a846677df585bd8ca8427f66e220 100644 (file)
@@ -40,6 +40,9 @@ WX_DEFINE_OBJARRAY(wxClassArray)
 // defined in ifacecheck.cpp
 extern bool g_verbose;
 
+// global variable:
+bool g_bLogEnabled = true;
+
 
 
 // ----------------------------------------------------------------------------
@@ -88,6 +91,12 @@ void wxType::SetTypeFromString(const wxString& t)
     // need to be considered as the same type
     if (m_strTypeClean.EndsWith("Base"))
         m_strTypeClean = m_strTypeClean.Left(m_strTypeClean.Len()-4);
+
+    // ADHOC-FIX:
+    // doxygen likes to put wxDateTime:: in front of all wxDateTime enums;
+    // fix this to avoid false positives
+    m_strTypeClean.Replace("wxDateTime::", "");
+    m_strTypeClean.Replace("wxStockGDI::", "");     // same story for some other classes
 }
 
 bool wxType::IsOk() const
@@ -110,6 +119,9 @@ bool wxType::operator==(const wxType& m) const
         IsReference() == m.IsReference())
         return true;
 
+    if (g_verbose)
+        LogMessage("Type '%s' does not match type '%s'", m_strType, m.m_strType);
+
     return false;
 }
 
@@ -134,7 +146,13 @@ void wxArgumentType::SetDefaultValue(const wxString& defval, const wxString& def
     else
         m_strDefaultValue.Replace("NULL", "0");
 */
+    // ADHOC-FIX:
+    // doxygen likes to put wxDateTime:: in front of all wxDateTime enums;
+    // fix this to avoid false positives
+    m_strDefaultValueForCmp.Replace("wxDateTime::", "");
+    m_strDefaultValueForCmp.Replace("wxStockGDI::", "");     // same story for some other classes
 
+    // ADHOC-FIX:
     if (m_strDefaultValue.Contains("wxGetTranslation"))
         m_strDefaultValue = "_(TOFIX)";     // TODO: wxGetTranslation gives problems to gccxml
 }
@@ -147,6 +165,13 @@ bool wxArgumentType::operator==(const wxArgumentType& m) const
     const wxString& def1 = m_strDefaultValueForCmp.IsEmpty() ? m_strDefaultValue : m_strDefaultValueForCmp;
     const wxString& def2 = m.m_strDefaultValueForCmp.IsEmpty() ? m.m_strDefaultValue : m.m_strDefaultValueForCmp;
 
+    // ADHOC-FIX:
+    // default values for style attributes of wxWindow-derived classes in gccxml appear as raw
+    // numbers; avoid false positives in this case!
+    if (m_strArgName == m.m_strArgName && m_strArgName == "style" &&
+        (def1.IsNumber() || def2.IsNumber()))
+        return true;
+
     if (def1 != def2)
     {
         // maybe the default values are numbers.
@@ -160,6 +185,9 @@ bool wxArgumentType::operator==(const wxArgumentType& m) const
                 return true;        // the default values match
         }
 
+        if (g_verbose)
+            LogMessage("Argument type '%s = %s' has different default value from '%s = %s'",
+                       m_strType, def1, m.m_strType, def2);
         return false;
     }
 
@@ -222,20 +250,20 @@ bool wxMethod::IsOk() const
     return true;
 }
 
-bool wxMethod::operator==(const wxMethod& m) const
+bool wxMethod::MatchesExceptForAttributes(const wxMethod& m) const
 {
     if (GetReturnType() != m.GetReturnType() ||
-        GetName() != m.GetName() ||
-        IsConst() != m.IsConst() ||
-        IsStatic() != m.IsStatic() ||
-        IsVirtual() != m.IsVirtual() ||
-        IsPureVirtual() != m.IsPureVirtual() ||
-        IsDeprecated() != m.IsDeprecated())
+        GetName() != m.GetName())
         return false;
 
-    if (m_args.GetCount()!=m.m_args.GetCount())
+    if (m_args.GetCount()!=m.m_args.GetCount()) {
+        if (g_verbose)
+            LogMessage("Method '%s' has %d arguments while '%s' has %d arguments",
+                       m_strName, m_args.GetCount(), m_strName, m.m_args.GetCount());
         return false;
+    }
 
+    // compare argument types
     for (unsigned int i=0; i<m_args.GetCount(); i++)
         if (m_args[i] != m.m_args[i])
             return false;
@@ -243,12 +271,31 @@ bool wxMethod::operator==(const wxMethod& m) const
     return true;
 }
 
-wxString wxMethod::GetAsString(bool bWithArgumentNames) const
+bool wxMethod::operator==(const wxMethod& m) const
+{
+    // check attributes
+    if (IsConst() != m.IsConst() ||
+        IsStatic() != m.IsStatic() ||
+        IsVirtual() != m.IsVirtual() ||
+        IsPureVirtual() != m.IsPureVirtual() ||
+        IsDeprecated() != m.IsDeprecated())
+        return false;
+
+    // check everything else
+    return MatchesExceptForAttributes(m);
+}
+
+wxString wxMethod::GetAsString(bool bWithArgumentNames, bool bClean, bool bDeprecated) const
 {
     wxString ret;
 
     if (m_retType!=wxEmptyType)
-        ret += m_retType.GetAsString() + " ";
+    {
+        if (bClean)
+            ret += m_retType.GetAsCleanString() + " ";
+        else
+            ret += m_retType.GetAsString() + " ";
+    }
     //else; this is a ctor or dtor
 
     ret += m_strName + "(";
@@ -261,7 +308,8 @@ wxString wxMethod::GetAsString(bool bWithArgumentNames) const
         if (bWithArgumentNames && !name.IsEmpty())
             ret += " " + name;
 
-        const wxString& def = m_args[i].GetDefaultValue();
+        const wxString& def = bClean ?
+            m_args[i].GetDefaultCleanValue() : m_args[i].GetDefaultValue();
         if (!def.IsEmpty())
             ret += " = " + def;
 
@@ -280,11 +328,9 @@ wxString wxMethod::GetAsString(bool bWithArgumentNames) const
     if (m_bVirtual || m_bPureVirtual)
         ret = "virtual " + ret;
     if (m_bPureVirtual)
-        ret = ret + " = 0";
-
-    // in doxygen headers we don't need wxDEPRECATED:
-    //if (m_bDeprecated)
-    //    ret = "wxDEPRECATED( " + ret + " )";
+        ret += " = 0";
+    if (m_bDeprecated && bDeprecated)
+        ret += " [deprecated]";
 
     return ret;
 }
@@ -967,7 +1013,9 @@ bool wxXmlGccInterface::ParseMethod(const wxXmlNode *p,
                 return false;
             }
 
-            argtypes.Add(wxArgumentType(idx->second, arg->GetAttribute("default")));
+            argtypes.Add(wxArgumentType(idx->second,
+                                        arg->GetAttribute("default"),
+                                        arg->GetAttribute("name")));
         }
 
         arg = arg->GetNext();
index c50034bb8a7bb0b5b88ce35d823d00833f8337d9..d40c043842339331cd7605a8a41c9629f630aa59 100644 (file)
 #include <wx/xml/xml.h>
 #include <wx/platinfo.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:
+
+*/
+
+
+
 // helper macros
-#define LogMessage(fmt, ...)   { wxPrintf(fmt "\n", __VA_ARGS__); fflush(stdout); }
-#define LogWarning(fmt, ...)   { wxPrintf(fmt "\n", __VA_ARGS__); fflush(stdout); }
-#define LogError(fmt, ...)     { wxPrintf("ERROR: " fmt "\n", __VA_ARGS__); fflush(stdout); }
+#define LogMessage(fmt, ...)   { if (g_bLogEnabled) { wxPrintf(fmt "\n", __VA_ARGS__); fflush(stdout); }}
+#define LogWarning(fmt, ...)   { if (g_bLogEnabled) { wxPrintf(fmt "\n", __VA_ARGS__); fflush(stdout); }}
+#define LogError(fmt, ...)     { if (g_bLogEnabled) { wxPrintf("ERROR: " fmt "\n", __VA_ARGS__); fflush(stdout); }}
 #define wxPrint(str)           { wxPrintf(str); fflush(stdout); }
 
+// enable/disable logging
+extern bool g_bLogEnabled;
+
+class LogNull
+{
+public:
+    LogNull() { g_bLogEnabled = false; }
+    ~LogNull() { g_bLogEnabled = true; }
+};
+
+
 
 // ----------------------------------------------------------------------------
 // Represents a type with or without const/static/ qualifier
@@ -38,6 +64,8 @@ public:
     void SetTypeFromString(const wxString& t);
     wxString GetAsString() const
         { return m_strType; }
+    wxString GetAsCleanString() const
+        { return m_strTypeClean; }
 
     bool IsConst() const
         { return m_strType.Contains("const"); }
@@ -83,6 +111,8 @@ public:
     void SetDefaultValue(const wxString& defval, const wxString& defvalForCmp = wxEmptyString);
     wxString GetDefaultValue() const
         { return m_strDefaultValue; }
+    wxString GetDefaultCleanValue() const
+        { return m_strDefaultValueForCmp.IsEmpty() ? m_strDefaultValue : m_strDefaultValueForCmp; }
 
     bool HasDefaultValue() const
         { return !m_strDefaultValue.IsEmpty(); }
@@ -127,7 +157,12 @@ public:
 
 public:     // getters
 
-    wxString GetAsString(bool bWithArgumentNames = true) const;
+    // bWithArgumentNames = output argument names?
+    // bClean = output type names or type _clean_ names (see wxType::GetAsCleanString)
+    // bDeprecated = output [deprecated] next to deprecated methods?
+    wxString GetAsString(bool bWithArgumentNames = true,
+                         bool bClean = false,
+                         bool bDeprecated = false) const;
 
     // parser of the prototype:
     // all these functions return strings with spaces stripped
@@ -193,6 +228,13 @@ 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;
+
     void Dump(wxTextOutputStream& stream) const;
 
 protected: