From 4e735ed6a6973429c5964c30825862a10949619c Mon Sep 17 00:00:00 2001 From: Kevin Ollivier Date: Sat, 2 May 2009 22:26:40 +0000 Subject: [PATCH] Move the scripts into a separate directory and commit initial start on automatic bindings generator. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@60490 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- docs/doxygen/{ => scripts}/doxymlparser.py | 0 docs/doxygen/scripts/make_bindings.py | 347 +++++++++++++++++++++ 2 files changed, 347 insertions(+) rename docs/doxygen/{ => scripts}/doxymlparser.py (100%) create mode 100644 docs/doxygen/scripts/make_bindings.py diff --git a/docs/doxygen/doxymlparser.py b/docs/doxygen/scripts/doxymlparser.py similarity index 100% rename from docs/doxygen/doxymlparser.py rename to docs/doxygen/scripts/doxymlparser.py diff --git a/docs/doxygen/scripts/make_bindings.py b/docs/doxygen/scripts/make_bindings.py new file mode 100644 index 0000000000..34f4d45d49 --- /dev/null +++ b/docs/doxygen/scripts/make_bindings.py @@ -0,0 +1,347 @@ +import doxymlparser +import optparse +import sys +import os +import string +import types + +option_dict = { + "output_dir" : ("output", "Directory to output bindings to"), + "sip" : (True, "Produce SIP bindings"), + "swig" : (True, "Produce SWIG bindings."), + +} + +# 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: + default = option_dict[opt][0] + + action = "store" + if type(default) == types.BooleanType: + action = "store_true" + parser.add_option("--" + opt, default=default, action=action, dest=opt, help=option_dict[opt][1]) + +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() + sys.exit(1) + + doxyparse = doxymlparser.DoxyMLParser() + for arg in arguments: + doxyparse.parse(arg) + + if options.sip: + builder = SIPBuilder(doxyparse, options.output_dir) + builder.make_bindings() + + if options.swig: + builder = SWIGBuilder(doxyparse, options.output_dir) + builder.make_bindings() -- 2.50.0