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
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);
// 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);
m_strToMatch = m_strToMatch.Mid(1, len-2);
}
+
ok = Compare();
}
if (matches == 0)
{
+ bool exit = false;
wxMethodPtrArray overloads;
// try searching for methods with the same name but with
// 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)
{
/*
" 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++;
}
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:
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
// 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);
}
}
}
+
+ return true;
}
bool IfaceCheckApp::ParsePreprocessorOutput(const wxString& filename)
// defined in ifacecheck.cpp
extern bool g_verbose;
+// global variable:
+bool g_bLogEnabled = true;
+
// ----------------------------------------------------------------------------
// 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
IsReference() == m.IsReference())
return true;
+ if (g_verbose)
+ LogMessage("Type '%s' does not match type '%s'", m_strType, m.m_strType);
+
return false;
}
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
}
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.
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;
}
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;
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 + "(";
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;
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;
}
return false;
}
- argtypes.Add(wxArgumentType(idx->second, arg->GetAttribute("default")));
+ argtypes.Add(wxArgumentType(idx->second,
+ arg->GetAttribute("default"),
+ arg->GetAttribute("name")));
}
arg = arg->GetNext();
#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
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"); }
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(); }
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
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: