From 0cbc1d02511500b8499a11939ef0c59309937fca Mon Sep 17 00:00:00 2001 From: Kevin Ollivier Date: Sat, 2 May 2009 23:07:51 +0000 Subject: [PATCH] Separate the parts of make_bindings.py out into common parts, and SWIG and SIP specific parts. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@60491 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- docs/doxygen/scripts/common.py | 162 +++++++++++++ docs/doxygen/scripts/doxymlparser.py | 8 +- docs/doxygen/scripts/make_bindings.py | 313 +------------------------- docs/doxygen/scripts/sip_tools.py | 84 +++++++ docs/doxygen/scripts/swig_tools.py | 61 +++++ 5 files changed, 315 insertions(+), 313 deletions(-) create mode 100644 docs/doxygen/scripts/common.py create mode 100644 docs/doxygen/scripts/sip_tools.py create mode 100644 docs/doxygen/scripts/swig_tools.py diff --git a/docs/doxygen/scripts/common.py b/docs/doxygen/scripts/common.py new file mode 100644 index 0000000000..41e80d7201 --- /dev/null +++ b/docs/doxygen/scripts/common.py @@ -0,0 +1,162 @@ +# format: class : {method : (prototype1, prototype2)} +# using a "*" means all prototypes +ignored_methods = { + "wxIcon": {'wxIcon': (['const char', 'int', 'int'], )}, +} + +# these classes are either replaced by different data types in bindings, or have equivalent / better +# functionality provided by the target language. +excluded_classes = [ + "wxArchiveClassFactory", + "wxArchiveEntry", + "wxArchiveInputStream", + "wxArchiveIterator", + "wxArchiveNotifier", + "wxArchiveOutputStream", + "wxArray< T >", + "wxArrayString", + "wxAutomationObject", + "wxBufferedInputStream", + "wxBufferedOutputStream", + "wxCharBuffer", + "wxCharTypeBuffer", + "wxClassInfo", + "wxCmdLineParser", + "wxCondition", + "wxConnection", + "wxConnectionBase", + "wxConvAuto", + "wxCountingOutputStream", + "wxCriticalSection", + "wxCriticalSectionLocker", + "wxCSConv", + "wxDatagramSocket", + "wxDataInputStream", + "wxDataOutputStream", + "wxDir", + "wxDirTraverser", + "wxFFile", + "wxFFileInputStream", + "wxFFileOutputStream", + "wxFile", + "wxFileInputStream", + "wxFileName", + "wxFileOutputStream", + "wxFileStream", + "wxFilterClassFactory", + "wxFilterInputStream", + "wxFilterOutputStream", + "wxFSFile", + "wxFSVolume", + "wxFTP", + "wxHashMap", + "wxHashSet", + "wxHashTable", + "wxHTTP", + "wxImage::HSVValue", + "wxImage::RGBValue", + "wxInputStream", + "wxIPAddress", + "wxIPV4Address", + "wxList< T >", + "wxLongLong", + "wxMBConv", + "wxMBConvFile", + "wxMBConvUTF7", + "wxMBConvUTF8", + "wxMBConvUTF16", + "wxMBConvUTF32", + "wxMemoryBuffer", + "wxMemoryFSHandler", + "wxMemoryInputStream", + "wxMemoryOutputStream", + "wxMessageQueue< T >", + "wxModule", + "wxMutex", + "wxMutexLocker", + "wxNode< T >", + "wxObjectDataPtr< T >", + "wxObjectRefData", + "wxOutputStream", + "wxProcess", + "wxProcessEvent", + "wxProtocol", + "wxProtocolLog", + "wxRecursionGuard", + "wxRecursionGuardFlag", + "wxRegKey", + "wxScopedArray", + "wxScopedCharTypeBuffer", + "wxScopedPtr", + "wxScopedPtr< T >", + "wxSharedPtr< T >", + "wxServer", + "wxSockAddress", + "wxSocketBase", + "wxSocketClient", + "wxSocketEvent", + "wxSocketInputStream", + "wxSocketOutputStream", + "wxSortedArrayString", + "wxStopWatch", + "wxStreamBase", + "wxStreamBuffer", + "wxStreamToTextRedirector", + "wxString", + "wxStringBuffer", + "wxStringBufferLength", + "wxStringClientData", + "wxStringInputStream", + "wxStringOutputStream", + "wxTarClassFactory", + "wxTarEntry", + "wxTarInputStream", + "wxTarOutputStream", + "wxTCPClient", + "wxTCPConnection", + "wxTCPServer", + "wxTempFile", + "wxTempFileOutputStream", + "wxTextInputStream", + "wxTextOutputStream", + "wxThread", + "wxThreadEvent", + "wxThreadHelper", + "wxULongLong", + "wxUniChar", + "wxUniCharRef", + "wxURI", + "wxURL", + "wxUString", + "wxVariant", + "wxVariantData", + "wxVector< T >", + "wxVector< T >::reverse_iterator", + "wxWCharBuffer", + "wxWeakRef< T >", + "wxWeakRefDynamic< T >", + "wxZipInputStream", + "wxZipOutputStream", + "wxZlibInputStream", + "wxZlibOutputStream", + ] + +def get_first_value(alist): + if len(alist) > 0: + return alist[0] + else: + return "" + +def make_enums(aclass): + retval = "" + for enum in aclass.enums: + retval += "enum %s {\n" % enum + num_values = len(aclass.enums[enum]) + for value in aclass.enums[enum]: + retval += " %s" % value + if not value == aclass.enums[enum][-1]: + retval += ", " + retval += "\n" + retval += "};\n\n" + + return retval diff --git a/docs/doxygen/scripts/doxymlparser.py b/docs/doxygen/scripts/doxymlparser.py index 414cf988d2..06c66870c7 100755 --- a/docs/doxygen/scripts/doxymlparser.py +++ b/docs/doxygen/scripts/doxymlparser.py @@ -23,6 +23,8 @@ import string import sys import types + +from common import * from xml.dom import minidom option_dict = { @@ -42,12 +44,6 @@ for opt in option_dict: options, arguments = parser.parse_args() -def get_first_value(alist): - if len(alist) > 0: - return alist[0] - else: - return "" - class ClassDefinition: def __init__(self): self.name = "" diff --git a/docs/doxygen/scripts/make_bindings.py b/docs/doxygen/scripts/make_bindings.py index 34f4d45d49..e3e83047c1 100644 --- a/docs/doxygen/scripts/make_bindings.py +++ b/docs/doxygen/scripts/make_bindings.py @@ -3,8 +3,12 @@ import optparse import sys import os import string +import sip_tools +import swig_tools import types +from common import * + option_dict = { "output_dir" : ("output", "Directory to output bindings to"), "sip" : (True, "Produce SIP bindings"), @@ -12,151 +16,6 @@ option_dict = { } -# format: class : {method : (prototype1, prototype2)} -# using a "*" means all prototypes -ignored_methods = { - "wxIcon": {'wxIcon': (['const char', 'int', 'int'], )}, - -} - -# these classes are either replaced by different data types in bindings, or have equivalent / better -# functionality provided by the target language. -excluded_classes = [ - "wxArchiveClassFactory", - "wxArchiveEntry", - "wxArchiveInputStream", - "wxArchiveIterator", - "wxArchiveNotifier", - "wxArchiveOutputStream", - "wxArray< T >", - "wxArrayString", - "wxAutomationObject", - "wxBufferedInputStream", - "wxBufferedOutputStream", - "wxCharBuffer", - "wxCharTypeBuffer", - "wxClassInfo", - "wxCmdLineParser", - "wxCondition", - "wxConnection", - "wxConnectionBase", - "wxConvAuto", - "wxCountingOutputStream", - "wxCriticalSection", - "wxCriticalSectionLocker", - "wxCSConv", - "wxDatagramSocket", - "wxDataInputStream", - "wxDataOutputStream", - "wxDir", - "wxDirTraverser", - "wxFFile", - "wxFFileInputStream", - "wxFFileOutputStream", - "wxFile", - "wxFileInputStream", - "wxFileName", - "wxFileOutputStream", - "wxFileStream", - "wxFilterClassFactory", - "wxFilterInputStream", - "wxFilterOutputStream", - "wxFSFile", - "wxFSVolume", - "wxFTP", - "wxHashMap", - "wxHashSet", - "wxHashTable", - "wxHTTP", - "wxImage::HSVValue", - "wxImage::RGBValue", - "wxInputStream", - "wxIPAddress", - "wxIPV4Address", - "wxList< T >", - "wxLongLong", - "wxMBConv", - "wxMBConvFile", - "wxMBConvUTF7", - "wxMBConvUTF8", - "wxMBConvUTF16", - "wxMBConvUTF32", - "wxMemoryBuffer", - "wxMemoryFSHandler", - "wxMemoryInputStream", - "wxMemoryOutputStream", - "wxMessageQueue< T >", - "wxModule", - "wxMutex", - "wxMutexLocker", - "wxNode< T >", - "wxObjectDataPtr< T >", - "wxObjectRefData", - "wxOutputStream", - "wxProcess", - "wxProcessEvent", - "wxProtocol", - "wxProtocolLog", - "wxRecursionGuard", - "wxRecursionGuardFlag", - "wxRegKey", - "wxScopedArray", - "wxScopedCharTypeBuffer", - "wxScopedPtr", - "wxScopedPtr< T >", - "wxSharedPtr< T >", - "wxServer", - "wxSockAddress", - "wxSocketBase", - "wxSocketClient", - "wxSocketEvent", - "wxSocketInputStream", - "wxSocketOutputStream", - "wxSortedArrayString", - "wxStopWatch", - "wxStreamBase", - "wxStreamBuffer", - "wxStreamToTextRedirector", - "wxString", - "wxStringBuffer", - "wxStringBufferLength", - "wxStringClientData", - "wxStringInputStream", - "wxStringOutputStream", - "wxTarClassFactory", - "wxTarEntry", - "wxTarInputStream", - "wxTarOutputStream", - "wxTCPClient", - "wxTCPConnection", - "wxTCPServer", - "wxTempFile", - "wxTempFileOutputStream", - "wxTextInputStream", - "wxTextOutputStream", - "wxThread", - "wxThreadEvent", - "wxThreadHelper", - "wxULongLong", - "wxUniChar", - "wxUniCharRef", - "wxURI", - "wxURL", - "wxUString", - "wxVariant", - "wxVariantData", - "wxVector< T >", - "wxVector< T >::reverse_iterator", - "wxWCharBuffer", - "wxWeakRef< T >", - "wxWeakRefDynamic< T >", - "wxZipInputStream", - "wxZipOutputStream", - "wxZlibInputStream", - "wxZlibOutputStream", - ] - - parser = optparse.OptionParser(usage="usage: %prog \n" , version="%prog 1.0") for opt in option_dict: @@ -169,166 +28,6 @@ for opt in option_dict: options, arguments = parser.parse_args() -def get_first_value(alist): - if len(alist) > 0: - return alist[0] - else: - return "" - -def make_enums(aclass): - retval = "" - for enum in aclass.enums: - retval += "enum %s {\n" % enum - num_values = len(aclass.enums[enum]) - for value in aclass.enums[enum]: - retval += " %s" % value - if not value == aclass.enums[enum][-1]: - retval += ", " - retval += "\n" - retval += "};\n\n" - - return retval - -class SIPBuilder: - def __init__(self, doxyparse, outputdir): - self.doxyparser = doxyparse - self.output_dir = outputdir - - def make_bindings(self): - output_dir = os.path.abspath(os.path.join(self.output_dir, "sip")) - if not os.path.exists(output_dir): - os.makedirs(output_dir) - - for aclass in self.doxyparser.classes: - if aclass.name in excluded_classes: - print "Skipping %s" % aclass.name - continue - - header_name = aclass.name[2:].lower() - filename = os.path.join(output_dir, header_name + ".sip") - enums_text = make_enums(aclass) - method_text = self.make_sip_methods(aclass) - base_class = get_first_value(aclass.bases) - if base_class != "": - base_class = ": %s" % base_class - - text = """ -%s -class %s %s -{ -%%TypeHeaderCode -#include <%s> -%%End - -public: -%s -}; -""" % (enums_text, aclass.name, base_class, get_first_value(aclass.includes), method_text) - - afile = open(filename, "wb") - afile.write(text) - afile.close() - - - def make_sip_methods(self, aclass): - retval = "" - - for amethod in aclass.constructors + aclass.methods: - transfer = "" - - # we need to come up with a way of filtering the methods out by various criteria - # including parameters and method name, and how to deal with overloads - if aclass.name in ignored_methods: - should_ignore = False - for method in ignored_methods[aclass.name]: - print "method = %s" % method - if method == amethod.name: - params = ignored_methods[aclass.name][method] - should_ignore = True - for i in xrange(len(params)): - if i >= len(amethod.params): - should_ignore = False - break - elif amethod.params[i]["type"] != params[i]: - print "param type = %s, amethod.param type = %s" % (params[i], amethod.params[i]["type"]) - should_ignore = False - break - - if should_ignore: - print "Ignoring method %s..." % amethod.name - continue - - if amethod in aclass.constructors and self.doxyparser.is_derived_from_base(aclass, "wxWindow"): - transfer = "/Transfer/" - - if amethod.name.startswith("operator"): - continue - - retval += " %s %s%s%s;\n\n" % (amethod.return_type.replace("virtual ", ""), amethod.name, amethod.argsstring, transfer) - - return retval - - - -class SWIGBuilder: - def __init__(self, doxyparse, outputdir): - self.doxyparser = doxyparse - self.output_dir = outputdir - - def make_bindings(self): - output_dir = os.path.abspath(os.path.join(self.output_dir, "swig")) - if not os.path.exists(output_dir): - os.makedirs(output_dir) - - for aclass in self.doxyparser.classes: - header_name = aclass.name[2:].lower() - if aclass.name in excluded_classes: - #print "Skipping %s" % aclass.name - continue - - filename = os.path.join(output_dir, header_name + ".i") - enums_text = make_enums(aclass) - method_text = self.make_swig_methods(aclass) - text = """ -%%newgroup - -%s -class %s : publib %s -{ - -public: -%s -}; -""" % (enums_text, aclass.name, get_first_value(aclass.bases), method_text) - - afile = open(filename, "wb") - afile.write(text) - afile.close() - - - def make_swig_methods(self, aclass): - retval = "" - - retval += """ - %%pythonAppend %s "self._setOORInfo(self)" - %%pythonAppend %s() "" - %%typemap(out) %s*; // turn off this typemap - """ % (aclass.name, aclass.name, aclass.name) - - for amethod in aclass.constructors: - retval += " %s%s;\n\n" % (amethod.name, amethod.argsstring) - - retval += """ - // Turn it back on again - %%typemap(out) %s* { $result = wxPyMake_wxObject($1, $owner); } - """ % aclass.name - - for amethod in aclass.methods: - retval += " %s %s%s;\n\n" % (amethod.return_type, amethod.name, amethod.argsstring) - - return retval - - if __name__ == "__main__": if len(arguments) < 1: parser.print_usage() @@ -339,9 +38,9 @@ if __name__ == "__main__": doxyparse.parse(arg) if options.sip: - builder = SIPBuilder(doxyparse, options.output_dir) + builder = sip_tools.SIPBuilder(doxyparse, options.output_dir) builder.make_bindings() if options.swig: - builder = SWIGBuilder(doxyparse, options.output_dir) + builder = swig_tools.SWIGBuilder(doxyparse, options.output_dir) builder.make_bindings() diff --git a/docs/doxygen/scripts/sip_tools.py b/docs/doxygen/scripts/sip_tools.py new file mode 100644 index 0000000000..a187e81731 --- /dev/null +++ b/docs/doxygen/scripts/sip_tools.py @@ -0,0 +1,84 @@ +import os + +from common import * + +class SIPBuilder: + def __init__(self, doxyparse, outputdir): + self.doxyparser = doxyparse + self.output_dir = outputdir + + def make_bindings(self): + output_dir = os.path.abspath(os.path.join(self.output_dir, "sip")) + if not os.path.exists(output_dir): + os.makedirs(output_dir) + + for aclass in self.doxyparser.classes: + if aclass.name in excluded_classes: + print "Skipping %s" % aclass.name + continue + + header_name = aclass.name[2:].lower() + filename = os.path.join(output_dir, header_name + ".sip") + enums_text = make_enums(aclass) + method_text = self.make_sip_methods(aclass) + base_class = get_first_value(aclass.bases) + if base_class != "": + base_class = ": %s" % base_class + + text = """ +%s +class %s %s +{ +%%TypeHeaderCode +#include <%s> +%%End + +public: +%s +}; +""" % (enums_text, aclass.name, base_class, get_first_value(aclass.includes), method_text) + + afile = open(filename, "wb") + afile.write(text) + afile.close() + + + def make_sip_methods(self, aclass): + retval = "" + + for amethod in aclass.constructors + aclass.methods: + transfer = "" + + # FIXME: we need to come up with a way of filtering the methods out by various criteria + # including parameters and method name, and how to deal with overloads + if aclass.name in ignored_methods: + should_ignore = False + for method in ignored_methods[aclass.name]: + print "method = %s" % method + if method == amethod.name: + params = ignored_methods[aclass.name][method] + should_ignore = True + for i in xrange(len(params)): + if i >= len(amethod.params): + should_ignore = False + break + elif amethod.params[i]["type"] != params[i]: + print "param type = %s, amethod.param type = %s" % (params[i], amethod.params[i]["type"]) + should_ignore = False + break + + if should_ignore: + continue + + # We need to let SIP know when wx is responsible for deleting the object. + # We do this if the class is derived from wxWindow, since wxTLW manages child windows + # and wxApp deletes all wxTLWs on shutdown + if amethod in aclass.constructors and self.doxyparser.is_derived_from_base(aclass, "wxWindow"): + transfer = "/Transfer/" + + if amethod.name.startswith("operator"): + continue + + retval += " %s %s%s%s;\n\n" % (amethod.return_type.replace("virtual ", ""), amethod.name, amethod.argsstring, transfer) + + return retval diff --git a/docs/doxygen/scripts/swig_tools.py b/docs/doxygen/scripts/swig_tools.py new file mode 100644 index 0000000000..3e2ee21469 --- /dev/null +++ b/docs/doxygen/scripts/swig_tools.py @@ -0,0 +1,61 @@ +import os + +from common import * + +class SWIGBuilder: + def __init__(self, doxyparse, outputdir): + self.doxyparser = doxyparse + self.output_dir = outputdir + + def make_bindings(self): + output_dir = os.path.abspath(os.path.join(self.output_dir, "swig")) + if not os.path.exists(output_dir): + os.makedirs(output_dir) + + for aclass in self.doxyparser.classes: + header_name = aclass.name[2:].lower() + if aclass.name in excluded_classes: + #print "Skipping %s" % aclass.name + continue + + filename = os.path.join(output_dir, header_name + ".i") + enums_text = make_enums(aclass) + method_text = self.make_swig_methods(aclass) + text = """ +%%newgroup + +%s +class %s : publib %s +{ + +public: +%s +}; +""" % (enums_text, aclass.name, get_first_value(aclass.bases), method_text) + + afile = open(filename, "wb") + afile.write(text) + afile.close() + + + def make_swig_methods(self, aclass): + retval = "" + + retval += """ + %%pythonAppend %s "self._setOORInfo(self)" + %%pythonAppend %s() "" + %%typemap(out) %s*; // turn off this typemap + """ % (aclass.name, aclass.name, aclass.name) + + for amethod in aclass.constructors: + retval += " %s%s;\n\n" % (amethod.name, amethod.argsstring) + + retval += """ + // Turn it back on again + %%typemap(out) %s* { $result = wxPyMake_wxObject($1, $owner); } + """ % aclass.name + + for amethod in aclass.methods: + retval += " %s %s%s;\n\n" % (amethod.return_type, amethod.name, amethod.argsstring) + + return retval -- 2.45.2