python: keep consistent handling of Python integer conversion
[libvirt-python/ericb.git] / generator.py
bloba98a8948fe9b12059e712622112453278304ed1b
1 #!/usr/bin/python -u
3 # generate python wrappers from the XML API description
6 functions = {}
7 qemu_functions = {}
8 enums = {} # { enumType: { enumConstant: enumValue } }
9 qemu_enums = {} # { enumType: { enumConstant: enumValue } }
11 import os
12 import sys
13 import string
14 import re
16 quiet=True
18 if __name__ == "__main__":
19 # launched as a script
20 srcPref = os.path.dirname(sys.argv[0])
21 if len(sys.argv) > 1:
22 python = sys.argv[1]
23 else:
24 print "Python binary not specified"
25 sys.exit(1)
26 else:
27 # imported
28 srcPref = os.path.dirname(__file__)
30 #######################################################################
32 # That part if purely the API acquisition phase from the
33 # libvirt API description
35 #######################################################################
36 import os
37 import xml.sax
39 debug = 0
41 def getparser():
42 # Attach parser to an unmarshalling object. return both objects.
43 target = docParser()
44 parser = xml.sax.make_parser()
45 parser.setContentHandler(target)
46 return parser, target
48 class docParser(xml.sax.handler.ContentHandler):
49 def __init__(self):
50 self._methodname = None
51 self._data = []
52 self.in_function = 0
54 self.startElement = self.start
55 self.endElement = self.end
56 self.characters = self.data
58 def close(self):
59 if debug:
60 print "close"
62 def getmethodname(self):
63 return self._methodname
65 def data(self, text):
66 if debug:
67 print "data %s" % text
68 self._data.append(text)
70 def cdata(self, text):
71 if debug:
72 print "data %s" % text
73 self._data.append(text)
75 def start(self, tag, attrs):
76 if debug:
77 print "start %s, %s" % (tag, attrs)
78 if tag == 'function':
79 self._data = []
80 self.in_function = 1
81 self.function = None
82 self.function_cond = None
83 self.function_args = []
84 self.function_descr = None
85 self.function_return = None
86 self.function_file = None
87 self.function_module= None
88 if attrs.has_key('name'):
89 self.function = attrs['name']
90 if attrs.has_key('file'):
91 self.function_file = attrs['file']
92 if attrs.has_key('module'):
93 self.function_module= attrs['module']
94 elif tag == 'cond':
95 self._data = []
96 elif tag == 'info':
97 self._data = []
98 elif tag == 'arg':
99 if self.in_function == 1:
100 self.function_arg_name = None
101 self.function_arg_type = None
102 self.function_arg_info = None
103 if attrs.has_key('name'):
104 self.function_arg_name = attrs['name']
105 if self.function_arg_name == 'from':
106 self.function_arg_name = 'frm'
107 if attrs.has_key('type'):
108 self.function_arg_type = attrs['type']
109 if attrs.has_key('info'):
110 self.function_arg_info = attrs['info']
111 elif tag == 'return':
112 if self.in_function == 1:
113 self.function_return_type = None
114 self.function_return_info = None
115 self.function_return_field = None
116 if attrs.has_key('type'):
117 self.function_return_type = attrs['type']
118 if attrs.has_key('info'):
119 self.function_return_info = attrs['info']
120 if attrs.has_key('field'):
121 self.function_return_field = attrs['field']
122 elif tag == 'enum':
123 if (attrs['file'] == "libvirt" or
124 attrs['file'] == "virterror"):
125 enum(attrs['type'],attrs['name'],attrs['value'])
126 elif attrs['file'] == "libvirt-qemu":
127 qemu_enum(attrs['type'],attrs['name'],attrs['value'])
129 def end(self, tag):
130 if debug:
131 print "end %s" % tag
132 if tag == 'function':
133 if self.function != None:
134 if (self.function_module == "libvirt" or
135 self.function_module == "event" or
136 self.function_module == "virterror"):
137 function(self.function, self.function_descr,
138 self.function_return, self.function_args,
139 self.function_file, self.function_module,
140 self.function_cond)
141 elif self.function_module == "libvirt-qemu":
142 qemu_function(self.function, self.function_descr,
143 self.function_return, self.function_args,
144 self.function_file, self.function_module,
145 self.function_cond)
146 elif self.function_file == "python":
147 function(self.function, self.function_descr,
148 self.function_return, self.function_args,
149 self.function_file, self.function_module,
150 self.function_cond)
151 elif self.function_file == "python-qemu":
152 qemu_function(self.function, self.function_descr,
153 self.function_return, self.function_args,
154 self.function_file, self.function_module,
155 self.function_cond)
156 self.in_function = 0
157 elif tag == 'arg':
158 if self.in_function == 1:
159 self.function_args.append([self.function_arg_name,
160 self.function_arg_type,
161 self.function_arg_info])
162 elif tag == 'return':
163 if self.in_function == 1:
164 self.function_return = [self.function_return_type,
165 self.function_return_info,
166 self.function_return_field]
167 elif tag == 'info':
168 str = ''
169 for c in self._data:
170 str = str + c
171 if self.in_function == 1:
172 self.function_descr = str
173 elif tag == 'cond':
174 str = ''
175 for c in self._data:
176 str = str + c
177 if self.in_function == 1:
178 self.function_cond = str
181 def function(name, desc, ret, args, file, module, cond):
182 functions[name] = (desc, ret, args, file, module, cond)
184 def qemu_function(name, desc, ret, args, file, module, cond):
185 qemu_functions[name] = (desc, ret, args, file, module, cond)
187 def enum(type, name, value):
188 if not enums.has_key(type):
189 enums[type] = {}
190 if value == 'VIR_TYPED_PARAM_INT':
191 value = 1
192 elif value == 'VIR_TYPED_PARAM_UINT':
193 value = 2
194 elif value == 'VIR_TYPED_PARAM_LLONG':
195 value = 3
196 elif value == 'VIR_TYPED_PARAM_ULLONG':
197 value = 4
198 elif value == 'VIR_TYPED_PARAM_DOUBLE':
199 value = 5
200 elif value == 'VIR_TYPED_PARAM_BOOLEAN':
201 value = 6
202 elif value == 'VIR_DOMAIN_AFFECT_CURRENT':
203 value = 0
204 elif value == 'VIR_DOMAIN_AFFECT_LIVE':
205 value = 1
206 elif value == 'VIR_DOMAIN_AFFECT_CONFIG':
207 value = 2
208 if name[-5:] != '_LAST':
209 enums[type][name] = value
211 def qemu_enum(type, name, value):
212 if not qemu_enums.has_key(type):
213 qemu_enums[type] = {}
214 qemu_enums[type][name] = value
217 #######################################################################
219 # Some filtering rukes to drop functions/types which should not
220 # be exposed as-is on the Python interface
222 #######################################################################
224 functions_failed = []
225 qemu_functions_failed = []
226 functions_skipped = [
227 "virConnectListDomains",
229 qemu_functions_skipped = []
231 skipped_modules = {
234 skipped_types = {
235 # 'int *': "usually a return type",
236 'virConnectDomainEventCallback': "No function types in python",
237 'virConnectDomainEventGenericCallback': "No function types in python",
238 'virConnectDomainEventRTCChangeCallback': "No function types in python",
239 'virConnectDomainEventWatchdogCallback': "No function types in python",
240 'virConnectDomainEventIOErrorCallback': "No function types in python",
241 'virConnectDomainEventGraphicsCallback': "No function types in python",
242 'virStreamEventCallback': "No function types in python",
243 'virEventHandleCallback': "No function types in python",
244 'virEventTimeoutCallback': "No function types in python",
245 'virDomainBlockJobInfoPtr': "Not implemented yet",
248 #######################################################################
250 # Table of remapping to/from the python type or class to the C
251 # counterpart.
253 #######################################################################
255 py_types = {
256 'void': (None, None, None, None),
257 'int': ('i', None, "int", "int"),
258 'long': ('l', None, "long", "long"),
259 'double': ('d', None, "double", "double"),
260 'unsigned int': ('i', None, "int", "int"),
261 'unsigned long': ('l', None, "long", "long"),
262 'long long': ('l', None, "longlong", "long long"),
263 'unsigned long long': ('l', None, "longlong", "long long"),
264 'unsigned char *': ('z', None, "charPtr", "char *"),
265 'char *': ('z', None, "charPtr", "char *"),
266 'const char *': ('z', None, "constcharPtr", "const char *"),
267 'size_t': ('n', None, "size_t", "size_t"),
269 'virDomainPtr': ('O', "virDomain", "virDomainPtr", "virDomainPtr"),
270 'const virDomainPtr': ('O', "virDomain", "virDomainPtr", "virDomainPtr"),
271 'virDomain *': ('O', "virDomain", "virDomainPtr", "virDomainPtr"),
272 'const virDomain *': ('O', "virDomain", "virDomainPtr", "virDomainPtr"),
274 'virNetworkPtr': ('O', "virNetwork", "virNetworkPtr", "virNetworkPtr"),
275 'const virNetworkPtr': ('O', "virNetwork", "virNetworkPtr", "virNetworkPtr"),
276 'virNetwork *': ('O', "virNetwork", "virNetworkPtr", "virNetworkPtr"),
277 'const virNetwork *': ('O', "virNetwork", "virNetworkPtr", "virNetworkPtr"),
279 'virInterfacePtr': ('O', "virInterface", "virInterfacePtr", "virInterfacePtr"),
280 'const virInterfacePtr': ('O', "virInterface", "virInterfacePtr", "virInterfacePtr"),
281 'virInterface *': ('O', "virInterface", "virInterfacePtr", "virInterfacePtr"),
282 'const virInterface *': ('O', "virInterface", "virInterfacePtr", "virInterfacePtr"),
284 'virStoragePoolPtr': ('O', "virStoragePool", "virStoragePoolPtr", "virStoragePoolPtr"),
285 'const virStoragePoolPtr': ('O', "virStoragePool", "virStoragePoolPtr", "virStoragePoolPtr"),
286 'virStoragePool *': ('O', "virStoragePool", "virStoragePoolPtr", "virStoragePoolPtr"),
287 'const virStoragePool *': ('O', "virStoragePool", "virStoragePoolPtr", "virStoragePoolPtr"),
289 'virStorageVolPtr': ('O', "virStorageVol", "virStorageVolPtr", "virStorageVolPtr"),
290 'const virStorageVolPtr': ('O', "virStorageVol", "virStorageVolPtr", "virStorageVolPtr"),
291 'virStorageVol *': ('O', "virStorageVol", "virStorageVolPtr", "virStorageVolPtr"),
292 'const virStorageVol *': ('O', "virStorageVol", "virStorageVolPtr", "virStorageVolPtr"),
294 'virConnectPtr': ('O', "virConnect", "virConnectPtr", "virConnectPtr"),
295 'const virConnectPtr': ('O', "virConnect", "virConnectPtr", "virConnectPtr"),
296 'virConnect *': ('O', "virConnect", "virConnectPtr", "virConnectPtr"),
297 'const virConnect *': ('O', "virConnect", "virConnectPtr", "virConnectPtr"),
299 'virNodeDevicePtr': ('O', "virNodeDevice", "virNodeDevicePtr", "virNodeDevicePtr"),
300 'const virNodeDevicePtr': ('O', "virNodeDevice", "virNodeDevicePtr", "virNodeDevicePtr"),
301 'virNodeDevice *': ('O', "virNodeDevice", "virNodeDevicePtr", "virNodeDevicePtr"),
302 'const virNodeDevice *': ('O', "virNodeDevice", "virNodeDevicePtr", "virNodeDevicePtr"),
304 'virSecretPtr': ('O', "virSecret", "virSecretPtr", "virSecretPtr"),
305 'const virSecretPtr': ('O', "virSecret", "virSecretPtr", "virSecretPtr"),
306 'virSecret *': ('O', "virSecret", "virSecretPtr", "virSecretPtr"),
307 'const virSecret *': ('O', "virSecret", "virSecretPtr", "virSecretPtr"),
309 'virNWFilterPtr': ('O', "virNWFilter", "virNWFilterPtr", "virNWFilterPtr"),
310 'const virNWFilterPtr': ('O', "virNWFilter", "virNWFilterPtr", "virNWFilterPtr"),
311 'virNWFilter *': ('O', "virNWFilter", "virNWFilterPtr", "virNWFilterPtr"),
312 'const virNWFilter *': ('O', "virNWFilter", "virNWFilterPtr", "virNWFilterPtr"),
314 'virStreamPtr': ('O', "virStream", "virStreamPtr", "virStreamPtr"),
315 'const virStreamPtr': ('O', "virStream", "virStreamPtr", "virStreamPtr"),
316 'virStream *': ('O', "virStream", "virStreamPtr", "virStreamPtr"),
317 'const virStream *': ('O', "virStream", "virStreamPtr", "virStreamPtr"),
319 'virDomainSnapshotPtr': ('O', "virDomainSnapshot", "virDomainSnapshotPtr", "virDomainSnapshotPtr"),
320 'const virDomainSnapshotPtr': ('O', "virDomainSnapshot", "virDomainSnapshotPtr", "virDomainSnapshotPtr"),
321 'virDomainSnapshot *': ('O', "virDomainSnapshot", "virDomainSnapshotPtr", "virDomainSnapshotPtr"),
322 'const virDomainSnapshot *': ('O', "virDomainSnapshot", "virDomainSnapshotPtr", "virDomainSnapshotPtr"),
325 py_return_types = {
328 unknown_types = {}
330 foreign_encoding_args = (
333 #######################################################################
335 # This part writes the C <-> Python stubs libvirt.[ch] and
336 # the table libvirt-export.c to add when registrering the Python module
338 #######################################################################
340 # Class methods which are written by hand in libvirt.c but the Python-level
341 # code is still automatically generated (so they are not in skip_function()).
342 skip_impl = (
343 'virConnectGetVersion',
344 'virConnectGetLibVersion',
345 'virConnectListDomainsID',
346 'virConnectListDefinedDomains',
347 'virConnectListNetworks',
348 'virConnectListDefinedNetworks',
349 'virConnectListSecrets',
350 'virConnectListInterfaces',
351 'virConnectListStoragePools',
352 'virConnectListDefinedStoragePools',
353 'virConnectListStorageVols',
354 'virConnectListDefinedStorageVols',
355 'virConnectListDefinedInterfaces',
356 'virConnectListNWFilters',
357 'virDomainSnapshotListNames',
358 'virDomainSnapshotListChildrenNames',
359 'virConnGetLastError',
360 'virGetLastError',
361 'virDomainGetInfo',
362 'virDomainGetState',
363 'virDomainGetControlInfo',
364 'virDomainGetBlockInfo',
365 'virDomainGetJobInfo',
366 'virNodeGetInfo',
367 'virDomainGetUUID',
368 'virDomainGetUUIDString',
369 'virDomainLookupByUUID',
370 'virNetworkGetUUID',
371 'virNetworkGetUUIDString',
372 'virNetworkLookupByUUID',
373 'virDomainGetAutostart',
374 'virNetworkGetAutostart',
375 'virDomainBlockStats',
376 'virDomainInterfaceStats',
377 'virDomainMemoryStats',
378 'virNodeGetCellsFreeMemory',
379 'virDomainGetSchedulerType',
380 'virDomainGetSchedulerParameters',
381 'virDomainGetSchedulerParametersFlags',
382 'virDomainSetSchedulerParameters',
383 'virDomainSetSchedulerParametersFlags',
384 'virDomainSetBlkioParameters',
385 'virDomainGetBlkioParameters',
386 'virDomainSetMemoryParameters',
387 'virDomainGetMemoryParameters',
388 'virDomainSetNumaParameters',
389 'virDomainGetNumaParameters',
390 'virDomainGetVcpus',
391 'virDomainPinVcpu',
392 'virDomainPinVcpuFlags',
393 'virDomainGetVcpuPinInfo',
394 'virSecretGetValue',
395 'virSecretSetValue',
396 'virSecretGetUUID',
397 'virSecretGetUUIDString',
398 'virSecretLookupByUUID',
399 'virNWFilterGetUUID',
400 'virNWFilterGetUUIDString',
401 'virNWFilterLookupByUUID',
402 'virStoragePoolGetUUID',
403 'virStoragePoolGetUUIDString',
404 'virStoragePoolLookupByUUID',
405 'virStoragePoolGetInfo',
406 'virStorageVolGetInfo',
407 'virStoragePoolGetAutostart',
408 'virStoragePoolListVolumes',
409 'virDomainBlockPeek',
410 'virDomainMemoryPeek',
411 'virEventRegisterImpl',
412 'virNodeListDevices',
413 'virNodeDeviceListCaps',
414 'virConnectBaselineCPU',
415 'virDomainRevertToSnapshot',
416 'virDomainSendKey',
417 'virNodeGetCPUStats',
418 'virNodeGetMemoryStats',
419 'virDomainGetBlockJobInfo',
420 'virDomainMigrateGetMaxSpeed',
421 'virDomainBlockStatsFlags',
422 'virDomainSetBlockIoTune',
423 'virDomainGetBlockIoTune',
424 'virDomainSetInterfaceParameters',
425 'virDomainGetInterfaceParameters',
426 'virDomainGetCPUStats',
427 'virDomainGetDiskErrors',
428 'virConnectUnregisterCloseCallback',
429 'virConnectRegisterCloseCallback',
430 'virNodeGetMemoryParameters',
431 'virNodeSetMemoryParameters',
434 qemu_skip_impl = (
435 'virDomainQemuMonitorCommand',
436 'virDomainQemuAgentCommand',
440 # These are functions which the generator skips completly - no python
441 # or C code is generated. Generally should not be used for any more
442 # functions than those already listed
443 skip_function = (
444 'virConnectListDomains', # Python API is called virConectListDomainsID for unknown reasons
445 'virConnSetErrorFunc', # Not used in Python API XXX is this a bug ?
446 'virResetError', # Not used in Python API XXX is this a bug ?
447 'virGetVersion', # Python C code is manually written
448 'virSetErrorFunc', # Python API is called virRegisterErrorHandler for unknown reasons
449 'virConnCopyLastError', # Python API is called virConnGetLastError instead
450 'virCopyLastError', # Python API is called virGetLastError instead
451 'virConnectOpenAuth', # Python C code is manually written
452 'virDefaultErrorFunc', # Python virErrorFuncHandler impl calls this from C
453 'virDomainGetSecurityLabel', # Needs investigation...
454 'virDomainGetSecurityLabelList', # Needs investigation...
455 'virNodeGetSecurityModel', # Needs investigation...
456 'virConnectDomainEventRegister', # overridden in virConnect.py
457 'virConnectDomainEventDeregister', # overridden in virConnect.py
458 'virConnectDomainEventRegisterAny', # overridden in virConnect.py
459 'virConnectDomainEventDeregisterAny', # overridden in virConnect.py
460 'virSaveLastError', # We have our own python error wrapper
461 'virFreeError', # Only needed if we use virSaveLastError
462 'virConnectListAllDomains', # overridden in virConnect.py
463 'virDomainListAllSnapshots', # overridden in virDomain.py
464 'virDomainSnapshotListAllChildren', # overridden in virDomainSnapshot.py
465 'virConnectListAllStoragePools', # overridden in virConnect.py
466 'virStoragePoolListAllVolumes', # overridden in virStoragePool.py
467 'virConnectListAllNetworks', # overridden in virConnect.py
468 'virConnectListAllInterfaces', # overridden in virConnect.py
469 'virConnectListAllNodeDevices', # overridden in virConnect.py
470 'virConnectListAllNWFilters', # overridden in virConnect.py
471 'virConnectListAllSecrets', # overridden in virConnect.py
473 'virStreamRecvAll', # Pure python libvirt-override-virStream.py
474 'virStreamSendAll', # Pure python libvirt-override-virStream.py
475 'virStreamRecv', # overridden in libvirt-override-virStream.py
476 'virStreamSend', # overridden in libvirt-override-virStream.py
478 # 'Ref' functions have no use for bindings users.
479 "virConnectRef",
480 "virDomainRef",
481 "virInterfaceRef",
482 "virNetworkRef",
483 "virNodeDeviceRef",
484 "virSecretRef",
485 "virNWFilterRef",
486 "virStoragePoolRef",
487 "virStorageVolRef",
488 'virStreamRef',
490 # This functions shouldn't be called via the bindings (and even the docs
491 # contain an explicit warning to that effect). The equivalent should be
492 # implemented in pure python for each class
493 "virDomainGetConnect",
494 "virInterfaceGetConnect",
495 "virNetworkGetConnect",
496 "virSecretGetConnect",
497 "virNWFilterGetConnect",
498 "virStoragePoolGetConnect",
499 "virStorageVolGetConnect",
502 qemu_skip_function = (
503 #"virDomainQemuAttach",
506 # Generate C code, but skip python impl
507 function_skip_python_impl = (
508 "virStreamFree", # Needed in custom virStream __del__, but free shouldn't
509 # be exposed in bindings
512 qemu_function_skip_python_impl = ()
514 function_skip_index_one = (
515 "virDomainRevertToSnapshot",
518 def print_function_wrapper(module, name, output, export, include):
519 global py_types
520 global unknown_types
521 global functions
522 global qemu_functions
523 global skipped_modules
524 global function_skip_python_impl
526 try:
527 if module == "libvirt":
528 (desc, ret, args, file, mod, cond) = functions[name]
529 if module == "libvirt-qemu":
530 (desc, ret, args, file, mod, cond) = qemu_functions[name]
531 except:
532 print "failed to get function %s infos" % name
533 return
535 if skipped_modules.has_key(module):
536 return 0
538 if module == "libvirt":
539 if name in skip_function:
540 return 0
541 if name in skip_impl:
542 # Don't delete the function entry in the caller.
543 return 1
544 elif module == "libvirt-qemu":
545 if name in qemu_skip_function:
546 return 0
547 if name in qemu_skip_impl:
548 # Don't delete the function entry in the caller.
549 return 1
551 c_call = "";
552 format=""
553 format_args=""
554 c_args=""
555 c_return=""
556 c_convert=""
557 num_bufs=0
558 for arg in args:
559 # This should be correct
560 if arg[1][0:6] == "const ":
561 arg[1] = arg[1][6:]
562 c_args = c_args + " %s %s;\n" % (arg[1], arg[0])
563 if py_types.has_key(arg[1]):
564 (f, t, n, c) = py_types[arg[1]]
565 if (f == 'z') and (name in foreign_encoding_args) and (num_bufs == 0):
566 f = 't#'
567 if f != None:
568 format = format + f
569 if t != None:
570 format_args = format_args + ", &pyobj_%s" % (arg[0])
571 c_args = c_args + " PyObject *pyobj_%s;\n" % (arg[0])
572 c_convert = c_convert + \
573 " %s = (%s) Py%s_Get(pyobj_%s);\n" % (arg[0],
574 arg[1], t, arg[0]);
575 else:
576 format_args = format_args + ", &%s" % (arg[0])
577 if f == 't#':
578 format_args = format_args + ", &py_buffsize%d" % num_bufs
579 c_args = c_args + " int py_buffsize%d;\n" % num_bufs
580 num_bufs = num_bufs + 1
581 if c_call != "":
582 c_call = c_call + ", ";
583 c_call = c_call + "%s" % (arg[0])
584 else:
585 if skipped_types.has_key(arg[1]):
586 return 0
587 if unknown_types.has_key(arg[1]):
588 lst = unknown_types[arg[1]]
589 lst.append(name)
590 else:
591 unknown_types[arg[1]] = [name]
592 return -1
593 if format != "":
594 format = format + ":%s" % (name)
596 if ret[0] == 'void':
597 if file == "python_accessor":
598 if args[1][1] == "char *":
599 c_call = "\n VIR_FREE(%s->%s);\n" % (
600 args[0][0], args[1][0], args[0][0], args[1][0])
601 c_call = c_call + " %s->%s = (%s)strdup((const xmlChar *)%s);\n" % (args[0][0],
602 args[1][0], args[1][1], args[1][0])
603 else:
604 c_call = "\n %s->%s = %s;\n" % (args[0][0], args[1][0],
605 args[1][0])
606 else:
607 c_call = "\n %s(%s);\n" % (name, c_call);
608 ret_convert = " Py_INCREF(Py_None);\n return Py_None;\n"
609 elif py_types.has_key(ret[0]):
610 (f, t, n, c) = py_types[ret[0]]
611 c_return = " %s c_retval;\n" % (ret[0])
612 if file == "python_accessor" and ret[2] != None:
613 c_call = "\n c_retval = %s->%s;\n" % (args[0][0], ret[2])
614 else:
615 c_call = "\n c_retval = %s(%s);\n" % (name, c_call);
616 ret_convert = " py_retval = libvirt_%sWrap((%s) c_retval);\n" % (n,c)
617 ret_convert = ret_convert + " return py_retval;\n"
618 elif py_return_types.has_key(ret[0]):
619 (f, t, n, c) = py_return_types[ret[0]]
620 c_return = " %s c_retval;\n" % (ret[0])
621 c_call = "\n c_retval = %s(%s);\n" % (name, c_call);
622 ret_convert = " py_retval = libvirt_%sWrap((%s) c_retval);\n" % (n,c)
623 ret_convert = ret_convert + " return py_retval;\n"
624 else:
625 if skipped_types.has_key(ret[0]):
626 return 0
627 if unknown_types.has_key(ret[0]):
628 lst = unknown_types[ret[0]]
629 lst.append(name)
630 else:
631 unknown_types[ret[0]] = [name]
632 return -1
634 if cond != None and cond != "":
635 include.write("#if %s\n" % cond)
636 export.write("#if %s\n" % cond)
637 output.write("#if %s\n" % cond)
639 include.write("PyObject * ")
640 if module == "libvirt":
641 include.write("libvirt_%s(PyObject *self, PyObject *args);\n" % (name));
642 export.write(" { (char *)\"%s\", libvirt_%s, METH_VARARGS, NULL },\n" %
643 (name, name))
644 elif module == "libvirt-qemu":
645 include.write("libvirt_qemu_%s(PyObject *self, PyObject *args);\n" % (name));
646 export.write(" { (char *)\"%s\", libvirt_qemu_%s, METH_VARARGS, NULL },\n" %
647 (name, name))
649 if file == "python":
650 # Those have been manually generated
651 if cond != None and cond != "":
652 include.write("#endif\n");
653 export.write("#endif\n");
654 output.write("#endif\n");
655 return 1
656 if file == "python_accessor" and ret[0] != "void" and ret[2] is None:
657 # Those have been manually generated
658 if cond != None and cond != "":
659 include.write("#endif\n");
660 export.write("#endif\n");
661 output.write("#endif\n");
662 return 1
664 output.write("PyObject *\n")
665 if module == "libvirt":
666 output.write("libvirt_%s(PyObject *self ATTRIBUTE_UNUSED," % (name))
667 elif module == "libvirt-qemu":
668 output.write("libvirt_qemu_%s(PyObject *self ATTRIBUTE_UNUSED," % (name))
669 output.write(" PyObject *args")
670 if format == "":
671 output.write(" ATTRIBUTE_UNUSED")
672 output.write(") {\n")
673 if ret[0] != 'void':
674 output.write(" PyObject *py_retval;\n")
675 if c_return != "":
676 output.write(c_return)
677 if c_args != "":
678 output.write(c_args)
679 if format != "":
680 output.write("\n if (!PyArg_ParseTuple(args, (char *)\"%s\"%s))\n" %
681 (format, format_args))
682 output.write(" return NULL;\n")
683 if c_convert != "":
684 output.write(c_convert + "\n")
686 output.write(" LIBVIRT_BEGIN_ALLOW_THREADS;");
687 output.write(c_call);
688 output.write(" LIBVIRT_END_ALLOW_THREADS;\n");
689 output.write(ret_convert)
690 output.write("}\n\n")
691 if cond != None and cond != "":
692 include.write("#endif /* %s */\n" % cond)
693 export.write("#endif /* %s */\n" % cond)
694 output.write("#endif /* %s */\n" % cond)
696 if module == "libvirt":
697 if name in function_skip_python_impl:
698 return 0
699 elif module == "libvirt-qemu":
700 if name in qemu_function_skip_python_impl:
701 return 0
702 return 1
704 def buildStubs(module):
705 global py_types
706 global py_return_types
707 global unknown_types
709 if module not in ["libvirt", "libvirt-qemu"]:
710 print "ERROR: Unknown module type: %s" % module
711 return None
713 if module == "libvirt":
714 funcs = functions
715 funcs_failed = functions_failed
716 funcs_skipped = functions_skipped
717 elif module == "libvirt-qemu":
718 funcs = qemu_functions
719 funcs_failed = qemu_functions_failed
720 funcs_skipped = functions_skipped
722 api_xml = "%s-api.xml" % module
724 try:
725 f = open(os.path.join(srcPref,api_xml))
726 data = f.read()
727 (parser, target) = getparser()
728 parser.feed(data)
729 parser.close()
730 except IOError, msg:
731 try:
732 f = open(os.path.join(srcPref,"..","docs",api_xml))
733 data = f.read()
734 (parser, target) = getparser()
735 parser.feed(data)
736 parser.close()
737 except IOError, msg:
738 print file, ":", msg
739 sys.exit(1)
741 n = len(funcs.keys())
742 if not quiet:
743 print "Found %d functions in %s" % ((n), api_xml)
745 override_api_xml = "%s-override-api.xml" % module
746 py_types['pythonObject'] = ('O', "pythonObject", "pythonObject", "pythonObject")
748 try:
749 f = open(os.path.join(srcPref, override_api_xml))
750 data = f.read()
751 (parser, target) = getparser()
752 parser.feed(data)
753 parser.close()
754 except IOError, msg:
755 print file, ":", msg
757 if not quiet:
758 # XXX: This is not right, same function already in @functions
759 # will be overwritten.
760 print "Found %d functions in %s" % ((len(funcs.keys()) - n), override_api_xml)
761 nb_wrap = 0
762 failed = 0
763 skipped = 0
765 header_file = "%s.h" % module
766 export_file = "%s-export.c" % module
767 wrapper_file = "%s.c" % module
769 include = open(header_file, "w")
770 include.write("/* Generated */\n\n")
772 export = open(export_file, "w")
773 export.write("/* Generated */\n\n")
775 wrapper = open(wrapper_file, "w")
776 wrapper.write("/* Generated by generator.py */\n\n")
777 wrapper.write("#include <config.h>\n")
778 wrapper.write("#include <Python.h>\n")
779 wrapper.write("#include <libvirt/" + module + ".h>\n")
780 wrapper.write("#include \"typewrappers.h\"\n")
781 wrapper.write("#include \"" + module + ".h\"\n\n")
783 for function in funcs.keys():
784 # Skip the functions which are not for the module
785 ret = print_function_wrapper(module, function, wrapper, export, include)
786 if ret < 0:
787 failed = failed + 1
788 funcs_failed.append(function)
789 del funcs[function]
790 if ret == 0:
791 skipped = skipped + 1
792 funcs_skipped.append(function)
793 del funcs[function]
794 if ret == 1:
795 nb_wrap = nb_wrap + 1
796 include.close()
797 export.close()
798 wrapper.close()
800 if not quiet:
801 print "Generated %d wrapper functions" % nb_wrap
803 if unknown_types:
804 print "Missing type converters: "
805 for type in unknown_types.keys():
806 print "%s:%d " % (type, len(unknown_types[type])),
808 for f in funcs_failed:
809 print "ERROR: failed %s" % f
811 if failed > 0:
812 return -1
813 if len(unknown_types) > 0:
814 return -1
815 return 0
817 #######################################################################
819 # This part writes part of the Python front-end classes based on
820 # mapping rules between types and classes and also based on function
821 # renaming to get consistent function names at the Python level
823 #######################################################################
826 # The type automatically remapped to generated classes
828 classes_type = {
829 "virDomainPtr": ("._o", "virDomain(self,_obj=%s)", "virDomain"),
830 "virDomain *": ("._o", "virDomain(self, _obj=%s)", "virDomain"),
831 "virNetworkPtr": ("._o", "virNetwork(self, _obj=%s)", "virNetwork"),
832 "virNetwork *": ("._o", "virNetwork(self, _obj=%s)", "virNetwork"),
833 "virInterfacePtr": ("._o", "virInterface(self, _obj=%s)", "virInterface"),
834 "virInterface *": ("._o", "virInterface(self, _obj=%s)", "virInterface"),
835 "virStoragePoolPtr": ("._o", "virStoragePool(self, _obj=%s)", "virStoragePool"),
836 "virStoragePool *": ("._o", "virStoragePool(self, _obj=%s)", "virStoragePool"),
837 "virStorageVolPtr": ("._o", "virStorageVol(self, _obj=%s)", "virStorageVol"),
838 "virStorageVol *": ("._o", "virStorageVol(self, _obj=%s)", "virStorageVol"),
839 "virNodeDevicePtr": ("._o", "virNodeDevice(self, _obj=%s)", "virNodeDevice"),
840 "virNodeDevice *": ("._o", "virNodeDevice(self, _obj=%s)", "virNodeDevice"),
841 "virSecretPtr": ("._o", "virSecret(self, _obj=%s)", "virSecret"),
842 "virSecret *": ("._o", "virSecret(self, _obj=%s)", "virSecret"),
843 "virNWFilterPtr": ("._o", "virNWFilter(self, _obj=%s)", "virNWFilter"),
844 "virNWFilter *": ("._o", "virNWFilter(self, _obj=%s)", "virNWFilter"),
845 "virStreamPtr": ("._o", "virStream(self, _obj=%s)", "virStream"),
846 "virStream *": ("._o", "virStream(self, _obj=%s)", "virStream"),
847 "virConnectPtr": ("._o", "virConnect(_obj=%s)", "virConnect"),
848 "virConnect *": ("._o", "virConnect(_obj=%s)", "virConnect"),
849 "virDomainSnapshotPtr": ("._o", "virDomainSnapshot(self,_obj=%s)", "virDomainSnapshot"),
850 "virDomainSnapshot *": ("._o", "virDomainSnapshot(self, _obj=%s)", "virDomainSnapshot"),
853 converter_type = {
856 primary_classes = ["virDomain", "virNetwork", "virInterface",
857 "virStoragePool", "virStorageVol",
858 "virConnect", "virNodeDevice", "virSecret",
859 "virNWFilter", "virStream", "virDomainSnapshot"]
861 classes_ancestor = {
864 classes_destructors = {
865 "virDomain": "virDomainFree",
866 "virNetwork": "virNetworkFree",
867 "virInterface": "virInterfaceFree",
868 "virStoragePool": "virStoragePoolFree",
869 "virStorageVol": "virStorageVolFree",
870 "virNodeDevice" : "virNodeDeviceFree",
871 "virSecret": "virSecretFree",
872 "virNWFilter": "virNWFilterFree",
873 "virDomainSnapshot": "virDomainSnapshotFree",
874 # We hand-craft __del__ for this one
875 #"virStream": "virStreamFree",
878 class_skip_connect_impl = {
879 "virConnect" : True,
880 "virDomainSnapshot": True,
883 class_domain_impl = {
884 "virDomainSnapshot": True,
887 functions_noexcept = {
888 'virDomainGetID': True,
889 'virDomainGetName': True,
890 'virNetworkGetName': True,
891 'virInterfaceGetName': True,
892 'virStoragePoolGetName': True,
893 'virStorageVolGetName': True,
894 'virStorageVolGetkey': True,
895 'virNodeDeviceGetName': True,
896 'virNodeDeviceGetParent': True,
897 'virSecretGetUsageType': True,
898 'virSecretGetUsageID': True,
899 'virNWFilterGetName': True,
902 reference_keepers = {
905 function_classes = {}
907 function_classes["None"] = []
909 function_post = {}
911 # Functions returning an integral type which need special rules to
912 # check for errors and raise exceptions.
913 functions_int_exception_test = {
914 'virDomainGetMaxMemory': "%s == 0",
916 functions_int_default_test = "%s == -1"
918 def is_integral_type (name):
919 return not re.search ("^(unsigned)? ?(int|long)$", name) is None
921 # Functions returning lists which need special rules to check for errors
922 # and raise exceptions.
923 functions_list_exception_test = {
925 functions_list_default_test = "%s is None"
927 def is_list_type (name):
928 whitelist = [ "virDomainBlockStats",
929 "virDomainInterfaceStats" ]
931 return name[-1:] == "*" or name in whitelist
933 def nameFixup(name, classe, type, file):
934 # avoid a desastrous clash
935 listname = classe + "List"
936 ll = len(listname)
937 l = len(classe)
938 if name[0:l] == listname:
939 func = name[l:]
940 func = string.lower(func[0:1]) + func[1:]
941 elif name[0:16] == "virNetworkDefine":
942 func = name[3:]
943 func = string.lower(func[0:1]) + func[1:]
944 elif name[0:19] == "virNetworkCreateXML":
945 func = name[3:]
946 func = string.lower(func[0:1]) + func[1:]
947 elif name[0:16] == "virNetworkLookup":
948 func = name[3:]
949 func = string.lower(func[0:1]) + func[1:]
950 elif name[0:18] == "virInterfaceDefine":
951 func = name[3:]
952 func = string.lower(func[0:1]) + func[1:]
953 elif name[0:21] == "virInterfaceCreateXML":
954 func = name[3:]
955 func = string.lower(func[0:1]) + func[1:]
956 elif name[0:18] == "virInterfaceLookup":
957 func = name[3:]
958 func = string.lower(func[0:1]) + func[1:]
959 elif name[0:15] == "virSecretDefine":
960 func = name[3:]
961 func = string.lower(func[0:1]) + func[1:]
962 elif name[0:15] == "virSecretLookup":
963 func = name[3:]
964 func = string.lower(func[0:1]) + func[1:]
965 elif name[0:17] == "virNWFilterDefine":
966 func = name[3:]
967 func = string.lower(func[0:3]) + func[3:]
968 elif name[0:17] == "virNWFilterLookup":
969 func = name[3:]
970 func = string.lower(func[0:3]) + func[3:]
971 elif name[0:20] == "virStoragePoolDefine":
972 func = name[3:]
973 func = string.lower(func[0:1]) + func[1:]
974 elif name[0:23] == "virStoragePoolCreateXML":
975 func = name[3:]
976 func = string.lower(func[0:1]) + func[1:]
977 elif name[0:20] == "virStoragePoolLookup":
978 func = name[3:]
979 func = string.lower(func[0:1]) + func[1:]
980 elif name[0:19] == "virStorageVolDefine":
981 func = name[3:]
982 func = string.lower(func[0:1]) + func[1:]
983 elif name[0:19] == "virStorageVolLookup":
984 func = name[3:]
985 func = string.lower(func[0:1]) + func[1:]
986 elif name[0:20] == "virDomainGetCPUStats":
987 func = name[9:]
988 func = string.lower(func[0:1]) + func[1:]
989 elif name[0:12] == "virDomainGet":
990 func = name[12:]
991 func = string.lower(func[0:1]) + func[1:]
992 elif name[0:29] == "virDomainSnapshotLookupByName":
993 func = name[9:]
994 func = string.lower(func[0:1]) + func[1:]
995 elif name[0:26] == "virDomainSnapshotListNames":
996 func = name[9:]
997 func = string.lower(func[0:1]) + func[1:]
998 elif name[0:28] == "virDomainSnapshotNumChildren":
999 func = name[17:]
1000 func = string.lower(func[0:1]) + func[1:]
1001 elif name[0:20] == "virDomainSnapshotNum":
1002 func = name[9:]
1003 func = string.lower(func[0:1]) + func[1:]
1004 elif name[0:26] == "virDomainSnapshotCreateXML":
1005 func = name[9:]
1006 func = string.lower(func[0:1]) + func[1:]
1007 elif name[0:24] == "virDomainSnapshotCurrent":
1008 func = name[9:]
1009 func = string.lower(func[0:1]) + func[1:]
1010 elif name[0:17] == "virDomainSnapshot":
1011 func = name[17:]
1012 func = string.lower(func[0:1]) + func[1:]
1013 elif name[0:9] == "virDomain":
1014 func = name[9:]
1015 func = string.lower(func[0:1]) + func[1:]
1016 elif name[0:13] == "virNetworkGet":
1017 func = name[13:]
1018 func = string.lower(func[0:1]) + func[1:]
1019 elif name[0:10] == "virNetwork":
1020 func = name[10:]
1021 func = string.lower(func[0:1]) + func[1:]
1022 elif name[0:15] == "virInterfaceGet":
1023 func = name[15:]
1024 func = string.lower(func[0:1]) + func[1:]
1025 elif name[0:12] == "virInterface":
1026 func = name[12:]
1027 func = string.lower(func[0:1]) + func[1:]
1028 elif name[0:12] == 'virSecretGet':
1029 func = name[12:]
1030 func = string.lower(func[0:1]) + func[1:]
1031 elif name[0:9] == 'virSecret':
1032 func = name[9:]
1033 func = string.lower(func[0:1]) + func[1:]
1034 elif name[0:14] == 'virNWFilterGet':
1035 func = name[14:]
1036 func = string.lower(func[0:1]) + func[1:]
1037 elif name[0:11] == 'virNWFilter':
1038 func = name[11:]
1039 func = string.lower(func[0:1]) + func[1:]
1040 elif name[0:12] == 'virStreamNew':
1041 func = "newStream"
1042 elif name[0:9] == 'virStream':
1043 func = name[9:]
1044 func = string.lower(func[0:1]) + func[1:]
1045 elif name[0:17] == "virStoragePoolGet":
1046 func = name[17:]
1047 func = string.lower(func[0:1]) + func[1:]
1048 elif name[0:14] == "virStoragePool":
1049 func = name[14:]
1050 func = string.lower(func[0:1]) + func[1:]
1051 elif name[0:16] == "virStorageVolGet":
1052 func = name[16:]
1053 func = string.lower(func[0:1]) + func[1:]
1054 elif name[0:13] == "virStorageVol":
1055 func = name[13:]
1056 func = string.lower(func[0:1]) + func[1:]
1057 elif name[0:13] == "virNodeDevice":
1058 if name[13:16] == "Get":
1059 func = string.lower(name[16]) + name[17:]
1060 elif name[13:19] == "Lookup" or name[13:19] == "Create":
1061 func = string.lower(name[3]) + name[4:]
1062 else:
1063 func = string.lower(name[13]) + name[14:]
1064 elif name[0:7] == "virNode":
1065 func = name[7:]
1066 func = string.lower(func[0:1]) + func[1:]
1067 elif name[0:10] == "virConnect":
1068 func = name[10:]
1069 func = string.lower(func[0:1]) + func[1:]
1070 elif name[0:3] == "xml":
1071 func = name[3:]
1072 func = string.lower(func[0:1]) + func[1:]
1073 else:
1074 func = name
1075 if func == "iD":
1076 func = "ID"
1077 if func == "uUID":
1078 func = "UUID"
1079 if func == "uUIDString":
1080 func = "UUIDString"
1081 if func == "oSType":
1082 func = "OSType"
1083 if func == "xMLDesc":
1084 func = "XMLDesc"
1085 if func == "mACString":
1086 func = "MACString"
1088 return func
1091 def functionCompare(info1, info2):
1092 (index1, func1, name1, ret1, args1, file1, mod1) = info1
1093 (index2, func2, name2, ret2, args2, file2, mod2) = info2
1094 if file1 == file2:
1095 if func1 < func2:
1096 return -1
1097 if func1 > func2:
1098 return 1
1099 if file1 == "python_accessor":
1100 return -1
1101 if file2 == "python_accessor":
1102 return 1
1103 if file1 < file2:
1104 return -1
1105 if file1 > file2:
1106 return 1
1107 return 0
1109 def writeDoc(module, name, args, indent, output):
1110 if module == "libvirt":
1111 funcs = functions
1112 elif module == "libvirt-qemu":
1113 funcs = qemu_functions
1114 if funcs[name][0] is None or funcs[name][0] == "":
1115 return
1116 val = funcs[name][0]
1117 val = string.replace(val, "NULL", "None");
1118 output.write(indent)
1119 output.write('"""')
1120 i = string.find(val, "\n")
1121 while i >= 0:
1122 str = val[0:i+1]
1123 val = val[i+1:]
1124 output.write(str)
1125 i = string.find(val, "\n")
1126 output.write(indent)
1127 output.write(val)
1128 output.write(' """\n')
1130 def buildWrappers(module):
1131 global ctypes
1132 global py_types
1133 global py_return_types
1134 global unknown_types
1135 global functions
1136 global function_classes
1137 global classes_type
1138 global classes_list
1139 global converter_type
1140 global primary_classes
1141 global converter_type
1142 global classes_ancestor
1143 global converter_type
1144 global primary_classes
1145 global classes_destructors
1146 global functions_noexcept
1148 if not module == "libvirt":
1149 print "ERROR: Unknown module type: %s" % module
1150 return None
1152 for type in classes_type.keys():
1153 function_classes[classes_type[type][2]] = []
1156 # Build the list of C types to look for ordered to start
1157 # with primary classes
1159 ctypes = []
1160 classes_list = []
1161 ctypes_processed = {}
1162 classes_processed = {}
1163 for classe in primary_classes:
1164 classes_list.append(classe)
1165 classes_processed[classe] = ()
1166 for type in classes_type.keys():
1167 tinfo = classes_type[type]
1168 if tinfo[2] == classe:
1169 ctypes.append(type)
1170 ctypes_processed[type] = ()
1171 for type in classes_type.keys():
1172 if ctypes_processed.has_key(type):
1173 continue
1174 tinfo = classes_type[type]
1175 if not classes_processed.has_key(tinfo[2]):
1176 classes_list.append(tinfo[2])
1177 classes_processed[tinfo[2]] = ()
1179 ctypes.append(type)
1180 ctypes_processed[type] = ()
1182 for name in functions.keys():
1183 found = 0;
1184 (desc, ret, args, file, mod, cond) = functions[name]
1185 for type in ctypes:
1186 classe = classes_type[type][2]
1188 if name[0:3] == "vir" and len(args) >= 1 and args[0][1] == type:
1189 found = 1
1190 func = nameFixup(name, classe, type, file)
1191 info = (0, func, name, ret, args, file, mod)
1192 function_classes[classe].append(info)
1193 elif name[0:3] == "vir" and len(args) >= 2 and args[1][1] == type \
1194 and file != "python_accessor" and not name in function_skip_index_one:
1195 found = 1
1196 func = nameFixup(name, classe, type, file)
1197 info = (1, func, name, ret, args, file, mod)
1198 function_classes[classe].append(info)
1199 if found == 1:
1200 continue
1201 func = nameFixup(name, "None", file, file)
1202 info = (0, func, name, ret, args, file, mod)
1203 function_classes['None'].append(info)
1205 classes_file = "%s.py" % module
1206 extra_file = os.path.join(srcPref, "%s-override.py" % module)
1207 extra = None
1209 classes = open(classes_file, "w")
1211 if os.path.exists(extra_file):
1212 extra = open(extra_file, "r")
1213 classes.write("#! " + python + " -i\n")
1214 classes.write("#\n")
1215 classes.write("# WARNING WARNING WARNING WARNING\n")
1216 classes.write("#\n")
1217 classes.write("# This file is automatically written by generator.py. Any changes\n")
1218 classes.write("# made here will be lost.\n")
1219 classes.write("#\n")
1220 classes.write("# To change the manually written methods edit " + module + "-override.py\n")
1221 classes.write("# To change the automatically written methods edit generator.py\n")
1222 classes.write("#\n")
1223 classes.write("# WARNING WARNING WARNING WARNING\n")
1224 classes.write("#\n")
1225 if extra != None:
1226 classes.writelines(extra.readlines())
1227 classes.write("#\n")
1228 classes.write("# WARNING WARNING WARNING WARNING\n")
1229 classes.write("#\n")
1230 classes.write("# Automatically written part of python bindings for libvirt\n")
1231 classes.write("#\n")
1232 classes.write("# WARNING WARNING WARNING WARNING\n")
1233 if extra != None:
1234 extra.close()
1236 if function_classes.has_key("None"):
1237 flist = function_classes["None"]
1238 flist.sort(functionCompare)
1239 oldfile = ""
1240 for info in flist:
1241 (index, func, name, ret, args, file, mod) = info
1242 if file != oldfile:
1243 classes.write("#\n# Functions from module %s\n#\n\n" % file)
1244 oldfile = file
1245 classes.write("def %s(" % func)
1246 n = 0
1247 for arg in args:
1248 if n != 0:
1249 classes.write(", ")
1250 classes.write("%s" % arg[0])
1251 n = n + 1
1252 classes.write("):\n")
1253 writeDoc(module, name, args, ' ', classes);
1255 for arg in args:
1256 if classes_type.has_key(arg[1]):
1257 classes.write(" if %s is None: %s__o = None\n" %
1258 (arg[0], arg[0]))
1259 classes.write(" else: %s__o = %s%s\n" %
1260 (arg[0], arg[0], classes_type[arg[1]][0]))
1261 if ret[0] != "void":
1262 classes.write(" ret = ");
1263 else:
1264 classes.write(" ");
1265 classes.write("libvirtmod.%s(" % name)
1266 n = 0
1267 for arg in args:
1268 if n != 0:
1269 classes.write(", ");
1270 classes.write("%s" % arg[0])
1271 if classes_type.has_key(arg[1]):
1272 classes.write("__o");
1273 n = n + 1
1274 classes.write(")\n");
1276 if ret[0] != "void":
1277 if classes_type.has_key(ret[0]):
1279 # Raise an exception
1281 if functions_noexcept.has_key(name):
1282 classes.write(" if ret is None:return None\n");
1283 else:
1284 classes.write(
1285 " if ret is None:raise libvirtError('%s() failed')\n" %
1286 (name))
1288 classes.write(" return ");
1289 classes.write(classes_type[ret[0]][1] % ("ret"));
1290 classes.write("\n");
1292 # For functions returning an integral type there are
1293 # several things that we can do, depending on the
1294 # contents of functions_int_*:
1295 elif is_integral_type (ret[0]):
1296 if not functions_noexcept.has_key (name):
1297 if functions_int_exception_test.has_key (name):
1298 test = functions_int_exception_test[name]
1299 else:
1300 test = functions_int_default_test
1301 classes.write ((" if " + test +
1302 ": raise libvirtError ('%s() failed')\n") %
1303 ("ret", name))
1304 classes.write(" return ret\n")
1306 elif is_list_type (ret[0]):
1307 if not functions_noexcept.has_key (name):
1308 if functions_list_exception_test.has_key (name):
1309 test = functions_list_exception_test[name]
1310 else:
1311 test = functions_list_default_test
1312 classes.write ((" if " + test +
1313 ": raise libvirtError ('%s() failed')\n") %
1314 ("ret", name))
1315 classes.write(" return ret\n")
1317 else:
1318 classes.write(" return ret\n")
1320 classes.write("\n");
1322 for classname in classes_list:
1323 if classname == "None":
1324 pass
1325 else:
1326 if classes_ancestor.has_key(classname):
1327 classes.write("class %s(%s):\n" % (classname,
1328 classes_ancestor[classname]))
1329 classes.write(" def __init__(self, _obj=None):\n")
1330 if reference_keepers.has_key(classname):
1331 rlist = reference_keepers[classname]
1332 for ref in rlist:
1333 classes.write(" self.%s = None\n" % ref[1])
1334 classes.write(" self._o = _obj\n")
1335 classes.write(" %s.__init__(self, _obj=_obj)\n\n" % (
1336 classes_ancestor[classname]))
1337 else:
1338 classes.write("class %s:\n" % (classname))
1339 if classname in [ "virDomain", "virNetwork", "virInterface", "virStoragePool",
1340 "virStorageVol", "virNodeDevice", "virSecret","virStream",
1341 "virNWFilter" ]:
1342 classes.write(" def __init__(self, conn, _obj=None):\n")
1343 elif classname in [ 'virDomainSnapshot' ]:
1344 classes.write(" def __init__(self, dom, _obj=None):\n")
1345 else:
1346 classes.write(" def __init__(self, _obj=None):\n")
1347 if reference_keepers.has_key(classname):
1348 list = reference_keepers[classname]
1349 for ref in list:
1350 classes.write(" self.%s = None\n" % ref[1])
1351 if classname in [ "virDomain", "virNetwork", "virInterface",
1352 "virNodeDevice", "virSecret", "virStream",
1353 "virNWFilter" ]:
1354 classes.write(" self._conn = conn\n")
1355 elif classname in [ "virStorageVol", "virStoragePool" ]:
1356 classes.write(" self._conn = conn\n" + \
1357 " if not isinstance(conn, virConnect):\n" + \
1358 " self._conn = conn._conn\n")
1359 elif classname in [ "virDomainSnapshot" ]:
1360 classes.write(" self._dom = dom\n")
1361 classes.write(" if _obj != None:self._o = _obj;return\n")
1362 classes.write(" self._o = None\n\n");
1363 destruct=None
1364 if classes_destructors.has_key(classname):
1365 classes.write(" def __del__(self):\n")
1366 classes.write(" if self._o != None:\n")
1367 classes.write(" libvirtmod.%s(self._o)\n" %
1368 classes_destructors[classname]);
1369 classes.write(" self._o = None\n\n");
1370 destruct=classes_destructors[classname]
1372 if not class_skip_connect_impl.has_key(classname):
1373 # Build python safe 'connect' method
1374 classes.write(" def connect(self):\n")
1375 classes.write(" return self._conn\n\n")
1377 if class_domain_impl.has_key(classname):
1378 classes.write(" def domain(self):\n")
1379 classes.write(" return self._dom\n\n")
1381 flist = function_classes[classname]
1382 flist.sort(functionCompare)
1383 oldfile = ""
1384 for info in flist:
1385 (index, func, name, ret, args, file, mod) = info
1387 # Do not provide as method the destructors for the class
1388 # to avoid double free
1390 if name == destruct:
1391 continue;
1392 if file != oldfile:
1393 if file == "python_accessor":
1394 classes.write(" # accessors for %s\n" % (classname))
1395 else:
1396 classes.write(" #\n")
1397 classes.write(" # %s functions from module %s\n" % (
1398 classname, file))
1399 classes.write(" #\n\n")
1400 oldfile = file
1401 classes.write(" def %s(self" % func)
1402 n = 0
1403 for arg in args:
1404 if n != index:
1405 classes.write(", %s" % arg[0])
1406 n = n + 1
1407 classes.write("):\n")
1408 writeDoc(module, name, args, ' ', classes);
1409 n = 0
1410 for arg in args:
1411 if classes_type.has_key(arg[1]):
1412 if n != index:
1413 classes.write(" if %s is None: %s__o = None\n" %
1414 (arg[0], arg[0]))
1415 classes.write(" else: %s__o = %s%s\n" %
1416 (arg[0], arg[0], classes_type[arg[1]][0]))
1417 n = n + 1
1418 if ret[0] != "void":
1419 classes.write(" ret = ");
1420 else:
1421 classes.write(" ");
1422 n = 0
1423 classes.write("libvirtmod.%s(" % name)
1424 for arg in args:
1425 if n != 0:
1426 classes.write(", ");
1427 if n != index:
1428 classes.write("%s" % arg[0])
1429 if classes_type.has_key(arg[1]):
1430 classes.write("__o");
1431 else:
1432 classes.write("self");
1433 if classes_type.has_key(arg[1]):
1434 classes.write(classes_type[arg[1]][0])
1435 n = n + 1
1436 classes.write(")\n");
1438 if name == "virConnectClose":
1439 classes.write(" self._o = None\n")
1441 # For functions returning object types:
1442 if ret[0] != "void":
1443 if classes_type.has_key(ret[0]):
1445 # Raise an exception
1447 if functions_noexcept.has_key(name):
1448 classes.write(
1449 " if ret is None:return None\n");
1450 else:
1451 if classname == "virConnect":
1452 classes.write(
1453 " if ret is None:raise libvirtError('%s() failed', conn=self)\n" %
1454 (name))
1455 elif classname == "virDomain":
1456 classes.write(
1457 " if ret is None:raise libvirtError('%s() failed', dom=self)\n" %
1458 (name))
1459 elif classname == "virNetwork":
1460 classes.write(
1461 " if ret is None:raise libvirtError('%s() failed', net=self)\n" %
1462 (name))
1463 elif classname == "virInterface":
1464 classes.write(
1465 " if ret is None:raise libvirtError('%s() failed', net=self)\n" %
1466 (name))
1467 elif classname == "virStoragePool":
1468 classes.write(
1469 " if ret is None:raise libvirtError('%s() failed', pool=self)\n" %
1470 (name))
1471 elif classname == "virStorageVol":
1472 classes.write(
1473 " if ret is None:raise libvirtError('%s() failed', vol=self)\n" %
1474 (name))
1475 elif classname == "virDomainSnapshot":
1476 classes.write(
1477 " if ret is None:raise libvirtError('%s() failed', dom=self._dom)\n" %
1478 (name))
1479 else:
1480 classes.write(
1481 " if ret is None:raise libvirtError('%s() failed')\n" %
1482 (name))
1485 # generate the returned class wrapper for the object
1487 classes.write(" __tmp = ");
1488 classes.write(classes_type[ret[0]][1] % ("ret"));
1489 classes.write("\n");
1492 # Sometime one need to keep references of the source
1493 # class in the returned class object.
1494 # See reference_keepers for the list
1496 tclass = classes_type[ret[0]][2]
1497 if reference_keepers.has_key(tclass):
1498 list = reference_keepers[tclass]
1499 for pref in list:
1500 if pref[0] == classname:
1501 classes.write(" __tmp.%s = self\n" %
1502 pref[1])
1504 # Post-processing - just before we return.
1505 if function_post.has_key(name):
1506 classes.write(" %s\n" %
1507 (function_post[name]));
1510 # return the class
1512 classes.write(" return __tmp\n");
1513 elif converter_type.has_key(ret[0]):
1515 # Raise an exception
1517 if functions_noexcept.has_key(name):
1518 classes.write(
1519 " if ret is None:return None");
1521 # Post-processing - just before we return.
1522 if function_post.has_key(name):
1523 classes.write(" %s\n" %
1524 (function_post[name]));
1526 classes.write(" return ");
1527 classes.write(converter_type[ret[0]] % ("ret"));
1528 classes.write("\n");
1530 # For functions returning an integral type there
1531 # are several things that we can do, depending on
1532 # the contents of functions_int_*:
1533 elif is_integral_type (ret[0]):
1534 if not functions_noexcept.has_key (name):
1535 if functions_int_exception_test.has_key (name):
1536 test = functions_int_exception_test[name]
1537 else:
1538 test = functions_int_default_test
1539 if classname == "virConnect":
1540 classes.write ((" if " + test +
1541 ": raise libvirtError ('%s() failed', conn=self)\n") %
1542 ("ret", name))
1543 elif classname == "virDomain":
1544 classes.write ((" if " + test +
1545 ": raise libvirtError ('%s() failed', dom=self)\n") %
1546 ("ret", name))
1547 elif classname == "virNetwork":
1548 classes.write ((" if " + test +
1549 ": raise libvirtError ('%s() failed', net=self)\n") %
1550 ("ret", name))
1551 elif classname == "virInterface":
1552 classes.write ((" if " + test +
1553 ": raise libvirtError ('%s() failed', net=self)\n") %
1554 ("ret", name))
1555 elif classname == "virStoragePool":
1556 classes.write ((" if " + test +
1557 ": raise libvirtError ('%s() failed', pool=self)\n") %
1558 ("ret", name))
1559 elif classname == "virStorageVol":
1560 classes.write ((" if " + test +
1561 ": raise libvirtError ('%s() failed', vol=self)\n") %
1562 ("ret", name))
1563 else:
1564 classes.write ((" if " + test +
1565 ": raise libvirtError ('%s() failed')\n") %
1566 ("ret", name))
1568 # Post-processing - just before we return.
1569 if function_post.has_key(name):
1570 classes.write(" %s\n" %
1571 (function_post[name]));
1573 classes.write (" return ret\n")
1575 elif is_list_type (ret[0]):
1576 if not functions_noexcept.has_key (name):
1577 if functions_list_exception_test.has_key (name):
1578 test = functions_list_exception_test[name]
1579 else:
1580 test = functions_list_default_test
1581 if classname == "virConnect":
1582 classes.write ((" if " + test +
1583 ": raise libvirtError ('%s() failed', conn=self)\n") %
1584 ("ret", name))
1585 elif classname == "virDomain":
1586 classes.write ((" if " + test +
1587 ": raise libvirtError ('%s() failed', dom=self)\n") %
1588 ("ret", name))
1589 elif classname == "virNetwork":
1590 classes.write ((" if " + test +
1591 ": raise libvirtError ('%s() failed', net=self)\n") %
1592 ("ret", name))
1593 elif classname == "virInterface":
1594 classes.write ((" if " + test +
1595 ": raise libvirtError ('%s() failed', net=self)\n") %
1596 ("ret", name))
1597 elif classname == "virStoragePool":
1598 classes.write ((" if " + test +
1599 ": raise libvirtError ('%s() failed', pool=self)\n") %
1600 ("ret", name))
1601 elif classname == "virStorageVol":
1602 classes.write ((" if " + test +
1603 ": raise libvirtError ('%s() failed', vol=self)\n") %
1604 ("ret", name))
1605 else:
1606 classes.write ((" if " + test +
1607 ": raise libvirtError ('%s() failed')\n") %
1608 ("ret", name))
1610 # Post-processing - just before we return.
1611 if function_post.has_key(name):
1612 classes.write(" %s\n" %
1613 (function_post[name]));
1615 classes.write (" return ret\n")
1617 else:
1618 # Post-processing - just before we return.
1619 if function_post.has_key(name):
1620 classes.write(" %s\n" %
1621 (function_post[name]));
1623 classes.write(" return ret\n");
1625 classes.write("\n");
1626 # Append "<classname>.py" to class def, iff it exists
1627 try:
1628 extra = open(os.path.join(srcPref,"libvirt-override-" + classname + ".py"), "r")
1629 classes.write (" #\n")
1630 classes.write (" # %s methods from %s.py (hand coded)\n" % (classname,classname))
1631 classes.write (" #\n")
1632 classes.writelines(extra.readlines())
1633 classes.write("\n")
1634 extra.close()
1635 except:
1636 pass
1639 # Generate enum constants
1641 for type,enum in enums.items():
1642 classes.write("# %s\n" % type)
1643 items = enum.items()
1644 items.sort(lambda i1,i2: cmp(long(i1[1]),long(i2[1])))
1645 for name,value in items:
1646 classes.write("%s = %s\n" % (name,value))
1647 classes.write("\n");
1649 classes.close()
1651 def qemuBuildWrappers(module):
1652 global qemu_functions
1654 if not module == "libvirt-qemu":
1655 print "ERROR: only libvirt-qemu is supported"
1656 return None
1658 extra_file = os.path.join(srcPref, "%s-override.py" % module)
1659 extra = None
1661 fd = open("libvirt_qemu.py", "w")
1663 if os.path.exists(extra_file):
1664 extra = open(extra_file, "r")
1665 fd.write("#! " + python + " -i\n")
1666 fd.write("#\n")
1667 fd.write("# WARNING WARNING WARNING WARNING\n")
1668 fd.write("#\n")
1669 fd.write("# This file is automatically written by generator.py. Any changes\n")
1670 fd.write("# made here will be lost.\n")
1671 fd.write("#\n")
1672 fd.write("# To change the manually written methods edit " + module + "-override.py\n")
1673 fd.write("# To change the automatically written methods edit generator.py\n")
1674 fd.write("#\n")
1675 fd.write("# WARNING WARNING WARNING WARNING\n")
1676 fd.write("#\n")
1677 if extra != None:
1678 fd.writelines(extra.readlines())
1679 fd.write("#\n")
1680 fd.write("# WARNING WARNING WARNING WARNING\n")
1681 fd.write("#\n")
1682 fd.write("# Automatically written part of python bindings for libvirt\n")
1683 fd.write("#\n")
1684 fd.write("# WARNING WARNING WARNING WARNING\n")
1685 if extra != None:
1686 extra.close()
1688 fd.write("try:\n")
1689 fd.write(" import libvirtmod_qemu\n")
1690 fd.write("except ImportError, lib_e:\n")
1691 fd.write(" try:\n")
1692 fd.write(" import cygvirtmod_qemu as libvirtmod_qemu\n")
1693 fd.write(" except ImportError, cyg_e:\n")
1694 fd.write(" if str(cyg_e).count(\"No module named\"):\n")
1695 fd.write(" raise lib_e\n\n")
1697 fd.write("import libvirt\n\n");
1698 fd.write("#\n# Functions from module %s\n#\n\n" % module)
1700 # Generate functions directly, no classes
1702 for name in qemu_functions.keys():
1703 func = nameFixup(name, 'None', None, None)
1704 (desc, ret, args, file, mod, cond) = qemu_functions[name]
1705 fd.write("def %s(" % func)
1706 n = 0
1707 for arg in args:
1708 if n != 0:
1709 fd.write(", ")
1710 fd.write("%s" % arg[0])
1711 n = n + 1
1712 fd.write("):\n")
1713 writeDoc(module, name, args, ' ', fd);
1715 if ret[0] != "void":
1716 fd.write(" ret = ");
1717 else:
1718 fd.write(" ");
1719 fd.write("libvirtmod_qemu.%s(" % name)
1720 n = 0
1722 conn = None
1724 for arg in args:
1725 if arg[1] == "virConnectPtr":
1726 conn = arg[0]
1728 if n != 0:
1729 fd.write(", ");
1730 if arg[1] in ["virDomainPtr", "virConnectPtr"]:
1731 # FIXME: This might have problem if the function
1732 # has multiple args which are objects.
1733 fd.write("%s.%s" % (arg[0], "_o"))
1734 else:
1735 fd.write("%s" % arg[0])
1736 n = n + 1
1737 fd.write(")\n");
1739 if ret[0] != "void":
1740 fd.write(" if ret is None: raise libvirt.libvirtError('" + name + "() failed')\n")
1741 if ret[0] == "virDomainPtr":
1742 fd.write(" __tmp = virDomain(" + conn + ",_obj=ret)\n")
1743 fd.write(" return __tmp\n")
1744 else:
1745 fd.write(" return ret\n")
1747 fd.write("\n")
1750 # Generate enum constants
1752 for type,enum in qemu_enums.items():
1753 fd.write("# %s\n" % type)
1754 items = enum.items()
1755 items.sort(lambda i1,i2: cmp(long(i1[1]),long(i2[1])))
1756 for name,value in items:
1757 fd.write("%s = %s\n" % (name,value))
1758 fd.write("\n");
1760 fd.close()
1763 quiet = 0
1764 if buildStubs("libvirt") < 0:
1765 sys.exit(1)
1766 if buildStubs("libvirt-qemu") < 0:
1767 sys.exit(1)
1768 buildWrappers("libvirt")
1769 qemuBuildWrappers("libvirt-qemu")
1770 sys.exit(0)