]> git.saurik.com Git - wxWidgets.git/blob - docs/doxygen/scripts/make_bindings.py
Move the scripts into a separate directory and commit initial start on automatic...
[wxWidgets.git] / docs / doxygen / scripts / make_bindings.py
1 import doxymlparser
2 import optparse
3 import sys
4 import os
5 import string
6 import types
7
8 option_dict = {
9 "output_dir" : ("output", "Directory to output bindings to"),
10 "sip" : (True, "Produce SIP bindings"),
11 "swig" : (True, "Produce SWIG bindings."),
12
13 }
14
15 # format: class : {method : (prototype1, prototype2)}
16 # using a "*" means all prototypes
17 ignored_methods = {
18 "wxIcon": {'wxIcon': (['const char', 'int', 'int'], )},
19
20 }
21
22 # these classes are either replaced by different data types in bindings, or have equivalent / better
23 # functionality provided by the target language.
24 excluded_classes = [
25 "wxArchiveClassFactory",
26 "wxArchiveEntry",
27 "wxArchiveInputStream",
28 "wxArchiveIterator",
29 "wxArchiveNotifier",
30 "wxArchiveOutputStream",
31 "wxArray< T >",
32 "wxArrayString",
33 "wxAutomationObject",
34 "wxBufferedInputStream",
35 "wxBufferedOutputStream",
36 "wxCharBuffer",
37 "wxCharTypeBuffer",
38 "wxClassInfo",
39 "wxCmdLineParser",
40 "wxCondition",
41 "wxConnection",
42 "wxConnectionBase",
43 "wxConvAuto",
44 "wxCountingOutputStream",
45 "wxCriticalSection",
46 "wxCriticalSectionLocker",
47 "wxCSConv",
48 "wxDatagramSocket",
49 "wxDataInputStream",
50 "wxDataOutputStream",
51 "wxDir",
52 "wxDirTraverser",
53 "wxFFile",
54 "wxFFileInputStream",
55 "wxFFileOutputStream",
56 "wxFile",
57 "wxFileInputStream",
58 "wxFileName",
59 "wxFileOutputStream",
60 "wxFileStream",
61 "wxFilterClassFactory",
62 "wxFilterInputStream",
63 "wxFilterOutputStream",
64 "wxFSFile",
65 "wxFSVolume",
66 "wxFTP",
67 "wxHashMap",
68 "wxHashSet",
69 "wxHashTable",
70 "wxHTTP",
71 "wxImage::HSVValue",
72 "wxImage::RGBValue",
73 "wxInputStream",
74 "wxIPAddress",
75 "wxIPV4Address",
76 "wxList< T >",
77 "wxLongLong",
78 "wxMBConv",
79 "wxMBConvFile",
80 "wxMBConvUTF7",
81 "wxMBConvUTF8",
82 "wxMBConvUTF16",
83 "wxMBConvUTF32",
84 "wxMemoryBuffer",
85 "wxMemoryFSHandler",
86 "wxMemoryInputStream",
87 "wxMemoryOutputStream",
88 "wxMessageQueue< T >",
89 "wxModule",
90 "wxMutex",
91 "wxMutexLocker",
92 "wxNode< T >",
93 "wxObjectDataPtr< T >",
94 "wxObjectRefData",
95 "wxOutputStream",
96 "wxProcess",
97 "wxProcessEvent",
98 "wxProtocol",
99 "wxProtocolLog",
100 "wxRecursionGuard",
101 "wxRecursionGuardFlag",
102 "wxRegKey",
103 "wxScopedArray",
104 "wxScopedCharTypeBuffer",
105 "wxScopedPtr",
106 "wxScopedPtr< T >",
107 "wxSharedPtr< T >",
108 "wxServer",
109 "wxSockAddress",
110 "wxSocketBase",
111 "wxSocketClient",
112 "wxSocketEvent",
113 "wxSocketInputStream",
114 "wxSocketOutputStream",
115 "wxSortedArrayString",
116 "wxStopWatch",
117 "wxStreamBase",
118 "wxStreamBuffer",
119 "wxStreamToTextRedirector",
120 "wxString",
121 "wxStringBuffer",
122 "wxStringBufferLength",
123 "wxStringClientData",
124 "wxStringInputStream",
125 "wxStringOutputStream",
126 "wxTarClassFactory",
127 "wxTarEntry",
128 "wxTarInputStream",
129 "wxTarOutputStream",
130 "wxTCPClient",
131 "wxTCPConnection",
132 "wxTCPServer",
133 "wxTempFile",
134 "wxTempFileOutputStream",
135 "wxTextInputStream",
136 "wxTextOutputStream",
137 "wxThread",
138 "wxThreadEvent",
139 "wxThreadHelper",
140 "wxULongLong",
141 "wxUniChar",
142 "wxUniCharRef",
143 "wxURI",
144 "wxURL",
145 "wxUString",
146 "wxVariant",
147 "wxVariantData",
148 "wxVector< T >",
149 "wxVector< T >::reverse_iterator",
150 "wxWCharBuffer",
151 "wxWeakRef< T >",
152 "wxWeakRefDynamic< T >",
153 "wxZipInputStream",
154 "wxZipOutputStream",
155 "wxZlibInputStream",
156 "wxZlibOutputStream",
157 ]
158
159
160 parser = optparse.OptionParser(usage="usage: %prog <doxyml files to parse>\n" , version="%prog 1.0")
161
162 for opt in option_dict:
163 default = option_dict[opt][0]
164
165 action = "store"
166 if type(default) == types.BooleanType:
167 action = "store_true"
168 parser.add_option("--" + opt, default=default, action=action, dest=opt, help=option_dict[opt][1])
169
170 options, arguments = parser.parse_args()
171
172 def get_first_value(alist):
173 if len(alist) > 0:
174 return alist[0]
175 else:
176 return ""
177
178 def make_enums(aclass):
179 retval = ""
180 for enum in aclass.enums:
181 retval += "enum %s {\n" % enum
182 num_values = len(aclass.enums[enum])
183 for value in aclass.enums[enum]:
184 retval += " %s" % value
185 if not value == aclass.enums[enum][-1]:
186 retval += ", "
187 retval += "\n"
188 retval += "};\n\n"
189
190 return retval
191
192 class SIPBuilder:
193 def __init__(self, doxyparse, outputdir):
194 self.doxyparser = doxyparse
195 self.output_dir = outputdir
196
197 def make_bindings(self):
198 output_dir = os.path.abspath(os.path.join(self.output_dir, "sip"))
199 if not os.path.exists(output_dir):
200 os.makedirs(output_dir)
201
202 for aclass in self.doxyparser.classes:
203 if aclass.name in excluded_classes:
204 print "Skipping %s" % aclass.name
205 continue
206
207 header_name = aclass.name[2:].lower()
208 filename = os.path.join(output_dir, header_name + ".sip")
209 enums_text = make_enums(aclass)
210 method_text = self.make_sip_methods(aclass)
211 base_class = get_first_value(aclass.bases)
212 if base_class != "":
213 base_class = ": %s" % base_class
214
215 text = """
216 %s
217 class %s %s
218 {
219 %%TypeHeaderCode
220 #include <%s>
221 %%End
222
223 public:
224 %s
225 };
226 """ % (enums_text, aclass.name, base_class, get_first_value(aclass.includes), method_text)
227
228 afile = open(filename, "wb")
229 afile.write(text)
230 afile.close()
231
232
233 def make_sip_methods(self, aclass):
234 retval = ""
235
236 for amethod in aclass.constructors + aclass.methods:
237 transfer = ""
238
239 # we need to come up with a way of filtering the methods out by various criteria
240 # including parameters and method name, and how to deal with overloads
241 if aclass.name in ignored_methods:
242 should_ignore = False
243 for method in ignored_methods[aclass.name]:
244 print "method = %s" % method
245 if method == amethod.name:
246 params = ignored_methods[aclass.name][method]
247 should_ignore = True
248 for i in xrange(len(params)):
249 if i >= len(amethod.params):
250 should_ignore = False
251 break
252 elif amethod.params[i]["type"] != params[i]:
253 print "param type = %s, amethod.param type = %s" % (params[i], amethod.params[i]["type"])
254 should_ignore = False
255 break
256
257 if should_ignore:
258 print "Ignoring method %s..." % amethod.name
259 continue
260
261 if amethod in aclass.constructors and self.doxyparser.is_derived_from_base(aclass, "wxWindow"):
262 transfer = "/Transfer/"
263
264 if amethod.name.startswith("operator"):
265 continue
266
267 retval += " %s %s%s%s;\n\n" % (amethod.return_type.replace("virtual ", ""), amethod.name, amethod.argsstring, transfer)
268
269 return retval
270
271
272
273 class SWIGBuilder:
274 def __init__(self, doxyparse, outputdir):
275 self.doxyparser = doxyparse
276 self.output_dir = outputdir
277
278 def make_bindings(self):
279 output_dir = os.path.abspath(os.path.join(self.output_dir, "swig"))
280 if not os.path.exists(output_dir):
281 os.makedirs(output_dir)
282
283 for aclass in self.doxyparser.classes:
284 header_name = aclass.name[2:].lower()
285 if aclass.name in excluded_classes:
286 #print "Skipping %s" % aclass.name
287 continue
288
289 filename = os.path.join(output_dir, header_name + ".i")
290 enums_text = make_enums(aclass)
291 method_text = self.make_swig_methods(aclass)
292 text = """
293 %%newgroup
294
295 %s
296 class %s : publib %s
297 {
298
299 public:
300 %s
301 };
302 """ % (enums_text, aclass.name, get_first_value(aclass.bases), method_text)
303
304 afile = open(filename, "wb")
305 afile.write(text)
306 afile.close()
307
308
309 def make_swig_methods(self, aclass):
310 retval = ""
311
312 retval += """
313 %%pythonAppend %s "self._setOORInfo(self)"
314 %%pythonAppend %s() ""
315 %%typemap(out) %s*; // turn off this typemap
316 """ % (aclass.name, aclass.name, aclass.name)
317
318 for amethod in aclass.constructors:
319 retval += " %s%s;\n\n" % (amethod.name, amethod.argsstring)
320
321 retval += """
322 // Turn it back on again
323 %%typemap(out) %s* { $result = wxPyMake_wxObject($1, $owner); }
324 """ % aclass.name
325
326 for amethod in aclass.methods:
327 retval += " %s %s%s;\n\n" % (amethod.return_type, amethod.name, amethod.argsstring)
328
329 return retval
330
331
332 if __name__ == "__main__":
333 if len(arguments) < 1:
334 parser.print_usage()
335 sys.exit(1)
336
337 doxyparse = doxymlparser.DoxyMLParser()
338 for arg in arguments:
339 doxyparse.parse(arg)
340
341 if options.sip:
342 builder = SIPBuilder(doxyparse, options.output_dir)
343 builder.make_bindings()
344
345 if options.swig:
346 builder = SWIGBuilder(doxyparse, options.output_dir)
347 builder.make_bindings()