diff --git a/docs/doxygen/Doxyfile_inc b/docs/doxygen/Doxyfile_inc
index 2fb298c095..b487efb308 100644
--- a/docs/doxygen/Doxyfile_inc
+++ b/docs/doxygen/Doxyfile_inc
@@ -77,10 +77,12 @@ ALIASES += nativeimpl{3}="
Implementations: &
ALIASES += nativeimpl{4}="
Implementations: native under \ref page_port_\1, \ref page_port_\2, \ref page_port_\3, \ref page_port_\4 ports; a generic implementation is used elsewhere.
"
# onlyfor infos:
-ALIASES += onlyfor{1}="
Availability: only available for the \ref page_port_\1 port.
"
-ALIASES += onlyfor{2}="
Availability: only available for the \ref page_port_\1, \ref page_port_\2 ports.
"
-ALIASES += onlyfor{3}="
Availability: only available for the \ref page_port_\1, \ref page_port_\2, \ref page_port_\3 ports.
"
-ALIASES += onlyfor{4}="
Availability: only available for the \ref page_port_\1, \ref page_port_\2, \ref page_port_\3, \ref page_port_\4 ports.
"
+# NOTE: we need to be able to retrieve these infos also from the XML output, thus
+# we use the \xmlonly and \endxmlonly commands to include custom XML tags
+ALIASES += onlyfor{1}="
Availability: only available for the \ref page_port_\1 port.
\xmlonly
\1 \endxmlonly"
+ALIASES += onlyfor{2}="
Availability: only available for the \ref page_port_\1, \ref page_port_\2 ports.
\xmlonly
\1,\2 \endxmlonly"
+ALIASES += onlyfor{3}="
Availability: only available for the \ref page_port_\1, \ref page_port_\2, \ref page_port_\3 ports.
\xmlonly
\1,\2,\3 \endxmlonly"
+ALIASES += onlyfor{4}="
Availability: only available for the \ref page_port_\1, \ref page_port_\2, \ref page_port_\3, \ref page_port_\4 ports.
\xmlonly
\1,\2,\3,\4 \endxmlonly"
# creates appearance section: this should be used for all main GUI controls
ALIASES += appearance{1}="@htmlonly
Appearance: |  |  |
wxMSW appearance | wxGTK appearance | wxMac appearance |
@endhtmlonly"
diff --git a/utils/ifacecheck/rungccxml.sh.in b/utils/ifacecheck/rungccxml.sh.in
index fcd58240cc..c18eae5ae9 100755
--- a/utils/ifacecheck/rungccxml.sh.in
+++ b/utils/ifacecheck/rungccxml.sh.in
@@ -34,7 +34,7 @@ me=$(basename $0)
path=${0%%/$me}
current=$(pwd) # current path
-gccxmloutput="$current/$gccxmloutput"
+#gccxmloutput="$current/$gccxmloutput"
cd @top_srcdir@/include # go to wx include folder
@@ -61,13 +61,13 @@ flags=`echo "$flags" | sed -e 's/-pthread//g' | sed -e 's/__WXDEBUG__//g'`
flags="-I . -I @top_srcdir@/include $flags -D__WXDEBUG__ -D__WX@TOOLKIT@__ -DWXBUILDING $allheaders"
# run gccxml with the same flag used for the real compilation of wx sources:
-echo "Running gccxml on the $allheaders file..."
+echo "Running gccxml on the $allheaders file... results in $gccxmloutput"
if [[ -f "$gccxmloutput" ]]; then rm $gccxmloutput; fi
gccxml $flags -fxml=$gccxmloutput
# now get the list of the #defined values for wx headers, so that the result
# can be passed to ifacecheck to aid the comparison
-echo "Running gccxml's preprocessor on the $allheaders file..."
+echo "Running gccxml's preprocessor on the $allheaders file... results in $preprocoutput"
gccxml -E -dM $flags >$preprocoutput
# cleanup
diff --git a/utils/ifacecheck/src/ifacecheck.cpp b/utils/ifacecheck/src/ifacecheck.cpp
index d2c63869e6..a8ce9b2bc6 100644
--- a/utils/ifacecheck/src/ifacecheck.cpp
+++ b/utils/ifacecheck/src/ifacecheck.cpp
@@ -93,8 +93,8 @@ public:
}
protected:
- wxXmlGccInterface m_api; // "real" headers API
- wxXmlDoxygenInterface m_interface; // doxygen-commented headers API
+ wxXmlGccInterface m_gccInterface; // "real" headers API
+ wxXmlDoxygenInterface m_doxyInterface; // doxygen-commented headers API
// was the MODIFY_SWITCH passed?
bool m_modify;
@@ -133,21 +133,21 @@ int IfaceCheckApp::OnRun()
}
// in any case set basic std preprocessor #defines:
- m_interface.AddPreprocessorValue("NULL", "0");
+ m_doxyInterface.AddPreprocessorValue("NULL", "0");
// parse the two XML files which contain the real and the doxygen interfaces
// for wxWidgets API:
- if (!m_api.Parse(parser.GetParam(0)) ||
- !m_interface.Parse(parser.GetParam(1)))
+ if (!m_gccInterface.Parse(parser.GetParam(0)) ||
+ !m_doxyInterface.Parse(parser.GetParam(1)))
return 1;
if (parser.Found(DUMP_SWITCH))
{
LogMessage("Dumping real API to '%s'...", API_DUMP_FILE);
- m_api.Dump(API_DUMP_FILE);
+ m_gccInterface.Dump(API_DUMP_FILE);
LogMessage("Dumping interface API to '%s'...", INTERFACE_DUMP_FILE);
- m_interface.Dump(INTERFACE_DUMP_FILE);
+ m_doxyInterface.Dump(INTERFACE_DUMP_FILE);
}
else
{
@@ -195,7 +195,7 @@ void IfaceCheckApp::ShowProgress()
bool IfaceCheckApp::Compare()
{
- const wxClassArray& interface = m_interface.GetClasses();
+ const wxClassArray& interface = m_doxyInterface.GetClasses();
const wxClass* c;
wxClassPtrArray api;
int mcount = 0, ccount = 0;
@@ -208,6 +208,18 @@ bool IfaceCheckApp::Compare()
for (unsigned int i=0; i
0) {
@@ -242,9 +254,9 @@ bool IfaceCheckApp::Compare()
}
LogMessage("%d methods (%.1f%%) of the interface headers do not exist in the real headers",
- mcount, (float)(100.0 * mcount/m_interface.GetMethodCount()));
+ mcount, (float)(100.0 * mcount/m_doxyInterface.GetMethodCount()));
LogMessage("%d classes (%.1f%%) of the interface headers do not exist in the real headers",
- ccount, (float)(100.0 * ccount/m_interface.GetClassesCount()));
+ ccount, (float)(100.0 * ccount/m_doxyInterface.GetClassesCount()));
return true;
}
@@ -270,6 +282,18 @@ int IfaceCheckApp::CompareClasses(const wxClass* iface, const wxClassPtrArray& a
const wxMethod& m = iface->GetMethod(i);
int matches = 0;
+ // only compare the methods which are available for the port
+ // for which the gcc XML was produced
+ if (m.GetAvailability() != wxPORT_UNKNOWN &&
+ (m.GetAvailability() & m_gccInterface.GetInterfacePort()) == 0) {
+
+ if (g_verbose)
+ LogMessage("skipping method '%s' since it's not available for the %s port.",
+ m.GetAsString(), m_gccInterface.GetInterfacePortName());
+
+ continue; // skip this method
+ }
+
// search in the methods of the api classes provided
for (unsigned int j=0; jGetMethodCount(); j++)
@@ -529,7 +553,7 @@ bool IfaceCheckApp::ParsePreprocessorOutput(const wxString& filename)
defval = defval.Mid(1, defval.Len()-2);
// store this pair in the doxygen interface, where it can be useful
- m_interface.AddPreprocessorValue(defname, defval);
+ m_doxyInterface.AddPreprocessorValue(defname, defval);
useful++;
}
@@ -542,9 +566,9 @@ bool IfaceCheckApp::ParsePreprocessorOutput(const wxString& filename)
void IfaceCheckApp::PrintStatistics(long secs)
{
LogMessage("wx real headers contains declaration of %d classes (%d methods)",
- m_api.GetClassesCount(), m_api.GetMethodCount());
+ m_gccInterface.GetClassesCount(), m_gccInterface.GetMethodCount());
LogMessage("wx interface headers contains declaration of %d classes (%d methods)",
- m_interface.GetClassesCount(), m_interface.GetMethodCount());
+ m_doxyInterface.GetClassesCount(), m_doxyInterface.GetMethodCount());
LogMessage("total processing took %d seconds.", secs);
}
diff --git a/utils/ifacecheck/src/xmlparser.cpp b/utils/ifacecheck/src/xmlparser.cpp
index 69d5684f1d..43892d970d 100644
--- a/utils/ifacecheck/src/xmlparser.cpp
+++ b/utils/ifacecheck/src/xmlparser.cpp
@@ -927,6 +927,121 @@ bool wxXmlGccInterface::ParseMethod(const wxXmlNode *p,
}
+
+// ----------------------------------------------------------------------------
+// wxXmlDoxygenInterface global helpers
+// ----------------------------------------------------------------------------
+
+static wxString GetTextFromChildren(const wxXmlNode *n)
+{
+ wxString text;
+
+ // consider the tree
+ //
+ // this is a string
+ //
+ //
+ // |-
+ // | |- this
+ // |- is a
+ // |-
+ // |- string
+ //
+ // unlike wxXmlNode::GetNodeContent() which would return " is a "
+ // this function returns "this is a string"
+
+ wxXmlNode *ref = n->GetChildren();
+ while (ref) {
+ if (ref->GetType() == wxXML_ELEMENT_NODE)
+ text += ref->GetNodeContent();
+ else if (ref->GetType() == wxXML_TEXT_NODE)
+ text += ref->GetContent();
+ else
+ LogWarning("Unexpected node type while getting text from '%s' node", n->GetName());
+
+ ref = ref->GetNext();
+ }
+
+ return text;
+}
+
+static bool HasTextNodeContaining(const wxXmlNode *parent, const wxString& name)
+{
+ if (!parent)
+ return false;
+
+ wxXmlNode *p = parent->GetChildren();
+ while (p)
+ {
+ switch (p->GetType())
+ {
+ case wxXML_TEXT_NODE:
+ if (p->GetContent() == name)
+ return true;
+ break;
+
+ case wxXML_ELEMENT_NODE:
+ // recurse into this node...
+ if (HasTextNodeContaining(p, name))
+ return true;
+ break;
+
+ default:
+ // skip it
+ break;
+ }
+
+ p = p->GetNext();
+ }
+
+ return false;
+}
+
+static const wxXmlNode* FindNodeNamed(const wxXmlNode* parent, const wxString& name)
+{
+ if (!parent)
+ return NULL;
+
+ const wxXmlNode *p = parent->GetChildren();
+ while (p)
+ {
+ if (p->GetName() == name)
+ return p; // found!
+
+ // search recursively in the children of this node
+ const wxXmlNode *ret = FindNodeNamed(p, name);
+ if (ret)
+ return ret;
+
+ p = p->GetNext();
+ }
+
+ return NULL;
+}
+
+int GetAvailabilityFor(const wxXmlNode *node)
+{
+ // identify custom XML tags
+ const wxXmlNode* onlyfor = FindNodeNamed(node, "onlyfor");
+ if (!onlyfor)
+ return wxPORT_UNKNOWN;
+
+ wxArrayString ports = wxSplit(onlyfor->GetNodeContent(), ',');
+ int nAvail = wxPORT_UNKNOWN;
+ for (unsigned int i=0; i < ports.GetCount(); i++)
+ {
+ if (!ports[i].StartsWith("wx")) {
+ LogError("unexpected port ID '%s'", ports[i]);
+ return false;
+ }
+
+ nAvail |= wxPlatformInfo::GetPortId(ports[i].Mid(2));
+ }
+
+ return nAvail;
+}
+
+
// ----------------------------------------------------------------------------
// wxXmlDoxygenInterface
// ----------------------------------------------------------------------------
@@ -1059,6 +1174,11 @@ bool wxXmlDoxygenInterface::ParseCompoundDefinition(const wxString& filename)
klass.SetHeader(subchild->GetNodeContent());
}*/
+ else if (subchild->GetName() == "detaileddescription")
+ {
+ // identify custom XML tags
+ klass.SetAvailability(GetAvailabilityFor(subchild));
+ }
subchild = subchild->GetNext();
}
@@ -1080,68 +1200,6 @@ bool wxXmlDoxygenInterface::ParseCompoundDefinition(const wxString& filename)
return true;
}
-static wxString GetTextFromChildren(const wxXmlNode *n)
-{
- wxString text;
-
- // consider the tree
- //
- // this is a string
- //
- //
- // |-
- // | |- this
- // |- is a
- // |-
- // |- string
- //
- // unlike wxXmlNode::GetNodeContent() which would return " is a "
- // this function returns "this is a string"
-
- wxXmlNode *ref = n->GetChildren();
- while (ref) {
- if (ref->GetType() == wxXML_ELEMENT_NODE)
- text += ref->GetNodeContent();
- else if (ref->GetType() == wxXML_TEXT_NODE)
- text += ref->GetContent();
- else
- LogWarning("Unexpected node type while getting text from '%s' node", n->GetName());
-
- ref = ref->GetNext();
- }
-
- return text;
-}
-
-static bool HasTextNodeContaining(const wxXmlNode *parent, const wxString& name)
-{
- wxXmlNode *p = parent->GetChildren();
- while (p)
- {
- switch (p->GetType())
- {
- case wxXML_TEXT_NODE:
- if (p->GetContent() == name)
- return true;
- break;
-
- case wxXML_ELEMENT_NODE:
- // recurse into this node...
- if (HasTextNodeContaining(p, name))
- return true;
- break;
-
- default:
- // skip it
- break;
- }
-
- p = p->GetNext();
- }
-
- return false;
-}
-
bool wxXmlDoxygenInterface::ParseMethod(const wxXmlNode* p, wxMethod& m, wxString& header)
{
wxArgumentTypeArray args;
@@ -1202,6 +1260,9 @@ bool wxXmlDoxygenInterface::ParseMethod(const wxXmlNode* p, wxMethod& m, wxStrin
// Doxygen outputs somewhere nested inside
// a Deprecated tag.
m.SetDeprecated(HasTextNodeContaining(child, "Deprecated"));
+
+ // identify custom XML tags
+ m.SetAvailability(GetAvailabilityFor(child));
}
child = child->GetNext();
diff --git a/utils/ifacecheck/src/xmlparser.h b/utils/ifacecheck/src/xmlparser.h
index 6e1de99a42..a593819279 100644
--- a/utils/ifacecheck/src/xmlparser.h
+++ b/utils/ifacecheck/src/xmlparser.h
@@ -114,7 +114,8 @@ class wxMethod
{
public:
wxMethod()
- { m_bConst=m_bVirtual=m_bPureVirtual=m_bStatic=m_bDeprecated=false; m_nLine=-1; }
+ { m_bConst=m_bVirtual=m_bPureVirtual=m_bStatic=m_bDeprecated=false;
+ m_nLine=-1; m_nAvailability=wxPORT_UNKNOWN; }
wxMethod(const wxType& rettype, const wxString& name,
const wxArgumentTypeArray& arguments,
@@ -138,6 +139,8 @@ public: // getters
{ return m_args; }
int GetLocation() const
{ return m_nLine; }
+ int GetAvailability() const
+ { return m_nAvailability; }
bool IsConst() const
{ return m_bConst; }
@@ -181,6 +184,8 @@ public: // setters
{ m_bDeprecated=c; }
void SetLocation(int lineNumber)
{ m_nLine=lineNumber; }
+ void SetAvailability(int nAvail)
+ { m_nAvailability=nAvail; }
public: // misc
@@ -194,12 +199,22 @@ protected:
wxType m_retType;
wxString m_strName;
wxArgumentTypeArray m_args;
+
+ // misc attributes:
bool m_bConst;
bool m_bStatic;
bool m_bVirtual;
bool m_bPureVirtual;
bool m_bDeprecated;
+
+ // m_nLine can be -1 if no location infos are available
int m_nLine;
+
+ // this is a combination of wxPORT_* flags (see wxPortId) or wxPORT_UNKNOWN
+ // if this method should be available for all wxWidgets ports.
+ // NOTE: this is not used for comparing wxMethod objects
+ // (gccXML never gives this kind of info).
+ int m_nAvailability;
};
WX_DECLARE_OBJARRAY(wxMethod, wxMethodArray);
@@ -216,18 +231,18 @@ public:
wxClass(const wxString& name, const wxString& headername)
: m_strName(name), m_strHeader(headername) {}
- void AddMethod(const wxMethod& func)
- { m_methods.Add(func); }
+
+public: // setters
void SetHeader(const wxString& header)
{ m_strHeader=header; }
void SetName(const wxString& name)
{ m_strName=name; }
- wxString GetName() const
- { return m_strName; }
- wxString GetHeader() const
- { return m_strHeader; }
- wxString GetNameWithoutTemplate() const;
+ void SetAvailability(int nAvail)
+ { m_nAvailability=nAvail; }
+
+
+public: // getters
bool IsOk() const
{ return !m_strName.IsEmpty() && !m_methods.IsEmpty(); }
@@ -235,6 +250,12 @@ public:
bool IsValidCtorForThisClass(const wxMethod& m) const;
bool IsValidDtorForThisClass(const wxMethod& m) const;
+ wxString GetName() const
+ { return m_strName; }
+ wxString GetHeader() const
+ { return m_strHeader; }
+ wxString GetNameWithoutTemplate() const;
+
unsigned int GetMethodCount() const
{ return m_methods.GetCount(); }
wxMethod& GetMethod(unsigned int n) const
@@ -242,6 +263,14 @@ public:
wxMethod& GetLastMethod() const
{ return m_methods.Last(); }
+ int GetAvailability() const
+ { return m_nAvailability; }
+
+public: // misc
+
+ void AddMethod(const wxMethod& func)
+ { m_methods.Add(func); }
+
// returns a single result (the first, which is also the only
// one if CheckConsistency() return true)
const wxMethod* FindMethod(const wxMethod& m) const;
@@ -260,6 +289,9 @@ protected:
wxString m_strName;
wxString m_strHeader;
wxMethodArray m_methods;
+
+ // see the wxMethod::m_nAvailability field for more info
+ int m_nAvailability;
};
WX_DECLARE_OBJARRAY(wxClass, wxClassArray);
@@ -333,12 +365,27 @@ typedef std::map wxTypeIdHashMap;
class wxXmlGccInterface : public wxXmlInterface
{
public:
- wxXmlGccInterface() {}
+ wxXmlGccInterface()
+ {
+ // FIXME: we should retrieve this from the XML file!
+ // here we suppose the XML was created for the currently-running port
+ m_portId = wxPlatformInfo::Get().GetPortId();
+ }
bool Parse(const wxString& filename);
bool ParseMethod(const wxXmlNode *p,
const wxTypeIdHashMap& types,
wxMethod& m);
+
+ wxPortId GetInterfacePort() const
+ { return m_portId; }
+
+ wxString GetInterfacePortName() const
+ { return wxPlatformInfo::GetPortIdName(m_portId, false); }
+
+protected:
+ // the port for which the gcc XML was generated
+ wxPortId m_portId;
};