initial commit

Signed-off-by: Peter Siegmund <mars3142@noreply.mars3142.dev>
This commit is contained in:
2025-10-31 23:37:30 +01:00
commit bf6b52fd94
9654 changed files with 4035664 additions and 0 deletions

View File

@@ -0,0 +1,55 @@
Ifacecheck utility
==================
1) INTRODUCTION
This utility compares the wxWidgets real interface contained in the "include"
hierarchy with the wxWidgets interface used for documentation purposes and
kept in the "interface" hierarchy.
Ifacecheck warns about incoherences (mainly wrong prototype signatures) and
can even correct them automatically. It uses the XML outputs of the gccxml utility
(see http://www.gccxml.org) and of the Doxygen utility (see http://www.doxygen.org)
to do the comparison.
It's explicitly designed for wxWidgets documentation needs and is probably of little
use for anything else than wxWidgets docs reviewing.
2) PREREQUISITES FOR USING IT
To use this utility you'll need at least:
- wxWidgets "include" and "interface" headers tree
- Doxygen installed
- Gccxml installed
3) HOW TO USE IT (on Linux)
First, create the doxygen XML:
> cd docs/doxygen
> ./regen.sh xml
> cd ../..
Next, create the gcc XML:
> ./configure # configure wxWidgets as you would do when building it
> cd utils/ifacecheck
> ./rungccxml.sh
> cd ../..
Last, build and run ifacecheck:
> cd utils/ifacecheck/src
> make
> make install
> cd ..
> ifacecheck -u wxapi-preproc.txt wxapi.xml ../../docs/doxygen/out/xml/index.xml >ifacecheck.log
Now you should have the log of the utility saved in 'ifacecheck.log'.
Its contents should be easy to interpret.
For more info about ifacecheck options just type:
> ifacecheck --help

View File

@@ -0,0 +1,343 @@
<!-- GCC_XML 0.7-cvs DTD Version 0.3 -->
<!-- Written by Paul Ross 2003-07-13 -->
<!-- Updated by Martin Piskernig 2004-11-14
* Some bugfixes (MP; 2004-11-18):
- added OffsetType attribute list
- Base cannot be child element of GCC_XML
- fixed Field::mutable to be of boolean type
- added "attributes" to destructor attlist
-->
<!ATTLIST Argument attributes CDATA #IMPLIED>
<!ATTLIST Argument default CDATA #IMPLIED>
<!ATTLIST Argument name CDATA #IMPLIED>
<!-- type can not be an IDREF as it might be "_4c" etc. which will be
an invalid id -->
<!ATTLIST Argument type CDATA #REQUIRED>
<!ATTLIST ArrayType align CDATA #IMPLIED>
<!ATTLIST ArrayType attributes CDATA #IMPLIED>
<!ATTLIST ArrayType id ID #REQUIRED>
<!ATTLIST ArrayType max CDATA #REQUIRED>
<!ATTLIST ArrayType min CDATA #FIXED "0">
<!ATTLIST ArrayType size CDATA #IMPLIED>
<!ATTLIST ArrayType type IDREF #REQUIRED>
<!ATTLIST Base access (public | private | protected) "public">
<!ATTLIST Base type IDREF #REQUIRED>
<!ATTLIST Base virtual (0 | 1) "0">
<!ATTLIST Class abstract (0 | 1) "0">
<!ATTLIST Class access (public | private | protected) "public">
<!ATTLIST Class align CDATA #IMPLIED>
<!ATTLIST Class artificial CDATA #IMPLIED>
<!ATTLIST Class attributes CDATA #IMPLIED>
<!ATTLIST Class bases CDATA #IMPLIED>
<!ATTLIST Class context IDREF #REQUIRED>
<!ATTLIST Class file CDATA #REQUIRED>
<!ATTLIST Class id ID #REQUIRED>
<!ATTLIST Class incomplete (0 | 1) "0">
<!ATTLIST Class line CDATA #REQUIRED>
<!ATTLIST Class location CDATA #REQUIRED>
<!ATTLIST Class mangled CDATA #REQUIRED>
<!ATTLIST Class members CDATA #IMPLIED>
<!ATTLIST Class name CDATA #REQUIRED>
<!ATTLIST Class size CDATA #IMPLIED>
<!ATTLIST Constructor access (public | private | protected) "public">
<!ATTLIST Constructor artificial CDATA #IMPLIED>
<!ATTLIST Constructor attributes CDATA #IMPLIED>
<!ATTLIST Constructor context CDATA #REQUIRED>
<!ATTLIST Constructor endline CDATA #IMPLIED>
<!ATTLIST Constructor extern (0 | 1) "0">
<!ATTLIST Constructor file CDATA #REQUIRED>
<!ATTLIST Constructor id ID #REQUIRED>
<!ATTLIST Constructor line CDATA #REQUIRED>
<!ATTLIST Constructor location CDATA #REQUIRED>
<!ATTLIST Constructor mangled CDATA #REQUIRED>
<!ATTLIST Constructor name CDATA #REQUIRED>
<!ATTLIST Constructor throw CDATA #IMPLIED>
<!ATTLIST Converter access (public | private | protected) "public">
<!ATTLIST Converter attributes CDATA #IMPLIED>
<!ATTLIST Converter const (0 | 1) "0">
<!ATTLIST Converter context IDREF #REQUIRED>
<!ATTLIST Converter endline CDATA #IMPLIED>
<!ATTLIST Converter extern (0 | 1) "0">
<!ATTLIST Converter file CDATA #REQUIRED>
<!ATTLIST Converter id ID #REQUIRED>
<!ATTLIST Converter line CDATA #REQUIRED>
<!ATTLIST Converter location CDATA #REQUIRED>
<!ATTLIST Converter mangled CDATA #REQUIRED>
<!ATTLIST Converter name CDATA #REQUIRED>
<!ATTLIST Converter returns IDREF #REQUIRED>
<!ATTLIST Converter throw CDATA #IMPLIED>
<!ATTLIST Converter virtual (0 | 1) "0">
<!ATTLIST CvQualifiedType align CDATA #IMPLIED>
<!ATTLIST CvQualifiedType attributes CDATA #IMPLIED>
<!ATTLIST CvQualifiedType const CDATA #IMPLIED>
<!ATTLIST CvQualifiedType id ID #REQUIRED>
<!ATTLIST CvQualifiedType restrict CDATA #IMPLIED>
<!ATTLIST CvQualifiedType size CDATA #IMPLIED>
<!ATTLIST CvQualifiedType type IDREF #REQUIRED>
<!ATTLIST CvQualifiedType volatile CDATA #IMPLIED>
<!ATTLIST Destructor access (public | private | protected) "public">
<!ATTLIST Destructor artificial CDATA #IMPLIED>
<!ATTLIST Destructor attributes CDATA #IMPLIED>
<!ATTLIST Destructor context IDREF #REQUIRED>
<!ATTLIST Destructor endline CDATA #IMPLIED>
<!ATTLIST Destructor extern (0 | 1) "0">
<!ATTLIST Destructor file CDATA #REQUIRED>
<!ATTLIST Destructor id ID #REQUIRED>
<!ATTLIST Destructor line CDATA #REQUIRED>
<!ATTLIST Destructor location CDATA #REQUIRED>
<!ATTLIST Destructor mangled CDATA #REQUIRED>
<!ATTLIST Destructor name CDATA #REQUIRED>
<!ATTLIST Destructor throw CDATA #IMPLIED>
<!ATTLIST Destructor virtual (0 | 1) "0">
<!ATTLIST EnumValue init CDATA #REQUIRED>
<!ATTLIST EnumValue name CDATA #REQUIRED>
<!ATTLIST Enumeration access (public | private | protected) "public">
<!ATTLIST Enumeration align CDATA #IMPLIED>
<!ATTLIST Enumeration artificial CDATA #IMPLIED>
<!ATTLIST Enumeration attributes CDATA #IMPLIED>
<!ATTLIST Enumeration context CDATA #REQUIRED>
<!ATTLIST Enumeration file CDATA #REQUIRED>
<!ATTLIST Enumeration id ID #REQUIRED>
<!ATTLIST Enumeration line CDATA #REQUIRED>
<!ATTLIST Enumeration location CDATA #REQUIRED>
<!ATTLIST Enumeration name CDATA #REQUIRED>
<!ATTLIST Enumeration size CDATA #IMPLIED>
<!ATTLIST Field access (public | private | protected) "public">
<!ATTLIST Field attributes CDATA #IMPLIED>
<!ATTLIST Field bits CDATA #IMPLIED>
<!ATTLIST Field context IDREF #REQUIRED>
<!ATTLIST Field file CDATA #REQUIRED>
<!ATTLIST Field id ID #REQUIRED>
<!ATTLIST Field line CDATA #REQUIRED>
<!ATTLIST Field location CDATA #REQUIRED>
<!ATTLIST Field mangled CDATA #IMPLIED>
<!ATTLIST Field mutable (0 | 1) "0">
<!ATTLIST Field name CDATA #REQUIRED>
<!ATTLIST Field offset CDATA #IMPLIED>
<!ATTLIST Field type CDATA #REQUIRED>
<!ATTLIST File id ID #REQUIRED>
<!ATTLIST File name CDATA #REQUIRED>
<!ATTLIST Function attributes CDATA #IMPLIED>
<!ATTLIST Function context IDREF #REQUIRED>
<!ATTLIST Function endline CDATA #IMPLIED>
<!ATTLIST Function extern (0 | 1) "0">
<!ATTLIST Function file CDATA #REQUIRED>
<!ATTLIST Function id ID #REQUIRED>
<!ATTLIST Function line CDATA #REQUIRED>
<!ATTLIST Function location CDATA #REQUIRED>
<!ATTLIST Function mangled CDATA #IMPLIED>
<!ATTLIST Function name CDATA #REQUIRED>
<!ATTLIST Function returns CDATA #REQUIRED>
<!ATTLIST Function throw CDATA #IMPLIED>
<!ATTLIST FunctionType attributes CDATA #IMPLIED>
<!ATTLIST FunctionType id ID #REQUIRED>
<!ATTLIST FunctionType returns IDREF #REQUIRED>
<!ATTLIST FundamentalType align CDATA #IMPLIED>
<!ATTLIST FundamentalType attributes CDATA #IMPLIED>
<!ATTLIST FundamentalType id ID #REQUIRED>
<!ATTLIST FundamentalType name CDATA #REQUIRED>
<!ATTLIST FundamentalType size CDATA #IMPLIED>
<!ATTLIST Method access (public | private | protected) "public">
<!ATTLIST Method attributes CDATA #IMPLIED>
<!ATTLIST Method const (0 | 1) "0">
<!ATTLIST Method context IDREF #REQUIRED>
<!ATTLIST Method endline CDATA #IMPLIED>
<!ATTLIST Method extern (0 | 1) "0">
<!ATTLIST Method file CDATA #REQUIRED>
<!ATTLIST Method id ID #REQUIRED>
<!ATTLIST Method line CDATA #REQUIRED>
<!ATTLIST Method location CDATA #REQUIRED>
<!ATTLIST Method mangled CDATA #REQUIRED>
<!ATTLIST Method name CDATA #REQUIRED>
<!ATTLIST Method pure_virtual (0 | 1) "0">
<!ATTLIST Method returns CDATA #REQUIRED>
<!ATTLIST Method static (0 | 1) "0">
<!ATTLIST Method throw CDATA #IMPLIED>
<!ATTLIST Method virtual (0 | 1) "0">
<!ATTLIST MethodType attributes CDATA #IMPLIED>
<!ATTLIST MethodType basetype IDREF #REQUIRED>
<!ATTLIST MethodType id ID #REQUIRED>
<!ATTLIST MethodType returns CDATA #REQUIRED>
<!ATTLIST Namespace attributes CDATA #IMPLIED>
<!ATTLIST Namespace context IDREF #IMPLIED>
<!ATTLIST Namespace id ID #REQUIRED>
<!ATTLIST Namespace mangled CDATA #IMPLIED>
<!ATTLIST Namespace members CDATA #IMPLIED>
<!ATTLIST Namespace name CDATA #REQUIRED>
<!ATTLIST NamespaceAlias context IDREF #IMPLIED>
<!ATTLIST NamespaceAlias id ID #REQUIRED>
<!ATTLIST NamespaceAlias mangled CDATA #IMPLIED>
<!ATTLIST NamespaceAlias name CDATA #REQUIRED>
<!ATTLIST NamespaceAlias namespace CDATA #REQUIRED>
<!ATTLIST OffsetType align CDATA #IMPLIED>
<!ATTLIST OffsetType attributes CDATA #IMPLIED>
<!ATTLIST OffsetType id ID #REQUIRED>
<!ATTLIST OffsetType basetype IDREF #REQUIRED>
<!ATTLIST OffsetType size CDATA #IMPLIED>
<!ATTLIST OffsetType type CDATA #REQUIRED>
<!ATTLIST OperatorFunction attributes CDATA #IMPLIED>
<!ATTLIST OperatorFunction context IDREF #REQUIRED>
<!ATTLIST OperatorFunction endline CDATA #IMPLIED>
<!ATTLIST OperatorFunction extern (0 | 1) "0">
<!ATTLIST OperatorFunction file CDATA #REQUIRED>
<!ATTLIST OperatorFunction id ID #REQUIRED>
<!ATTLIST OperatorFunction line CDATA #REQUIRED>
<!ATTLIST OperatorFunction location CDATA #REQUIRED>
<!ATTLIST OperatorFunction mangled CDATA #REQUIRED>
<!ATTLIST OperatorFunction name CDATA #REQUIRED>
<!ATTLIST OperatorFunction returns IDREF #REQUIRED>
<!ATTLIST OperatorFunction throw CDATA #IMPLIED>
<!ATTLIST OperatorMethod access (public | private | protected) "public">
<!ATTLIST OperatorMethod attributes CDATA #IMPLIED>
<!ATTLIST OperatorMethod const (0 | 1) "0">
<!ATTLIST OperatorMethod context IDREF #REQUIRED>
<!ATTLIST OperatorMethod endline CDATA #IMPLIED>
<!ATTLIST OperatorMethod extern (0 | 1) "0">
<!ATTLIST OperatorMethod file CDATA #REQUIRED>
<!ATTLIST OperatorMethod id ID #REQUIRED>
<!ATTLIST OperatorMethod line CDATA #REQUIRED>
<!ATTLIST OperatorMethod location CDATA #REQUIRED>
<!ATTLIST OperatorMethod mangled CDATA #REQUIRED>
<!ATTLIST OperatorMethod name CDATA #REQUIRED>
<!ATTLIST OperatorMethod pure_virtual (0 | 1) "0">
<!ATTLIST OperatorMethod returns IDREF #REQUIRED>
<!ATTLIST OperatorMethod static (0 | 1) "0">
<!ATTLIST OperatorMethod throw CDATA #IMPLIED>
<!ATTLIST OperatorMethod virtual (0 | 1) "0">
<!ATTLIST PointerType align CDATA #IMPLIED>
<!ATTLIST PointerType attributes CDATA #IMPLIED>
<!ATTLIST PointerType id ID #REQUIRED>
<!ATTLIST PointerType size CDATA #IMPLIED>
<!ATTLIST PointerType type CDATA #REQUIRED>
<!ATTLIST ReferenceType align CDATA #IMPLIED>
<!ATTLIST ReferenceType attributes CDATA #IMPLIED>
<!ATTLIST ReferenceType id ID #REQUIRED>
<!ATTLIST ReferenceType size CDATA #IMPLIED>
<!ATTLIST ReferenceType type CDATA #REQUIRED>
<!ATTLIST Struct abstract (0 | 1) "0">
<!ATTLIST Struct access (public | private | protected) "public">
<!ATTLIST Struct align CDATA #IMPLIED>
<!ATTLIST Struct artificial (0 | 1) "0">
<!ATTLIST Struct attributes CDATA #IMPLIED>
<!ATTLIST Struct bases CDATA #IMPLIED>
<!ATTLIST Struct context IDREF #REQUIRED>
<!ATTLIST Struct file CDATA #REQUIRED>
<!ATTLIST Struct id ID #REQUIRED>
<!ATTLIST Struct incomplete (0 | 1) "0">
<!ATTLIST Struct line CDATA #REQUIRED>
<!ATTLIST Struct location CDATA #REQUIRED>
<!ATTLIST Struct mangled CDATA #REQUIRED>
<!ATTLIST Struct members CDATA #IMPLIED>
<!ATTLIST Struct name CDATA #IMPLIED>
<!ATTLIST Struct size CDATA #IMPLIED>
<!ATTLIST Typedef attributes CDATA #IMPLIED>
<!ATTLIST Typedef context IDREF #REQUIRED>
<!ATTLIST Typedef file CDATA #REQUIRED>
<!ATTLIST Typedef id ID #REQUIRED>
<!ATTLIST Typedef line CDATA #REQUIRED>
<!ATTLIST Typedef location CDATA #REQUIRED>
<!ATTLIST Typedef name CDATA #REQUIRED>
<!ATTLIST Typedef type CDATA #REQUIRED>
<!ATTLIST Unimplemented function CDATA #IMPLIED>
<!ATTLIST Unimplemented id ID #REQUIRED>
<!ATTLIST Unimplemented node CDATA #REQUIRED>
<!ATTLIST Unimplemented tree_code (187 | 190 | 193) #REQUIRED>
<!ATTLIST Unimplemented tree_code_name (template_type_parm |
typename_type | using_decl) #REQUIRED>
<!ATTLIST Union abstract (0 | 1) "0">
<!ATTLIST Union access (public | private | protected) "public">
<!ATTLIST Union align CDATA #IMPLIED>
<!ATTLIST Union artificial (0 | 1) "0">
<!ATTLIST Union attributes CDATA #IMPLIED>
<!ATTLIST Union bases CDATA #IMPLIED>
<!ATTLIST Union context IDREF #REQUIRED>
<!ATTLIST Union file CDATA #REQUIRED>
<!ATTLIST Union id ID #REQUIRED>
<!ATTLIST Union incomplete (0 | 1) "0">
<!ATTLIST Union line CDATA #REQUIRED>
<!ATTLIST Union location CDATA #REQUIRED>
<!ATTLIST Union mangled CDATA #REQUIRED>
<!ATTLIST Union members CDATA #IMPLIED>
<!ATTLIST Union name CDATA #IMPLIED>
<!ATTLIST Union size CDATA #IMPLIED>
<!ATTLIST Variable access (public | private | protected) "public">
<!ATTLIST Variable artificial CDATA #IMPLIED>
<!ATTLIST Variable attributes CDATA #IMPLIED>
<!ATTLIST Variable context IDREF #REQUIRED>
<!ATTLIST Variable extern (0 | 1) "0">
<!ATTLIST Variable file CDATA #REQUIRED>
<!ATTLIST Variable id ID #REQUIRED>
<!ATTLIST Variable init CDATA #IMPLIED>
<!ATTLIST Variable line CDATA #REQUIRED>
<!ATTLIST Variable location CDATA #REQUIRED>
<!ATTLIST Variable mangled CDATA #IMPLIED>
<!ATTLIST Variable name CDATA #REQUIRED>
<!ATTLIST Variable type CDATA #REQUIRED>
<!ATTLIST GCC_XML cvs_revision CDATA #IMPLIED>
<!ELEMENT Argument EMPTY>
<!ELEMENT Ellipsis EMPTY>
<!ELEMENT ArrayType EMPTY>
<!ELEMENT Base EMPTY>
<!ELEMENT Class (Base)*>
<!ELEMENT Constructor (Argument | Ellipsis)*>
<!ELEMENT Converter EMPTY>
<!ELEMENT CvQualifiedType EMPTY>
<!ELEMENT Destructor (Argument)*> <!-- FIXME -->
<!ELEMENT EnumValue EMPTY>
<!ELEMENT Enumeration (EnumValue)+>
<!ELEMENT Field EMPTY>
<!ELEMENT File EMPTY>
<!ELEMENT Function (Argument | Ellipsis)*>
<!ELEMENT FunctionType (Argument | Ellipsis)*>
<!ELEMENT FundamentalType EMPTY>
<!ELEMENT Method (Argument | Ellipsis)*>
<!ELEMENT MethodType (Argument | Ellipsis)*>
<!ELEMENT Namespace EMPTY>
<!ELEMENT NamespaceAlias EMPTY>
<!ELEMENT OffsetType EMPTY>
<!ELEMENT OperatorFunction (Argument | Ellipsis)*>
<!ELEMENT OperatorMethod (Argument | Ellipsis)*>
<!ELEMENT PointerType EMPTY>
<!ELEMENT ReferenceType EMPTY>
<!ELEMENT Struct (Base)*>
<!ELEMENT Typedef EMPTY>
<!ELEMENT Unimplemented EMPTY>
<!ELEMENT Union (Base)*>
<!ELEMENT Variable EMPTY>
<!ELEMENT GCC_XML (ArrayType | Class | Constructor | Converter | CvQualifiedType |
Destructor | Enumeration | Field | File | Function | FunctionType |
FundamentalType | Method | MethodType | Namespace | NamespaceAlias | OperatorFunction
| OperatorMethod | OffsetType | PointerType | ReferenceType | Struct | Typedef |
Unimplemented | Union | Variable)+>

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,83 @@
#!/bin/bash
#
# Runs gccxml on the wxWidgets include folder, in order to build the XML
# file to fetch to ifacecheck to check the coherency of the wxWidgets
# interface headers with the "real" ones.
## CONSTANTS
############
gccxmloutput="wxapi.xml" # the file where we store the gccXML output
preprocoutput="wxapi-preproc.txt" # the file where we store the preprocessor's #define values
allheaders="/tmp/wx-all.h" # the header which includes all wx public headers (autogenerated)
# the list of all wxWidgets public headers
listcmd="ls wx/*.h wx/aui/*.h wx/html/*.h wx/protocol/*.h wx/richtext/*.h wx/stc/*.h wx/xml/*.h wx/xrc/*.h"
## MAIN
#######
if [[ ! -z "$1" ]]; then
echo "This script does not accept arguments."
echo "Usage: $0"
echo "Creates a '$gccxmloutput' file which you can pass to ifacecheck."
exit 1
fi
me=$(basename $0)
current=$(pwd)/${0%%/$me} # current path
gccxmloutput="$current/$gccxmloutput"
cd @top_srcdir@/include # go to wx include folder
# now filter it
headerlist=`$listcmd | grep -v wxshl | grep -v wx_cw | grep -v setup | grep -v xti | grep -v dde.h | grep -v fmappriv`
cd $current # return to the original path
# create the header file to pass to gccxml
echo "Creating the $allheaders dummy file which #includes all wxWidgets interface header files..."
if [[ -f $allheaders ]]; then rm $allheaders; fi
for f in $headerlist; do
echo "#include <$f>" >> $allheaders
done
# filter the configure flags to pass to gccxml
wx_top_builddir="@wx_top_builddir@"
top_srcdir="@top_srcdir@"
flags="@CPPFLAGS@ @CXXFLAGS@"
# NOTE: it's important to define __WXDEBUG__ because some functions of wx
# are declared (and thus parsed by gcc) only if that symbol is defined.
# So we remove it from $flags (in case it's defined) and then readd it.
flags=`echo "$flags" | sed -e 's/-pthread//g' | sed -e 's/__WXDEBUG__//g'`
# append some other flags:
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... results in $gccxmloutput"
if [[ -f "$gccxmloutput" ]]; then rm $gccxmloutput; fi
gccxml $flags -fxml=$gccxmloutput
if [[ $? != 0 ]]; then
echo "Errors running gccxml... aborting."
exit
fi
# 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... results in $preprocoutput"
gccxml -E -dM $flags >$preprocoutput
if [[ $? != 0 ]]; then
echo "Errors running gccxml preprocessor... aborting."
exit
fi
# cleanup
rm $allheaders

View File

@@ -0,0 +1,132 @@
# =========================================================================
# This makefile was generated by
# Bakefile 0.2.13 (http://www.bakefile.org)
# Do not modify, all changes will be overwritten!
# =========================================================================
@MAKE_SET@
prefix = @prefix@
exec_prefix = @exec_prefix@
datarootdir = @datarootdir@
INSTALL = @INSTALL@
EXEEXT = @EXEEXT@
STRIP = @STRIP@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_DIR = @INSTALL_DIR@
BK_DEPS = @BK_DEPS@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
bindir = @bindir@
LIBS = @LIBS@
CXX = @CXX@
CXXFLAGS = @CXXFLAGS@
CPPFLAGS = @CPPFLAGS@
LDFLAGS = @LDFLAGS@
WX_LIB_FLAVOUR = @WX_LIB_FLAVOUR@
TOOLKIT = @TOOLKIT@
TOOLKIT_LOWERCASE = @TOOLKIT_LOWERCASE@
TOOLKIT_VERSION = @TOOLKIT_VERSION@
EXTRALIBS = @EXTRALIBS@
EXTRALIBS_XML = @EXTRALIBS_XML@
EXTRALIBS_GUI = @EXTRALIBS_GUI@
WX_CPPFLAGS = @WX_CPPFLAGS@
WX_CXXFLAGS = @WX_CXXFLAGS@
WX_LDFLAGS = @WX_LDFLAGS@
HOST_SUFFIX = @HOST_SUFFIX@
DYLIB_RPATH_FLAG = @DYLIB_RPATH_FLAG@
wx_top_builddir = @wx_top_builddir@
### Variables: ###
DESTDIR =
WX_RELEASE = 3.3
LIBDIRNAME = $(wx_top_builddir)/lib
IFACECHECK_CXXFLAGS = $(WX_CPPFLAGS) -D__WX$(TOOLKIT)__ $(__WXUNIV_DEFINE_p) \
$(__DEBUG_DEFINE_p) $(__EXCEPTIONS_DEFINE_p) $(__RTTI_DEFINE_p) \
$(__THREAD_DEFINE_p) -I$(srcdir) $(__DLLFLAG_p) -DwxUSE_GUI=0 $(WX_CXXFLAGS) \
$(CPPFLAGS) $(CXXFLAGS)
IFACECHECK_OBJECTS = \
ifacecheck_ifacecheck.o \
ifacecheck_xmlparser.o
### Conditionally set variables: ###
@COND_DEPS_TRACKING_0@CXXC = $(CXX)
@COND_DEPS_TRACKING_1@CXXC = $(BK_DEPS) $(CXX)
@COND_USE_GUI_0@PORTNAME = base
@COND_USE_GUI_1@PORTNAME = $(TOOLKIT_LOWERCASE)$(TOOLKIT_VERSION)
@COND_TOOLKIT_MAC@WXBASEPORT = _carbon
@COND_BUILD_debug@WXDEBUGFLAG = d
@COND_WXUNIV_1@WXUNIVNAME = univ
@COND_MONOLITHIC_0@EXTRALIBS_FOR_BASE = $(EXTRALIBS)
@COND_MONOLITHIC_1@EXTRALIBS_FOR_BASE = $(EXTRALIBS) \
@COND_MONOLITHIC_1@ $(EXTRALIBS_XML) $(EXTRALIBS_GUI)
@COND_WXUNIV_1@__WXUNIV_DEFINE_p = -D__WXUNIVERSAL__
@COND_DEBUG_FLAG_0@__DEBUG_DEFINE_p = -DwxDEBUG_LEVEL=0
@COND_USE_EXCEPTIONS_0@__EXCEPTIONS_DEFINE_p = -DwxNO_EXCEPTIONS
@COND_USE_RTTI_0@__RTTI_DEFINE_p = -DwxNO_RTTI
@COND_USE_THREADS_0@__THREAD_DEFINE_p = -DwxNO_THREADS
@COND_SHARED_1@__DLLFLAG_p = -DWXUSINGDLL
COND_MONOLITHIC_0___WXLIB_XML_p = \
-lwx_base$(WXBASEPORT)u$(WXDEBUGFLAG)$(WX_LIB_FLAVOUR)_xml-$(WX_RELEASE)$(HOST_SUFFIX)
@COND_MONOLITHIC_0@__WXLIB_XML_p = $(COND_MONOLITHIC_0___WXLIB_XML_p)
COND_MONOLITHIC_0___WXLIB_BASE_p = \
-lwx_base$(WXBASEPORT)u$(WXDEBUGFLAG)$(WX_LIB_FLAVOUR)-$(WX_RELEASE)$(HOST_SUFFIX)
@COND_MONOLITHIC_0@__WXLIB_BASE_p = $(COND_MONOLITHIC_0___WXLIB_BASE_p)
COND_MONOLITHIC_1___WXLIB_MONO_p = \
-lwx_$(PORTNAME)$(WXUNIVNAME)u$(WXDEBUGFLAG)$(WX_LIB_FLAVOUR)-$(WX_RELEASE)$(HOST_SUFFIX)
@COND_MONOLITHIC_1@__WXLIB_MONO_p = $(COND_MONOLITHIC_1___WXLIB_MONO_p)
@COND_MONOLITHIC_1@__LIB_PNG_IF_MONO_p = $(__LIB_PNG_p)
@COND_USE_GUI_1_wxUSE_LIBPNG_builtin@__LIB_PNG_p \
@COND_USE_GUI_1_wxUSE_LIBPNG_builtin@ = \
@COND_USE_GUI_1_wxUSE_LIBPNG_builtin@ -lwxpng$(WXDEBUGFLAG)$(WX_LIB_FLAVOUR)-$(WX_RELEASE)$(HOST_SUFFIX)
@COND_wxUSE_ZLIB_builtin@__LIB_ZLIB_p = \
@COND_wxUSE_ZLIB_builtin@ -lwxzlib$(WXDEBUGFLAG)$(WX_LIB_FLAVOUR)-$(WX_RELEASE)$(HOST_SUFFIX)
@COND_wxUSE_REGEX_builtin@__LIB_REGEX_p = \
@COND_wxUSE_REGEX_builtin@ -lwxregexu$(WXDEBUGFLAG)$(WX_LIB_FLAVOUR)-$(WX_RELEASE)$(HOST_SUFFIX)
@COND_wxUSE_EXPAT_builtin@__LIB_EXPAT_p = \
@COND_wxUSE_EXPAT_builtin@ -lwxexpat$(WXDEBUGFLAG)$(WX_LIB_FLAVOUR)-$(WX_RELEASE)$(HOST_SUFFIX)
### Targets: ###
all: ifacecheck$(EXEEXT)
install: install_ifacecheck
uninstall: uninstall_ifacecheck
install-strip: install
$(STRIP) $(DESTDIR)$(bindir)/ifacecheck$(EXEEXT)
clean:
rm -rf ./.deps ./.pch
rm -f ./*.o
rm -f ifacecheck$(EXEEXT)
distclean: clean
rm -f config.cache config.log config.status bk-deps bk-make-pch Makefile
ifacecheck$(EXEEXT): $(IFACECHECK_OBJECTS)
$(CXX) -o $@ $(IFACECHECK_OBJECTS) -L$(LIBDIRNAME) $(DYLIB_RPATH_FLAG) $(LDFLAGS) $(WX_LDFLAGS) $(__WXLIB_XML_p) $(EXTRALIBS_XML) $(__WXLIB_BASE_p) $(__WXLIB_MONO_p) $(__LIB_PNG_IF_MONO_p) $(__LIB_ZLIB_p) $(__LIB_REGEX_p) $(__LIB_EXPAT_p) $(EXTRALIBS_FOR_BASE) $(LIBS)
install_ifacecheck: ifacecheck$(EXEEXT)
$(INSTALL_DIR) $(DESTDIR)$(bindir)
$(INSTALL_PROGRAM) ifacecheck$(EXEEXT) $(DESTDIR)$(bindir)
uninstall_ifacecheck:
rm -f $(DESTDIR)$(bindir)/ifacecheck$(EXEEXT)
ifacecheck_ifacecheck.o: $(srcdir)/ifacecheck.cpp
$(CXXC) -c -o $@ $(IFACECHECK_CXXFLAGS) $(srcdir)/ifacecheck.cpp
ifacecheck_xmlparser.o: $(srcdir)/xmlparser.cpp
$(CXXC) -c -o $@ $(IFACECHECK_CXXFLAGS) $(srcdir)/xmlparser.cpp
# Include dependency info, if present:
@IF_GNU_MAKE@-include ./.deps/*.d
.PHONY: all install uninstall clean distclean install_ifacecheck \
uninstall_ifacecheck

View File

@@ -0,0 +1,19 @@
<?xml version="1.0" ?>
<makefile>
<include file="../../../build/bakefiles/common_samples.bkl"/>
<exe id="ifacecheck" template="wx_util_console" template_append="wx_append_base">
<sources>
ifacecheck.cpp
xmlparser.cpp
</sources>
<headers>xmlparser.h</headers>
<wx-lib>xml</wx-lib>
<wx-lib>base</wx-lib>
<install-to>$(BINDIR)</install-to>
</exe>
</makefile>

View File

@@ -0,0 +1,685 @@
/////////////////////////////////////////////////////////////////////////////
// Name: ifacecheck.cpp
// Purpose: Interface headers <=> real headers coherence checker
// Author: Francesco Montorsi
// Created: 2008/03/17
// Copyright: (c) 2008 Francesco Montorsi
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
// For compilers that support precompilation, includes "wx/wx.h".
#include "wx/wxprec.h"
// for all others, include the necessary headers
#ifndef WX_PRECOMP
#include "wx/app.h"
#include "wx/crt.h"
#endif
#include "wx/cmdline.h"
#include "wx/textfile.h"
#include "wx/filename.h"
#include "wx/stopwatch.h" // for wxGetLocalTime
#include "xmlparser.h"
// global verbosity flag
bool g_verbose = false;
// ----------------------------------------------------------------------------
// IfaceCheckApp
// ----------------------------------------------------------------------------
#define API_DUMP_FILE "dump.api.txt"
#define INTERFACE_DUMP_FILE "dump.interface.txt"
#define PROCESS_ONLY_OPTION "p"
#define USE_PREPROCESSOR_OPTION "u"
#define MODIFY_SWITCH "m"
#define DUMP_SWITCH "d"
#define HELP_SWITCH "h"
#define VERBOSE_SWITCH "v"
static const wxCmdLineEntryDesc g_cmdLineDesc[] =
{
{ wxCMD_LINE_OPTION, USE_PREPROCESSOR_OPTION, "use-preproc",
"uses the preprocessor output to increase the checker accuracy",
wxCMD_LINE_VAL_STRING, wxCMD_LINE_NEEDS_SEPARATOR },
{ wxCMD_LINE_OPTION, PROCESS_ONLY_OPTION, "process-only",
"processes only header files matching the given wildcard",
wxCMD_LINE_VAL_STRING, wxCMD_LINE_NEEDS_SEPARATOR },
{ wxCMD_LINE_SWITCH, MODIFY_SWITCH, "modify",
"modify the interface headers to match the real ones" },
{ wxCMD_LINE_SWITCH, DUMP_SWITCH, "dump",
"dump both interface and API to plain text dump.*.txt files" },
{ wxCMD_LINE_SWITCH, HELP_SWITCH, "help",
"show help message", wxCMD_LINE_VAL_NONE, wxCMD_LINE_OPTION_HELP },
{ wxCMD_LINE_SWITCH, VERBOSE_SWITCH, "verbose",
"be verbose" },
{ wxCMD_LINE_PARAM, nullptr, nullptr,
"gccXML", wxCMD_LINE_VAL_STRING, wxCMD_LINE_OPTION_MANDATORY },
{ wxCMD_LINE_PARAM, nullptr, nullptr,
"doxygenXML", wxCMD_LINE_VAL_STRING, wxCMD_LINE_OPTION_MANDATORY },
wxCMD_LINE_DESC_END
};
class IfaceCheckLog : public wxLog
{
public:
IfaceCheckLog() {}
virtual void DoLogText(const wxString& msg)
{
// send all messages to stdout (normal behaviour is to sent them to stderr)
wxPuts(msg);
fflush(stdout);
}
};
class IfaceCheckApp : public wxAppConsole
{
public:
// don't use builtin cmd line parsing:
virtual bool OnInit() { m_modify=false; return true; }
virtual int OnRun();
bool ParsePreprocessorOutput(const wxString& filename);
bool Compare();
int CompareClasses(const wxClass* iface, const wxClass* api);
bool FixMethod(const wxString& header, const wxMethod* iface, const wxMethod* api);
bool StringContainsMethodName(const wxString& str, const wxMethod* m);
void PrintStatistics(long secs);
bool IsToProcess(const wxString& headername) const
{
if (m_strToMatch.IsEmpty())
return true;
return wxMatchWild(m_strToMatch, headername, false);
}
protected:
wxXmlGccInterface m_gccInterface; // "real" headers API
wxXmlDoxygenInterface m_doxyInterface; // doxygen-commented headers API
// was the MODIFY_SWITCH passed?
bool m_modify;
// if non-empty, then PROCESS_ONLY_OPTION was passed and this is the
// wildcard expression to match
wxString m_strToMatch;
};
wxIMPLEMENT_APP_CONSOLE(IfaceCheckApp);
int IfaceCheckApp::OnRun()
{
long startTime = wxGetLocalTime(); // for timing purpose
wxCmdLineParser parser(g_cmdLineDesc, argc, argv);
parser.SetLogo(
wxString::Format("wxWidgets Interface checker utility (built %s against %s)",
__DATE__, wxVERSION_STRING));
// make the output more readable:
wxLog::SetActiveTarget(new IfaceCheckLog);
wxLog::DisableTimestamp();
// parse the command line...
bool ok = true;
wxString preprocFile;
switch (parser.Parse())
{
case 0:
if (parser.Found(VERBOSE_SWITCH))
g_verbose = true;
// IMPORTANT: parsing #define values must be done _before_ actually
// parsing the GCC/doxygen XML files
if (parser.Found(USE_PREPROCESSOR_OPTION, &preprocFile))
{
if (!ParsePreprocessorOutput(preprocFile))
return 1;
}
// in any case set basic std preprocessor #defines:
m_doxyInterface.AddPreprocessorValue("NULL", "0");
// 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;
if (parser.Found(DUMP_SWITCH))
{
wxLogMessage("Dumping real API to '%s'...", API_DUMP_FILE);
m_gccInterface.Dump(API_DUMP_FILE);
wxLogMessage("Dumping interface API to '%s'...", INTERFACE_DUMP_FILE);
m_doxyInterface.Dump(INTERFACE_DUMP_FILE);
}
else
{
if (parser.Found(MODIFY_SWITCH))
m_modify = true;
if (parser.Found(PROCESS_ONLY_OPTION, &m_strToMatch))
{
size_t len = m_strToMatch.Len();
if (m_strToMatch.StartsWith("\"") &&
m_strToMatch.EndsWith("\"") &&
len > 2)
m_strToMatch = m_strToMatch.Mid(1, len-2);
}
ok = Compare();
}
PrintStatistics(wxGetLocalTime() - startTime);
return ok ? 0 : 1;
default:
wxPrintf("\nThis utility checks that the interface XML files created by Doxygen are in\n");
wxPrintf("synch with the real headers (whose contents are extracted by the gcc XML file).\n\n");
wxPrintf("The 'gccXML' parameter should be the wxapi.xml file created by the 'rungccxml.sh'\n");
wxPrintf("script which resides in 'utils/ifacecheck'.\n");
wxPrintf("The 'doxygenXML' parameter should be the index.xml file created by Doxygen\n");
wxPrintf("for the wxWidgets 'interface' folder.\n\n");
wxPrintf("Since the gcc XML file does not contain info about #defines, if you use\n");
wxPrintf("the -%s option, you'll get a smaller number of false warnings.\n",
USE_PREPROCESSOR_OPTION);
// HELP_SWITCH was passed or a syntax error occurred
return 0;
}
}
bool IfaceCheckApp::Compare()
{
const wxClassArray& interfaces = m_doxyInterface.GetClasses();
const wxClass* c;
int mcount = 0, ccount = 0;
wxLogMessage("Comparing the interface API to the real API (%d classes to compare)...",
interfaces.GetCount());
if (!m_strToMatch.IsEmpty())
{
wxLogMessage("Processing only header files matching '%s' expression.", m_strToMatch);
}
for (unsigned int i=0; i<interfaces.GetCount(); i++)
{
// only compare the methods which are available for the port
// for which the gcc XML was produced
if (interfaces[i].GetAvailability() != wxPORT_UNKNOWN &&
(interfaces[i].GetAvailability() & m_gccInterface.GetInterfacePort()) == 0) {
if (g_verbose)
{
wxLogMessage("skipping class '%s' since it's not available for the %s port.",
interfaces[i].GetName(), m_gccInterface.GetInterfacePortName());
}
continue; // skip this method
}
// shorten the name of the header so the log file is more readable
// and also for calling IsToProcess() against it
wxString header = wxFileName(interfaces[i].GetHeader()).GetFullName();
if (!IsToProcess(header))
continue; // skip this one
wxString cname = interfaces[i].GetName();
// search in the real headers for i-th interface class; we search for
// both class cname and cnameBase since in wxWidgets world tipically
// class cname is platform-specific while the real public interface of
// that class is part of the cnameBase class.
/*c = m_gccInterface.FindClass(cname + "Base");
if (c) api.Add(c);*/
c = m_gccInterface.FindClass(cname);
if (!c)
{
// sometimes the platform-specific class is named "wxGeneric" + cname
// or similar:
c = m_gccInterface.FindClass("wxGeneric" + cname.Mid(2));
if (!c)
{
c = m_gccInterface.FindClass("wxGtk" + cname.Mid(2));
}
}
if (c) {
// there is a class with the same (logic) name!
mcount += CompareClasses(&interfaces[i], c);
} else {
wxLogMessage("%s: couldn't find the real interface for the '%s' class",
header, cname);
ccount++;
}
}
wxLogMessage("%d on a total of %d methods (%.1f%%) of the interface headers do not exist in the real headers",
mcount, m_doxyInterface.GetMethodCount(), (float)(100.0 * mcount/m_doxyInterface.GetMethodCount()));
wxLogMessage("%d on a total of %d classes (%.1f%%) of the interface headers do not exist in the real headers",
ccount, m_doxyInterface.GetClassesCount(), (float)(100.0 * ccount/m_doxyInterface.GetClassesCount()));
return true;
}
int IfaceCheckApp::CompareClasses(const wxClass* iface, const wxClass* api)
{
const wxMethod *real;
int count = 0;
wxASSERT(iface && api);
// shorten the name of the header so the log file is more readable
wxString header = wxFileName(iface->GetHeader()).GetFullName();
for (unsigned int i=0; i<iface->GetMethodCount(); i++)
{
const wxMethod& m = iface->GetMethod(i);
// 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)
{
wxLogMessage("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
real = api->RecursiveUpwardFindMethod(m, &m_gccInterface);
// avoid some false positives:
if (!real && m.ActsAsDefaultCtor())
{
// build an artificial default ctor for this class:
wxMethod temp(m);
temp.GetArgumentTypes().Clear();
// repeat search:
real = api->RecursiveUpwardFindMethod(temp, &m_gccInterface);
}
// no matches?
if (!real)
{
bool proceed = true;
wxMethodPtrArray overloads =
api->RecursiveUpwardFindMethodsNamed(m.GetName(), &m_gccInterface);
// avoid false positives:
for (unsigned int k=0; k<overloads.GetCount(); k++)
if (overloads[k]->MatchesExceptForAttributes(m) &&
m.IsDeprecated() && !overloads[k]->IsDeprecated())
{
// maybe the iface method is marked as deprecated but the
// real method is not?
wxMethod tmp(*overloads[k]);
tmp.SetDeprecated(true);
if (tmp == m)
{
// in this case, we can disregard this warning... the real
// method probably is included in WXWIN_COMPAT sections!
proceed = false; // skip this method
}
}
#define HACK_TO_AUTO_CORRECT_ONLY_METHOD_ATTRIBUTES 0
#if HACK_TO_AUTO_CORRECT_ONLY_METHOD_ATTRIBUTES
for (unsigned int k=0; k<overloads.GetCount(); k++)
if (overloads[k]->MatchesExceptForAttributes(m))
{
// fix default values of results[k]:
wxMethod tmp(*overloads[k]);
tmp.SetArgumentTypes(m.GetArgumentTypes());
// modify interface header
if (FixMethod(iface->GetHeader(), &m, &tmp))
{
wxLogMessage("Adjusted attributes of '%s' method", m.GetAsString());
}
proceed = false;
break;
}
#endif // HACK_TO_AUTO_CORRECT_ONLY_METHOD_ATTRIBUTES
if (proceed)
{
if (overloads.GetCount()==0)
{
wxLogMessage("%s: real '%s' class and their parents have no method '%s'",
header, api->GetName(), m.GetAsString());
// we've found no overloads
}
else
{
// first, output a warning
wxString warning = header;
if (overloads.GetCount()>1)
warning += wxString::Format(": in the real headers there are %d overloads of '%s' for "
"'%s' all with different signatures:\n",
overloads.GetCount(), m.GetName(), api->GetName());
else {
warning += wxString::Format(": in the real headers there is a method '%s' for '%s'"
" but has different signature:\n",
m.GetName(), api->GetName());
}
// get a list of the prototypes with _all_ possible attributes:
warning += "\tdoxy header: " + m.GetAsString(true, true, true, true);
for (unsigned int j=0; j<overloads.GetCount(); j++)
warning += "\n\treal header: " + overloads[j]->GetAsString(true, true, true, true);
wxLogWarning(warning);
count++;
if (overloads.GetCount()>1)
{
// TODO: decide which of these overloads is the most "similar" to m
// and eventually modify it
if (m_modify)
{
wxLogWarning("\tmanual fix is required");
}
}
else
{
wxASSERT(overloads.GetCount() == 1);
if (m_modify || m.IsCtor())
{
wxLogWarning("\tfixing it...");
// try to modify it!
FixMethod(iface->GetHeader(), &m, overloads[0]);
}
}
}
count++;
} // if (proceed)
}
}
return count;
}
bool IfaceCheckApp::StringContainsMethodName(const wxString& str, const wxMethod* m)
{
return str.Contains(m->GetName()) ||
(m->IsOperator() && str.Contains("operator"));
}
bool IfaceCheckApp::FixMethod(const wxString& header, const wxMethod* iface, const wxMethod* api)
{
unsigned int i,j;
wxASSERT(iface && api);
wxTextFile file;
if (!file.Open(header)) {
wxLogError("\tcan't open the '%s' header file.", header);
return false;
}
// GetLocation() returns the line where the last part of the prototype is placed;
// i.e. the line containing the semicolon at the end of the declaration.
int end = iface->GetLocation()-1;
if (end <= 0 || end >= (int)file.GetLineCount()) {
wxLogWarning("\tinvalid location info for method '%s': %d.",
iface->GetAsString(), iface->GetLocation());
return false;
}
if (!file.GetLine(end).Contains(";")) {
wxLogWarning("\tinvalid location info for method '%s': %d.",
iface->GetAsString(), iface->GetLocation());
return false;
}
// is this a one-line prototype declaration?
bool founddecl = false;
int start;
if (StringContainsMethodName(file.GetLine(end), iface))
{
// yes, this prototype is all on this line:
start = end;
founddecl = true;
}
else
{
start = end; // will be decremented inside the while{} loop below
// find the start point of this prototype declaration; i.e. the line
// containing the function name, which is also the line following
// the marker '*/' for the closure of the doxygen comment
do
{
start--; // go up one line
if (StringContainsMethodName(file.GetLine(start), iface))
founddecl = true;
}
while (start > 0 && !founddecl &&
!file.GetLine(start).Contains(";") &&
!file.GetLine(start).Contains("*/"));
}
if (start <= 0 || !founddecl)
{
wxLogError("\tcan't find the beginning of the declaration of '%s' method in '%s' header looking backwards from line %d; I arrived at %d and gave up",
iface->GetAsString(), header, end+1 /* zero-based => 1-based */, start);
return false;
}
// remove the old prototype
for (int k=start; k<=end; k++)
file.RemoveLine(start); // remove (end-start)-nth times the start-th line
#define INDENTATION_STR wxString(" ")
// if possible, add also the @deprecated tag in the doxygen comment if it's missing
int deprecationOffset = 0;
if (file.GetLine(start-1).Contains("*/") &&
(api->IsDeprecated() && !iface->IsDeprecated()))
{
file.RemoveLine(start-1);
file.InsertLine(INDENTATION_STR + INDENTATION_STR +
"@deprecated @todo provide deprecation description", start-1);
file.InsertLine(INDENTATION_STR + "*/", start++);
// we have added a new line in the final balance
deprecationOffset=1;
}
wxMethod tmp(*api);
// discard gcc XML argument names and replace them with those parsed from doxygen XML;
// in this way we should avoid introducing doxygen warnings about cases where the argument
// 'xx' of the prototype is called 'yy' in the function's docs.
const wxArgumentTypeArray& doxygenargs = iface->GetArgumentTypes();
const wxArgumentTypeArray& realargs = api->GetArgumentTypes();
if (realargs.GetCount() == doxygenargs.GetCount())
{
for (j=0; j<doxygenargs.GetCount(); j++)
if (doxygenargs[j]==realargs[j])
{
realargs[j].SetArgumentName(doxygenargs[j].GetArgumentName());
if (realargs[j].GetDefaultValue().IsNumber() &&
doxygenargs[j].GetDefaultValue().StartsWith("wx"))
realargs[j].SetDefaultValue(doxygenargs[j].GetDefaultValue());
}
tmp.SetArgumentTypes(realargs);
}
#define WRAP_COLUMN 80
wxArrayString toinsert;
toinsert.Add(INDENTATION_STR + tmp.GetAsString() + ";");
int nStartColumn = toinsert[0].Find('(');
wxASSERT(nStartColumn != wxNOT_FOUND);
// wrap lines too long at comma boundaries
for (i=0; i<toinsert.GetCount(); i++)
{
size_t len = toinsert[i].Len();
if (len > WRAP_COLUMN)
{
wxASSERT(i == toinsert.GetCount()-1);
// break this line
wxString tmpleft = toinsert[i].Left(WRAP_COLUMN);
int comma = tmpleft.Find(',', true /* from end */);
if (comma == wxNOT_FOUND)
break; // break out of the for cycle...
toinsert.Add(wxString(' ', nStartColumn+1) +
toinsert[i].Right(len-comma-2)); // exclude the comma and the space after it
toinsert[i] = tmpleft.Left(comma+1); // include the comma
}
}
// insert the new lines
for (i=0; i<toinsert.GetCount(); i++)
file.InsertLine(toinsert[i], start+i);
// now save the modification
if (!file.Write()) {
wxLogError("\tcan't save the '%s' header file.", header);
return false;
}
// how many lines did we add/remove in total?
int nOffset = toinsert.GetCount() + deprecationOffset - (end-start+1);
if (nOffset == 0)
return false;
if (g_verbose)
{
wxLogMessage("\tthe final row offset for following methods is %d lines.", nOffset);
}
// update the other method's locations for those methods which belong to the modified header
// and are placed _below_ the modified method
wxClassPtrArray cToUpdate = m_doxyInterface.FindClassesDefinedIn(header);
for (i=0; i < cToUpdate.GetCount(); i++)
{
for (j=0; j < cToUpdate[i]->GetMethodCount(); j++)
{
wxMethod& m = cToUpdate[i]->GetMethod(j);
if (m.GetLocation() > iface->GetLocation())
{
// update the location of this method
m.SetLocation(m.GetLocation()+nOffset);
}
}
}
return true;
}
bool IfaceCheckApp::ParsePreprocessorOutput(const wxString& filename)
{
wxTextFile tf;
if (!tf.Open(filename)) {
wxLogError("can't open the '%s' preprocessor output file.", filename);
return false;
}
size_t useful = 0;
for (unsigned int i=0; i < tf.GetLineCount(); i++)
{
const wxString& line = tf.GetLine(i);
wxString defnameval = line.Mid(8); // what follows the "#define " string
// the format of this line should be:
// #define DEFNAME DEFVALUE
if (!line.StartsWith("#define ")) {
wxLogError("unexpected content in '%s' at line %d.", filename, i+1);
return false;
}
if (defnameval.Contains(" "))
{
// get DEFNAME
wxString defname = defnameval.BeforeFirst(' ');
if (defname.Contains("("))
continue; // this is a macro, skip it!
// get DEFVAL
wxString defval = defnameval.AfterFirst(' ').Strip(wxString::both);
if (defval.StartsWith("(") && defval.EndsWith(")"))
defval = defval.Mid(1, defval.Len()-2);
// store this pair in the doxygen interface, where it can be useful
m_doxyInterface.AddPreprocessorValue(defname, defval);
useful++;
}
else
{
// it looks like the format of this line is:
// #define DEFNAME
// we are not interested to symbols #defined to nothing,
// so we just ignore this line.
}
}
wxLogMessage("Parsed %d preprocessor #defines from '%s' which will be used later...",
useful, filename);
return true;
}
void IfaceCheckApp::PrintStatistics(long secs)
{
// these stats, for what regards the gcc XML, are all referred to the wxWidgets
// classes only!
wxLogMessage("wx real headers contains declaration of %d classes (%d methods)",
m_gccInterface.GetClassesCount(), m_gccInterface.GetMethodCount());
wxLogMessage("wx interface headers contains declaration of %d classes (%d methods)",
m_doxyInterface.GetClassesCount(), m_doxyInterface.GetMethodCount());
// build a list of the undocumented wx classes
wxString list;
int undoc = 0;
const wxClassArray& arr = m_gccInterface.GetClasses();
for (unsigned int i=0; i<arr.GetCount(); i++) {
if (m_doxyInterface.FindClass(arr[i].GetName()) == nullptr) {
list += arr[i].GetName() + ", ";
undoc++;
}
}
list.RemoveLast();
list.RemoveLast();
wxLogMessage("the list of the %d undocumented wx classes is: %s", undoc, list);
wxLogMessage("total processing took %d seconds.", secs);
}

View File

@@ -0,0 +1,185 @@
# =========================================================================
# This makefile was generated by
# Bakefile 0.2.13 (http://www.bakefile.org)
# Do not modify, all changes will be overwritten!
# =========================================================================
include ../../../build/msw/config.gcc
# -------------------------------------------------------------------------
# Do not modify the rest of this file!
# -------------------------------------------------------------------------
### Variables: ###
CPPDEPS = -MT$@ -MF$@.d -MD -MP
WX_RELEASE_NODOT = 33
COMPILER_PREFIX = gcc
OBJS = \
$(COMPILER_PREFIX)$(COMPILER_VERSION)_$(PORTNAME)$(WXUNIVNAME)u$(WXDEBUGFLAG)$(WXDLLFLAG)$(CFG)
LIBDIRNAME = \
.\..\..\..\lib\$(COMPILER_PREFIX)$(COMPILER_VERSION)_$(LIBTYPE_SUFFIX)$(CFG)
SETUPHDIR = $(LIBDIRNAME)\$(PORTNAME)$(WXUNIVNAME)u$(WXDEBUGFLAG)
IFACECHECK_CXXFLAGS = $(__DEBUGINFO) $(__OPTIMIZEFLAG_2) $(__THREADSFLAG) \
-D__WXMSW__ $(__WXUNIV_DEFINE_p) $(__DEBUG_DEFINE_p) $(__NDEBUG_DEFINE_p) \
$(__EXCEPTIONS_DEFINE_p) $(__RTTI_DEFINE_p) $(__THREAD_DEFINE_p) \
-I$(SETUPHDIR) -I.\..\..\..\include $(____CAIRO_INCLUDEDIR_FILENAMES_p) -W \
-Wall -I. $(__DLLFLAG_p) -DwxUSE_GUI=0 $(__RTTIFLAG_5) $(__EXCEPTIONSFLAG_6) \
-Wno-ctor-dtor-privacy $(CPPFLAGS) $(CXXFLAGS)
IFACECHECK_OBJECTS = \
$(OBJS)\ifacecheck_ifacecheck.o \
$(OBJS)\ifacecheck_xmlparser.o
### Conditionally set variables: ###
ifeq ($(USE_GUI),0)
PORTNAME = base
endif
ifeq ($(USE_GUI),1)
PORTNAME = msw$(TOOLKIT_VERSION)
endif
ifeq ($(OFFICIAL_BUILD),1)
COMPILER_VERSION = ERROR-COMPILER-VERSION-MUST-BE-SET-FOR-OFFICIAL-BUILD
endif
ifeq ($(BUILD),debug)
WXDEBUGFLAG = d
endif
ifeq ($(WXUNIV),1)
WXUNIVNAME = univ
endif
ifeq ($(SHARED),1)
WXDLLFLAG = dll
endif
ifeq ($(SHARED),0)
LIBTYPE_SUFFIX = lib
endif
ifeq ($(SHARED),1)
LIBTYPE_SUFFIX = dll
endif
ifeq ($(MONOLITHIC),0)
EXTRALIBS_FOR_BASE =
endif
ifeq ($(MONOLITHIC),1)
EXTRALIBS_FOR_BASE =
endif
ifeq ($(BUILD),debug)
__OPTIMIZEFLAG_2 = -O0
endif
ifeq ($(BUILD),release)
__OPTIMIZEFLAG_2 = -O2
endif
ifeq ($(USE_RTTI),0)
__RTTIFLAG_5 = -fno-rtti
endif
ifeq ($(USE_RTTI),1)
__RTTIFLAG_5 =
endif
ifeq ($(USE_EXCEPTIONS),0)
__EXCEPTIONSFLAG_6 = -fno-exceptions
endif
ifeq ($(USE_EXCEPTIONS),1)
__EXCEPTIONSFLAG_6 =
endif
ifeq ($(WXUNIV),1)
__WXUNIV_DEFINE_p = -D__WXUNIVERSAL__
endif
ifeq ($(DEBUG_FLAG),0)
__DEBUG_DEFINE_p = -DwxDEBUG_LEVEL=0
endif
ifeq ($(BUILD),release)
__NDEBUG_DEFINE_p = -DNDEBUG
endif
ifeq ($(USE_EXCEPTIONS),0)
__EXCEPTIONS_DEFINE_p = -DwxNO_EXCEPTIONS
endif
ifeq ($(USE_RTTI),0)
__RTTI_DEFINE_p = -DwxNO_RTTI
endif
ifeq ($(USE_THREADS),0)
__THREAD_DEFINE_p = -DwxNO_THREADS
endif
ifeq ($(USE_CAIRO),1)
____CAIRO_INCLUDEDIR_FILENAMES_p = -I$(CAIRO_ROOT)\include\cairo
endif
ifeq ($(SHARED),1)
__DLLFLAG_p = -DWXUSINGDLL
endif
ifeq ($(MONOLITHIC),0)
__WXLIB_XML_p = \
-lwxbase$(WX_RELEASE_NODOT)u$(WXDEBUGFLAG)$(WX_LIB_FLAVOUR)_xml
endif
ifeq ($(MONOLITHIC),0)
__WXLIB_BASE_p = -lwxbase$(WX_RELEASE_NODOT)u$(WXDEBUGFLAG)$(WX_LIB_FLAVOUR)
endif
ifeq ($(MONOLITHIC),1)
__WXLIB_MONO_p = \
-lwx$(PORTNAME)$(WXUNIVNAME)$(WX_RELEASE_NODOT)u$(WXDEBUGFLAG)$(WX_LIB_FLAVOUR)
endif
ifeq ($(MONOLITHIC),1)
__LIB_PNG_IF_MONO_p = $(__LIB_PNG_p)
endif
ifeq ($(USE_GUI),1)
__LIB_PNG_p = -lwxpng$(WXDEBUGFLAG)
endif
ifeq ($(USE_CAIRO),1)
__CAIRO_LIB_p = -lcairo
endif
ifeq ($(USE_CAIRO),1)
____CAIRO_LIBDIR_FILENAMES_p = -L$(CAIRO_ROOT)\lib
endif
ifeq ($(BUILD),debug)
ifeq ($(DEBUG_INFO),default)
__DEBUGINFO = -g
endif
endif
ifeq ($(BUILD),release)
ifeq ($(DEBUG_INFO),default)
__DEBUGINFO =
endif
endif
ifeq ($(DEBUG_INFO),0)
__DEBUGINFO =
endif
ifeq ($(DEBUG_INFO),1)
__DEBUGINFO = -g
endif
ifeq ($(USE_THREADS),0)
__THREADSFLAG =
endif
ifeq ($(USE_THREADS),1)
__THREADSFLAG = -mthreads
endif
all: $(OBJS)
$(OBJS):
-if not exist $(OBJS) mkdir $(OBJS)
### Targets: ###
all: $(OBJS)\ifacecheck.exe
clean:
-if exist $(OBJS)\*.o del $(OBJS)\*.o
-if exist $(OBJS)\*.d del $(OBJS)\*.d
-if exist $(OBJS)\ifacecheck.exe del $(OBJS)\ifacecheck.exe
$(OBJS)\ifacecheck.exe: $(IFACECHECK_OBJECTS)
$(foreach f,$(subst \,/,$(IFACECHECK_OBJECTS)),$(shell echo $f >> $(subst \,/,$@).rsp.tmp))
@move /y $@.rsp.tmp $@.rsp >nul
$(CXX) -o $@ @$@.rsp $(__DEBUGINFO) $(__THREADSFLAG) -L$(LIBDIRNAME) $(____CAIRO_LIBDIR_FILENAMES_p) $(LDFLAGS) $(__WXLIB_XML_p) $(__WXLIB_BASE_p) $(__WXLIB_MONO_p) $(__LIB_PNG_IF_MONO_p) -lwxzlib$(WXDEBUGFLAG) -lwxregexu$(WXDEBUGFLAG) -lwxexpat$(WXDEBUGFLAG) $(EXTRALIBS_FOR_BASE) $(__CAIRO_LIB_p) -lkernel32 -luser32 -lgdi32 -lgdiplus -lmsimg32 -lcomdlg32 -lwinspool -lwinmm -lshell32 -lshlwapi -lcomctl32 -lole32 -loleaut32 -luuid -lrpcrt4 -ladvapi32 -lversion -lws2_32 -lwininet -loleacc -luxtheme
@-del $@.rsp
$(OBJS)\ifacecheck_ifacecheck.o: ./ifacecheck.cpp
$(CXX) -c -o $@ $(IFACECHECK_CXXFLAGS) $(CPPDEPS) $<
$(OBJS)\ifacecheck_xmlparser.o: ./xmlparser.cpp
$(CXX) -c -o $@ $(IFACECHECK_CXXFLAGS) $(CPPDEPS) $<
.PHONY: all clean
SHELL := $(COMSPEC)
# Dependencies tracking:
-include $(OBJS)/*.d

View File

@@ -0,0 +1,339 @@
# =========================================================================
# This makefile was generated by
# Bakefile 0.2.13 (http://www.bakefile.org)
# Do not modify, all changes will be overwritten!
# =========================================================================
!include <../../../build/msw/config.vc>
# -------------------------------------------------------------------------
# Do not modify the rest of this file!
# -------------------------------------------------------------------------
### Variables: ###
WX_RELEASE_NODOT = 33
COMPILER_PREFIX = vc
OBJS = \
$(COMPILER_PREFIX)$(COMPILER_VERSION)$(ARCH_SUFFIX)_$(PORTNAME)$(WXUNIVNAME)u$(WXDEBUGFLAG)$(WXDLLFLAG)$(CFG)
LIBDIRNAME = \
.\..\..\..\lib\$(COMPILER_PREFIX)$(COMPILER_VERSION)$(ARCH_SUFFIX)_$(LIBTYPE_SUFFIX)$(CFG)
SETUPHDIR = $(LIBDIRNAME)\$(PORTNAME)$(WXUNIVNAME)u$(WXDEBUGFLAG)
IFACECHECK_CXXFLAGS = /M$(__RUNTIME_LIBS_10)$(__DEBUGRUNTIME_4) /DWIN32 \
$(__DEBUGINFO_0) /Fd$(OBJS)\ifacecheck.pdb $(____DEBUGRUNTIME_3_p) \
$(__OPTIMIZEFLAG_6) /D_CRT_SECURE_NO_DEPRECATE=1 \
/D_CRT_NON_CONFORMING_SWPRINTFS=1 /D_SCL_SECURE_NO_WARNINGS=1 \
$(__NO_VC_CRTDBG_p) $(__TARGET_CPU_COMPFLAG_p) /D__WXMSW__ \
$(__WXUNIV_DEFINE_p) $(__DEBUG_DEFINE_p) $(__NDEBUG_DEFINE_p) \
$(__EXCEPTIONS_DEFINE_p) $(__RTTI_DEFINE_p) $(__THREAD_DEFINE_p) \
/I$(SETUPHDIR) /I.\..\..\..\include $(____CAIRO_INCLUDEDIR_FILENAMES_p) /W4 \
/I. $(__DLLFLAG_p) /D_CONSOLE /DwxUSE_GUI=0 $(__RTTIFLAG_11) \
$(__EXCEPTIONSFLAG_12) $(CPPFLAGS) $(CXXFLAGS)
IFACECHECK_OBJECTS = \
$(OBJS)\ifacecheck_ifacecheck.obj \
$(OBJS)\ifacecheck_xmlparser.obj
### Conditionally set variables: ###
!if "$(TARGET_CPU)" == "AMD64"
ARCH_SUFFIX = _x64
!endif
!if "$(TARGET_CPU)" == "ARM"
ARCH_SUFFIX = _arm
!endif
!if "$(TARGET_CPU)" == "ARM64"
ARCH_SUFFIX = _arm64
!endif
!if "$(TARGET_CPU)" == "IA64"
ARCH_SUFFIX = _ia64
!endif
!if "$(TARGET_CPU)" == "X64"
ARCH_SUFFIX = _x64
!endif
!if "$(TARGET_CPU)" == "" && "$(VISUALSTUDIOPLATFORM)" == "X64"
ARCH_SUFFIX = _x64
!endif
!if "$(TARGET_CPU)" == "" && "$(VISUALSTUDIOPLATFORM)" == "x64"
ARCH_SUFFIX = _x64
!endif
!if "$(TARGET_CPU)" == "amd64"
ARCH_SUFFIX = _x64
!endif
!if "$(TARGET_CPU)" == "arm"
ARCH_SUFFIX = _arm
!endif
!if "$(TARGET_CPU)" == "arm64"
ARCH_SUFFIX = _arm64
!endif
!if "$(TARGET_CPU)" == "ia64"
ARCH_SUFFIX = _ia64
!endif
!if "$(TARGET_CPU)" == "x64"
ARCH_SUFFIX = _x64
!endif
!if "$(USE_GUI)" == "0"
PORTNAME = base
!endif
!if "$(USE_GUI)" == "1"
PORTNAME = msw$(TOOLKIT_VERSION)
!endif
!if "$(OFFICIAL_BUILD)" == "1"
COMPILER_VERSION = ERROR-COMPILER-VERSION-MUST-BE-SET-FOR-OFFICIAL-BUILD
!endif
!if "$(BUILD)" == "debug" && "$(DEBUG_RUNTIME_LIBS)" == "default"
WXDEBUGFLAG = d
!endif
!if "$(DEBUG_RUNTIME_LIBS)" == "1"
WXDEBUGFLAG = d
!endif
!if "$(WXUNIV)" == "1"
WXUNIVNAME = univ
!endif
!if "$(SHARED)" == "1"
WXDLLFLAG = dll
!endif
!if "$(SHARED)" == "0"
LIBTYPE_SUFFIX = lib
!endif
!if "$(SHARED)" == "1"
LIBTYPE_SUFFIX = dll
!endif
!if "$(TARGET_CPU)" == "AMD64"
LINK_TARGET_CPU = /MACHINE:X64
!endif
!if "$(TARGET_CPU)" == "ARM"
LINK_TARGET_CPU = /MACHINE:ARM
!endif
!if "$(TARGET_CPU)" == "ARM64"
LINK_TARGET_CPU = /MACHINE:ARM64
!endif
!if "$(TARGET_CPU)" == "IA64"
LINK_TARGET_CPU = /MACHINE:IA64
!endif
!if "$(TARGET_CPU)" == "X64"
LINK_TARGET_CPU = /MACHINE:X64
!endif
!if "$(TARGET_CPU)" == "" && "$(VISUALSTUDIOPLATFORM)" == "X64"
LINK_TARGET_CPU = /MACHINE:X64
!endif
!if "$(TARGET_CPU)" == "" && "$(VISUALSTUDIOPLATFORM)" == "x64"
LINK_TARGET_CPU = /MACHINE:X64
!endif
!if "$(TARGET_CPU)" == "amd64"
LINK_TARGET_CPU = /MACHINE:X64
!endif
!if "$(TARGET_CPU)" == "arm"
LINK_TARGET_CPU = /MACHINE:ARM
!endif
!if "$(TARGET_CPU)" == "arm64"
LINK_TARGET_CPU = /MACHINE:ARM64
!endif
!if "$(TARGET_CPU)" == "ia64"
LINK_TARGET_CPU = /MACHINE:IA64
!endif
!if "$(TARGET_CPU)" == "x64"
LINK_TARGET_CPU = /MACHINE:X64
!endif
!if "$(MONOLITHIC)" == "0"
EXTRALIBS_FOR_BASE =
!endif
!if "$(MONOLITHIC)" == "1"
EXTRALIBS_FOR_BASE =
!endif
!if "$(BUILD)" == "debug" && "$(DEBUG_INFO)" == "default"
__DEBUGINFO_0 = /Zi
!endif
!if "$(BUILD)" == "release" && "$(DEBUG_INFO)" == "default"
__DEBUGINFO_0 =
!endif
!if "$(DEBUG_INFO)" == "0"
__DEBUGINFO_0 =
!endif
!if "$(DEBUG_INFO)" == "1"
__DEBUGINFO_0 = /Zi
!endif
!if "$(BUILD)" == "debug" && "$(DEBUG_INFO)" == "default"
__DEBUGINFO_1 = /DEBUG
!endif
!if "$(BUILD)" == "release" && "$(DEBUG_INFO)" == "default"
__DEBUGINFO_1 =
!endif
!if "$(DEBUG_INFO)" == "0"
__DEBUGINFO_1 =
!endif
!if "$(DEBUG_INFO)" == "1"
__DEBUGINFO_1 = /DEBUG
!endif
!if "$(BUILD)" == "debug" && "$(DEBUG_INFO)" == "default"
__DEBUGINFO_2 = $(__DEBUGRUNTIME_5)
!endif
!if "$(BUILD)" == "release" && "$(DEBUG_INFO)" == "default"
__DEBUGINFO_2 =
!endif
!if "$(DEBUG_INFO)" == "0"
__DEBUGINFO_2 =
!endif
!if "$(DEBUG_INFO)" == "1"
__DEBUGINFO_2 = $(__DEBUGRUNTIME_5)
!endif
!if "$(BUILD)" == "debug" && "$(DEBUG_RUNTIME_LIBS)" == "default"
____DEBUGRUNTIME_3_p = /D_DEBUG
!endif
!if "$(BUILD)" == "release" && "$(DEBUG_RUNTIME_LIBS)" == "default"
____DEBUGRUNTIME_3_p =
!endif
!if "$(DEBUG_RUNTIME_LIBS)" == "0"
____DEBUGRUNTIME_3_p =
!endif
!if "$(DEBUG_RUNTIME_LIBS)" == "1"
____DEBUGRUNTIME_3_p = /D_DEBUG
!endif
!if "$(BUILD)" == "debug" && "$(DEBUG_RUNTIME_LIBS)" == "default"
__DEBUGRUNTIME_4 = d
!endif
!if "$(BUILD)" == "release" && "$(DEBUG_RUNTIME_LIBS)" == "default"
__DEBUGRUNTIME_4 =
!endif
!if "$(DEBUG_RUNTIME_LIBS)" == "0"
__DEBUGRUNTIME_4 =
!endif
!if "$(DEBUG_RUNTIME_LIBS)" == "1"
__DEBUGRUNTIME_4 = d
!endif
!if "$(BUILD)" == "debug" && "$(DEBUG_RUNTIME_LIBS)" == "default"
__DEBUGRUNTIME_5 =
!endif
!if "$(BUILD)" == "release" && "$(DEBUG_RUNTIME_LIBS)" == "default"
__DEBUGRUNTIME_5 = /opt:ref /opt:icf
!endif
!if "$(DEBUG_RUNTIME_LIBS)" == "0"
__DEBUGRUNTIME_5 = /opt:ref /opt:icf
!endif
!if "$(DEBUG_RUNTIME_LIBS)" == "1"
__DEBUGRUNTIME_5 =
!endif
!if "$(BUILD)" == "debug"
__OPTIMIZEFLAG_6 = /Od
!endif
!if "$(BUILD)" == "release"
__OPTIMIZEFLAG_6 = /O2
!endif
!if "$(USE_THREADS)" == "0"
__THREADSFLAG_9 = L
!endif
!if "$(USE_THREADS)" == "1"
__THREADSFLAG_9 = T
!endif
!if "$(RUNTIME_LIBS)" == "dynamic"
__RUNTIME_LIBS_10 = D
!endif
!if "$(RUNTIME_LIBS)" == "static"
__RUNTIME_LIBS_10 = $(__THREADSFLAG_9)
!endif
!if "$(USE_RTTI)" == "0"
__RTTIFLAG_11 = /GR-
!endif
!if "$(USE_RTTI)" == "1"
__RTTIFLAG_11 = /GR
!endif
!if "$(USE_EXCEPTIONS)" == "0"
__EXCEPTIONSFLAG_12 =
!endif
!if "$(USE_EXCEPTIONS)" == "1"
__EXCEPTIONSFLAG_12 = /EHsc
!endif
!if "$(BUILD)" == "debug" && "$(DEBUG_RUNTIME_LIBS)" == "0"
__NO_VC_CRTDBG_p = /D__NO_VC_CRTDBG__
!endif
!if "$(BUILD)" == "release" && "$(DEBUG_FLAG)" == "1"
__NO_VC_CRTDBG_p = /D__NO_VC_CRTDBG__
!endif
!if "$(TARGET_CPU)" == ""
__TARGET_CPU_COMPFLAG_p = /DTARGET_CPU_COMPFLAG=0
!endif
!if "$(TARGET_CPU)" == "" && "$(VISUALSTUDIOPLATFORM)" == "x64"
__TARGET_CPU_COMPFLAG_p =
!endif
!if "$(TARGET_CPU)" == "" && "$(VISUALSTUDIOPLATFORM)" == "X64"
__TARGET_CPU_COMPFLAG_p =
!endif
!if "$(WXUNIV)" == "1"
__WXUNIV_DEFINE_p = /D__WXUNIVERSAL__
!endif
!if "$(DEBUG_FLAG)" == "0"
__DEBUG_DEFINE_p = /DwxDEBUG_LEVEL=0
!endif
!if "$(BUILD)" == "release" && "$(DEBUG_RUNTIME_LIBS)" == "default"
__NDEBUG_DEFINE_p = /DNDEBUG
!endif
!if "$(DEBUG_RUNTIME_LIBS)" == "0"
__NDEBUG_DEFINE_p = /DNDEBUG
!endif
!if "$(USE_EXCEPTIONS)" == "0"
__EXCEPTIONS_DEFINE_p = /DwxNO_EXCEPTIONS
!endif
!if "$(USE_RTTI)" == "0"
__RTTI_DEFINE_p = /DwxNO_RTTI
!endif
!if "$(USE_THREADS)" == "0"
__THREAD_DEFINE_p = /DwxNO_THREADS
!endif
!if "$(USE_CAIRO)" == "1"
____CAIRO_INCLUDEDIR_FILENAMES_p = /I$(CAIRO_ROOT)\include\cairo
!endif
!if "$(SHARED)" == "1"
__DLLFLAG_p = /DWXUSINGDLL
!endif
!if "$(MONOLITHIC)" == "0"
__WXLIB_XML_p = \
wxbase$(WX_RELEASE_NODOT)u$(WXDEBUGFLAG)$(WX_LIB_FLAVOUR)_xml.lib
!endif
!if "$(MONOLITHIC)" == "0"
__WXLIB_BASE_p = \
wxbase$(WX_RELEASE_NODOT)u$(WXDEBUGFLAG)$(WX_LIB_FLAVOUR).lib
!endif
!if "$(MONOLITHIC)" == "1"
__WXLIB_MONO_p = \
wx$(PORTNAME)$(WXUNIVNAME)$(WX_RELEASE_NODOT)u$(WXDEBUGFLAG)$(WX_LIB_FLAVOUR).lib
!endif
!if "$(MONOLITHIC)" == "1"
__LIB_PNG_IF_MONO_p = $(__LIB_PNG_p)
!endif
!if "$(USE_GUI)" == "1"
__LIB_PNG_p = wxpng$(WXDEBUGFLAG).lib
!endif
!if "$(USE_CAIRO)" == "1"
__CAIRO_LIB_p = cairo.lib
!endif
!if "$(USE_CAIRO)" == "1"
____CAIRO_LIBDIR_FILENAMES_p = /LIBPATH:$(CAIRO_ROOT)\lib
!endif
all: $(OBJS)
$(OBJS):
-if not exist $(OBJS) mkdir $(OBJS)
### Targets: ###
all: $(OBJS)\ifacecheck.exe
clean:
-if exist $(OBJS)\*.obj del $(OBJS)\*.obj
-if exist $(OBJS)\*.res del $(OBJS)\*.res
-if exist $(OBJS)\*.pch del $(OBJS)\*.pch
-if exist $(OBJS)\ifacecheck.exe del $(OBJS)\ifacecheck.exe
-if exist $(OBJS)\ifacecheck.ilk del $(OBJS)\ifacecheck.ilk
-if exist $(OBJS)\ifacecheck.pdb del $(OBJS)\ifacecheck.pdb
$(OBJS)\ifacecheck.exe: $(IFACECHECK_OBJECTS)
link /NOLOGO /OUT:$@ $(__DEBUGINFO_1) /pdb:"$(OBJS)\ifacecheck.pdb" $(__DEBUGINFO_2) $(LINK_TARGET_CPU) /LIBPATH:$(LIBDIRNAME) /SUBSYSTEM:CONSOLE $(____CAIRO_LIBDIR_FILENAMES_p) $(LDFLAGS) @<<
$(IFACECHECK_OBJECTS) $(__WXLIB_XML_p) $(__WXLIB_BASE_p) $(__WXLIB_MONO_p) $(__LIB_PNG_IF_MONO_p) wxzlib$(WXDEBUGFLAG).lib wxregexu$(WXDEBUGFLAG).lib wxexpat$(WXDEBUGFLAG).lib $(EXTRALIBS_FOR_BASE) $(__CAIRO_LIB_p) kernel32.lib user32.lib gdi32.lib gdiplus.lib msimg32.lib comdlg32.lib winspool.lib winmm.lib shell32.lib shlwapi.lib comctl32.lib ole32.lib oleaut32.lib uuid.lib rpcrt4.lib advapi32.lib version.lib ws2_32.lib wininet.lib
<<
$(OBJS)\ifacecheck_ifacecheck.obj: .\ifacecheck.cpp
$(CXX) /c /nologo /TP /Fo$@ $(IFACECHECK_CXXFLAGS) .\ifacecheck.cpp
$(OBJS)\ifacecheck_xmlparser.obj: .\xmlparser.cpp
$(CXX) /c /nologo /TP /Fo$@ $(IFACECHECK_CXXFLAGS) .\xmlparser.cpp

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,521 @@
/////////////////////////////////////////////////////////////////////////////
// Name: xmlparser.h
// Purpose: Parser of the API/interface XML files
// Author: Francesco Montorsi
// Created: 2008/03/17
// Copyright: (c) 2008 Francesco Montorsi
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
#ifndef _XMLPARSER_H_
#define _XMLPARSER_H_
#include <wx/txtstrm.h>
#include <wx/dynarray.h>
#include <wx/xml/xml.h>
#include <wx/platinfo.h>
#include <wx/log.h>
#include <wx/hashmap.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:
// ...fix description...
*/
// NOTE: all messages in this way are printed on the stderr
//#define wxLogWarning wxLogMessage
// ----------------------------------------------------------------------------
// Represents a type with or without const/static/ qualifier
// and with or without & and * operators
// ----------------------------------------------------------------------------
class wxType
{
public:
wxType() {}
wxType(const wxString& type)
{ SetTypeFromString(type); }
void SetTypeFromString(const wxString& t);
wxString GetAsString() const
{ return m_strType; }
// returns this type _without_ any decoration,
// including the & (which indicates this is a reference),
// the * (which indicates this is a pointer), etc.
wxString GetAsCleanString() const
{ return m_strTypeClean; }
bool IsConst() const
{ return m_strType.Contains("const"); }
bool IsStatic() const
{ return m_strType.Contains("static"); }
bool IsPointer() const
{ return m_strType.Contains("*"); }
bool IsReference() const
{ return m_strType.Contains("&"); }
bool operator==(const wxType& m) const;
bool operator!=(const wxType& m) const
{ return !(*this == m); }
bool IsOk() const;
protected:
wxString m_strType,
m_strTypeClean; // m_strType "cleaned" of its attributes
// (only for internal use)
};
extern wxType wxEmptyType;
WX_DECLARE_OBJARRAY(wxType, wxTypeArray);
// ----------------------------------------------------------------------------
// Represents a type used as argument for some wxMethod
// ----------------------------------------------------------------------------
class wxArgumentType : public wxType
{
public:
wxArgumentType() {}
wxArgumentType(const wxString& type, const wxString& defVal,
const wxString& argName = wxEmptyString)
{ SetTypeFromString(type); SetDefaultValue(defVal); m_strArgName = argName; }
void SetArgumentName(const wxString& name)
{ m_strArgName=name.Strip(wxString::both); }
wxString GetArgumentName() const
{ return m_strArgName; }
void SetDefaultValue(const wxString& defval,
const wxString& defvalForCmp = wxEmptyString);
wxString GetDefaultValue() const
{ return m_strDefaultValue; }
// returns the default value used for comparisons
wxString GetDefaultCleanValue() const
{ return m_strDefaultValueForCmp; }
bool HasDefaultValue() const
{ return !m_strDefaultValue.IsEmpty(); }
bool operator==(const wxArgumentType& m) const;
bool operator!=(const wxArgumentType& m) const
{ return !(*this == m); }
protected:
wxString m_strDefaultValue;
// this string may differ from m_strDefaultValue if there were
// preprocessor substitutions or other "replacements" done to
// avoid false errors.
wxString m_strDefaultValueForCmp;
// the argument name
wxString m_strArgName;
};
extern wxArgumentType wxEmptyArgumentType;
WX_DECLARE_OBJARRAY(wxArgumentType, wxArgumentTypeArray);
enum wxMethodAccessSpecifier
{
wxMAS_PUBLIC,
wxMAS_PROTECTED,
wxMAS_PRIVATE
};
// ----------------------------------------------------------------------------
// Represents a single prototype of a class' member.
// ----------------------------------------------------------------------------
class wxMethod
{
public:
wxMethod()
{ m_bConst=m_bVirtual=m_bPureVirtual=m_bStatic=m_bDeprecated=false;
m_nLine=-1; m_nAvailability=wxPORT_UNKNOWN; m_access=wxMAS_PUBLIC; }
wxMethod(const wxType& rettype, const wxString& name,
const wxArgumentTypeArray& arguments,
bool isConst, bool isStatic, bool isVirtual)
: m_retType(rettype), m_strName(name.Strip(wxString::both)),
m_bConst(isConst), m_bStatic(isStatic), m_bVirtual(isVirtual)
{ SetArgumentTypes(arguments); m_nLine=-1; }
public: // getters
// bWithArgumentNames = output argument names?
// bCleanDefaultValues = output clean argument default values?
// bDeprecated = output [deprecated] next to deprecated methods?
// bAccessSpec = output [public], [protected] or [private] next to method?
//
// TODO: convert to readable flags this set of bools
wxString GetAsString(bool bWithArgumentNames = true,
bool bCleanDefaultValues = false,
bool bDeprecated = false,
bool bAccessSpec = false) const;
// parser of the prototype:
// all these functions return strings with spaces stripped
wxType GetReturnType() const
{ return m_retType; }
wxString GetName() const
{ return m_strName; }
const wxArgumentTypeArray& GetArgumentTypes() const
{ return m_args; }
wxArgumentTypeArray& GetArgumentTypes()
{ return m_args; }
int GetLocation() const
{ return m_nLine; }
int GetAvailability() const
{ return m_nAvailability; }
wxMethodAccessSpecifier GetAccessSpecifier() const
{ return m_access; }
bool IsConst() const
{ return m_bConst; }
bool IsStatic() const
{ return m_bStatic; }
bool IsVirtual() const
{ return m_bVirtual; }
bool IsPureVirtual() const
{ return m_bPureVirtual; }
bool IsOk() const;
bool IsCtor() const
{ return m_retType==wxEmptyType && !m_strName.StartsWith("~"); }
bool IsDtor() const
{ return m_retType==wxEmptyType && m_strName.StartsWith("~"); }
bool IsOperator() const
{ return m_strName.StartsWith("operator"); }
bool IsDeprecated() const
{ return m_bDeprecated; }
public: // setters
void SetReturnType(const wxType& t)
{ m_retType=t; }
void SetName(const wxString& name)
{ m_strName=name; }
void SetArgumentTypes(const wxArgumentTypeArray& arr)
{ m_args=arr; }
void SetConst(bool c = true)
{ m_bConst=c; }
void SetStatic(bool c = true)
{ m_bStatic=c; }
void SetVirtual(bool c = true)
{ m_bVirtual=c; }
void SetPureVirtual(bool c = true)
{
m_bPureVirtual=c;
if (c) m_bVirtual=c; // pure virtual => virtual
}
void SetDeprecated(bool c = true)
{ m_bDeprecated=c; }
void SetLocation(int lineNumber)
{ m_nLine=lineNumber; }
void SetAvailability(int nAvail)
{ m_nAvailability=nAvail; }
void SetAccessSpecifier(wxMethodAccessSpecifier spec)
{ m_access=spec; }
public: // misc
bool operator==(const wxMethod&) const;
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;
// returns true if this is a ctor which has default values for all its
// argument, thus is able to act also as default ctor
bool ActsAsDefaultCtor() const;
// dumps the contents of this class in the given stream
void Dump(wxTextOutputStream& stream) const;
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;
// the access specifier for this method
wxMethodAccessSpecifier m_access;
};
WX_DECLARE_OBJARRAY(wxMethod, wxMethodArray);
WX_DEFINE_ARRAY(const wxMethod*, wxMethodPtrArray);
// we need wxClassPtrArray to be defined _before_ wxClass itself,
// since wxClass uses wxClassPtrArray.
class wxClass;
WX_DEFINE_ARRAY(const wxClass*, wxClassPtrArray);
class wxXmlInterface;
// ----------------------------------------------------------------------------
// Represents a class of the wx API/interface.
// ----------------------------------------------------------------------------
class wxClass
{
public:
wxClass() {}
wxClass(const wxString& name, const wxString& headername)
: m_strName(name), m_strHeader(headername) {}
public: // setters
void SetHeader(const wxString& header)
{ m_strHeader=header; }
void SetName(const wxString& name)
{ m_strName=name; }
void SetAvailability(int nAvail)
{ m_nAvailability=nAvail; }
void SetParent(unsigned int k, const wxString& name)
{ m_parents[k]=name; }
public: // getters
bool IsOk() const
{ return !m_strName.IsEmpty() && !m_methods.IsEmpty(); }
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
{ return m_methods[n]; }
wxMethod& GetLastMethod() const
{ return m_methods.Last(); }
int GetAvailability() const
{ return m_nAvailability; }
//const wxClass *GetParent(unsigned int i) const
const wxString& GetParent(unsigned int i) const
{ return m_parents[i]; }
unsigned int GetParentCount() const
{ return m_parents.GetCount(); }
public: // misc
void AddMethod(const wxMethod& func)
{ m_methods.Add(func); }
void AddParent(const wxString& parent)//wxClass* parent)
{ m_parents.Add(parent); }
// returns a single result (the first, which is also the only
// one if CheckConsistency() return true)
const wxMethod* FindMethod(const wxMethod& m) const;
// like FindMethod() but this one searches also recursively in
// the parents of this class.
const wxMethod* RecursiveUpwardFindMethod(const wxMethod& m,
const wxXmlInterface* allclasses) const;
// returns an array of pointers to the overloaded methods with the
// same given name
wxMethodPtrArray FindMethodsNamed(const wxString& name) const;
// like FindMethodsNamed() but this one searches also recursively in
// the parents of this class.
wxMethodPtrArray RecursiveUpwardFindMethodsNamed(const wxString& name,
const wxXmlInterface* allclasses) const;
// dumps all methods to the given output stream
void Dump(wxTextOutputStream& stream) const;
// slow check
bool CheckConsistency() const;
protected:
wxString m_strName;
wxString m_strHeader;
wxMethodArray m_methods;
// name of the base classes: we store the names and not the pointers
// because this makes _much_ easier the parsing process!
// (basically because when parsing class X which derives from Y,
// we may have not parsed yet class Y!)
wxArrayString m_parents;
// see the wxMethod::m_nAvailability field for more info
int m_nAvailability;
};
WX_DECLARE_OBJARRAY(wxClass, wxClassArray);
// ----------------------------------------------------------------------------
// wxXmlInterface
// ----------------------------------------------------------------------------
class wxXmlInterface
{
public:
wxXmlInterface() {}
const wxClass* FindClass(const wxString& classname) const
{
for (unsigned int i=0; i<m_classes.GetCount(); i++)
if (m_classes[i].GetName() == classname)
return &m_classes[i];
return nullptr;
}
void Dump(const wxString& filename);
const wxClassArray& GetClasses() const
{ return m_classes; }
unsigned int GetClassesCount() const
{ return m_classes.GetCount(); }
unsigned int GetMethodCount() const
{
unsigned int methods = 0;
for (unsigned i=0; i < m_classes.GetCount(); i++)
methods += m_classes[i].GetMethodCount();
return methods;
}
// pass a full-path header filename:
wxClassPtrArray FindClassesDefinedIn(const wxString& headerfile) const;
void ShowProgress()
{ /*wxFprintf(stderr, ".");*/ }
// is this interface coherent?
bool CheckConsistency() const;
protected:
wxClassArray m_classes;
};
#if 1
// for wxTypeIdHashMap, keys == gccxml IDs and values == associated type strings
// e.g. key = "0x123f" and value = "const wxAboutDialogInfo&"
WX_DECLARE_HASH_MAP( unsigned long, wxString,
wxIntegerHash, wxIntegerEqual,
wxTypeIdHashMap );
WX_DECLARE_STRING_HASH_MAP( wxString, wxStringHashMap );
#else
#include <map>
typedef std::basic_string<char> stlString;
typedef std::map<unsigned long, stlString> wxTypeIdHashMap;
#endif
// ----------------------------------------------------------------------------
// Represents the real interface of wxWidgets
// Loads it from the XML produced by gccXML: http://www.gccxml.org
// ----------------------------------------------------------------------------
class wxXmlGccInterface : public wxXmlInterface
{
public:
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;
};
// ----------------------------------------------------------------------------
// Represents the interface of the doxygen headers of wxWidgets
// Loads it from the XML produced by Doxygen: http://www.doxygen.org
// ----------------------------------------------------------------------------
class wxXmlDoxygenInterface : public wxXmlInterface
{
public:
wxXmlDoxygenInterface() {}
// !!SPEEDUP-TODO!!
// Using wxXmlDocument::Load as is, the entire XML file is parsed
// and an entire tree of wxXmlNodes is built in memory.
// We need however only small portions of the Doxygen-generated XML: to speedup the
// processing we could detach the expat callbacks when we detect the beginning of a
// node we're not interested about, or just don't create a wxXmlNode for it!
// This needs a modification of wxXml API.
bool Parse(const wxString& filename);
bool ParseCompoundDefinition(const wxString& filename);
bool ParseMethod(const wxXmlNode*, wxMethod&, wxString& header);
// this class can take advantage of the preprocessor output to give
// a minor number of false positive warnings in the final comparison
void AddPreprocessorValue(const wxString& name, const wxString& val)
{ m_preproc[name]=val; }
protected:
wxStringHashMap m_preproc;
};
#endif // _XMLPARSER_H_