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
This commit is contained in:
		
							
								
								
									
										347
									
								
								docs/doxygen/scripts/make_bindings.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										347
									
								
								docs/doxygen/scripts/make_bindings.py
									
									
									
									
									
										Normal file
									
								
							@@ -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 <doxyml files to parse>\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()
 | 
			
		||||
		Reference in New Issue
	
	Block a user