// 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
+ m_strTypeClean.Replace("wxHelpEvent::", "");
}
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;
}
void wxArgumentType::SetDefaultValue(const wxString& defval, const wxString& defvalForCmp)
{
- m_strDefaultValue=defval.Strip(wxString::both);
- m_strDefaultValueForCmp=defvalForCmp.Strip(wxString::both);
+ m_strDefaultValue = defval.Strip(wxString::both);
+ m_strDefaultValueForCmp = defvalForCmp.IsEmpty() ? m_strDefaultValue : defvalForCmp.Strip(wxString::both);
+
+ // adjust aesthetic form of DefaultValue for the modify mode of ifacecheck:
+ // we may need to write it out in an interface header
+ if (m_strDefaultValue == "0u")
+ m_strDefaultValue = "0";
// in order to make valid&simple comparison on argument defaults,
// we reduce some of the multiple forms in which the same things may appear
// to a single form:
- if (m_strDefaultValue == "0u")
- m_strDefaultValue = "0";
+ if (m_strDefaultValueForCmp == "0u")
+ m_strDefaultValueForCmp = "0";
+
+ // fix for unicode strings:
+ 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_strDefaultValue.Replace("0", "NULL");
+ m_strDefaultValueForCmp.Replace("0", "NULL");
else
- m_strDefaultValue.Replace("NULL", "0");
+ m_strDefaultValueForCmp.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
+ m_strDefaultValueForCmp.Replace("wxHelpEvent::", ""); // same story for some other classes
+
+ m_strDefaultValueForCmp.Replace("wxGet_wxConvLocal()", "wxConvLocal");
- if (m_strDefaultValue.Contains("wxGetTranslation"))
- m_strDefaultValue = "_(TOFIX)"; // TODO: wxGetTranslation gives problems to gccxml
+ m_strDefaultValueForCmp.Replace("* GetColour(COLOUR_BLACK)", "*wxBLACK");
+
+ // ADHOC-FIX:
+ if (m_strDefaultValueForCmp.Contains("wxGetTranslation"))
+ m_strDefaultValueForCmp = "_(TOFIX)"; // TODO: wxGetTranslation gives problems to gccxml
}
bool wxArgumentType::operator==(const wxArgumentType& m) const
if ((const wxType&)(*this) != (const wxType&)m)
return false;
- 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" &&
+ (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 (def1 != def2)
+ if (m_strDefaultValueForCmp != m.m_strDefaultValueForCmp)
{
// maybe the default values are numbers.
// in this case gccXML gives as default values things like '-0x0000001' instead of just '-1'.
// To handle these cases, we try to convert the default value strings to numbers:
long def1val, def2val;
- if (def1.ToLong(&def1val, 0 /* auto-detect */) &&
- def2.ToLong(&def2val, 0 /* auto-detect */))
+ if (m_strDefaultValueForCmp.ToLong(&def1val, 0 /* auto-detect */) &&
+ m.m_strDefaultValueForCmp.ToLong(&def2val, 0 /* auto-detect */))
{
if (def1val == def2val)
return true; // the default values match
}
+ if (g_verbose)
+ LogMessage("Argument type '%s = %s' has different default value from '%s = %s'",
+ m_strType, m_strDefaultValueForCmp, m.m_strType, m.m_strDefaultValueForCmp);
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() ||
+ GetAccessSpecifier() != m.GetAccessSpecifier())
+ return false;
+
+ // check everything else
+ return MatchesExceptForAttributes(m);
+}
+
+wxString wxMethod::GetAsString(bool bWithArgumentNames, bool bCleanDefaultValues,
+ bool bDeprecated, bool bAccessSpec) const
{
wxString ret;
+ // NOTE: for return and argument types, never use wxType::GetAsCleanString
+ // since in that way we'd miss important decorators like &,*,const etc
+
if (m_retType!=wxEmptyType)
ret += m_retType.GetAsString() + " ";
//else; this is a ctor or dtor
if (bWithArgumentNames && !name.IsEmpty())
ret += " " + name;
- const wxString& def = m_args[i].GetDefaultValue();
+ const wxString& def = bCleanDefaultValues ?
+ 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";
+ ret += " = 0";
+ if (m_bDeprecated && bDeprecated)
+ ret += " [deprecated]";
- // in doxygen headers we don't need wxDEPRECATED:
- //if (m_bDeprecated)
- // ret = "wxDEPRECATED( " + ret + " )";
+ 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;
}
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;
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());
return false;
}
- argtypes.Add(wxArgumentType(idx->second, arg->GetAttribute("default")));
+ argtypes.Add(wxArgumentType(idx->second,
+ arg->GetAttribute("default"),
+ arg->GetAttribute("name")));
}
arg = arg->GetNext();
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;
wxXmlNode *subchild = child->GetChildren();
while (subchild)
{
+ wxString kind = subchild->GetAttribute("kind");
+
+ // parse only public&protected functions:
if (subchild->GetName() == "sectiondef" &&
- subchild->GetAttribute("kind") == "public-func")
+ (kind == "public-func" || kind == "protected-func"))
{
wxXmlNode *membernode = subchild->GetChildren();
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)