From 97f0dbd6f81fae70cbef690c0c0af10cf4334659 Mon Sep 17 00:00:00 2001 From: Francesco Montorsi Date: Mon, 22 Sep 2008 21:55:38 +0000 Subject: [PATCH] BIG CHANGES: - 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 | 9 --- utils/ifacecheck/src/ifacecheck.cpp | 99 ++++++++++++++++++++++------- utils/ifacecheck/src/xmlparser.cpp | 82 +++++++++++++++++++----- utils/ifacecheck/src/xmlparser.h | 50 +++++++++++++-- 4 files changed, 187 insertions(+), 53 deletions(-) diff --git a/utils/ifacecheck/rungccxml.sh.in b/utils/ifacecheck/rungccxml.sh.in index 86f6b4885f..d50c4189ea 100755 --- a/utils/ifacecheck/rungccxml.sh.in +++ b/utils/ifacecheck/rungccxml.sh.in @@ -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 diff --git a/utils/ifacecheck/src/ifacecheck.cpp b/utils/ifacecheck/src/ifacecheck.cpp index 99054195e7..778a70f5f6 100644 --- a/utils/ifacecheck/src/ifacecheck.cpp +++ b/utils/ifacecheck/src/ifacecheck.cpp @@ -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; kMatchesExceptForAttributes(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; jGetAsString(); + 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) diff --git a/utils/ifacecheck/src/xmlparser.cpp b/utils/ifacecheck/src/xmlparser.cpp index 142ca3c4b4..b4a0c33f26 100644 --- a/utils/ifacecheck/src/xmlparser.cpp +++ b/utils/ifacecheck/src/xmlparser.cpp @@ -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; isecond, arg->GetAttribute("default"))); + argtypes.Add(wxArgumentType(idx->second, + arg->GetAttribute("default"), + arg->GetAttribute("name"))); } arg = arg->GetNext(); diff --git a/utils/ifacecheck/src/xmlparser.h b/utils/ifacecheck/src/xmlparser.h index c50034bb8a..d40c043842 100644 --- a/utils/ifacecheck/src/xmlparser.h +++ b/utils/ifacecheck/src/xmlparser.h @@ -17,12 +17,38 @@ #include #include + +/* + 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: -- 2.47.2