API: make declaration of _LAST enum values conditional
[libvirt-python/ericb.git] / generator.py
blobde635dc92dc9ecdf0523fe28bb3d83104f635b29
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 'unsigned long long': ('l', None, "longlong", "long long"),
263 'unsigned char *': ('z', None, "charPtr", "char *"),
264 'char *': ('z', None, "charPtr", "char *"),
265 'const char *': ('z', None, "charPtrConst", "const char *"),
266 'size_t': ('n', None, "size_t", "size_t"),
268 'virDomainPtr': ('O', "virDomain", "virDomainPtr", "virDomainPtr"),
269 'const virDomainPtr': ('O', "virDomain", "virDomainPtr", "virDomainPtr"),
270 'virDomain *': ('O', "virDomain", "virDomainPtr", "virDomainPtr"),
271 'const virDomain *': ('O', "virDomain", "virDomainPtr", "virDomainPtr"),
273 'virNetworkPtr': ('O', "virNetwork", "virNetworkPtr", "virNetworkPtr"),
274 'const virNetworkPtr': ('O', "virNetwork", "virNetworkPtr", "virNetworkPtr"),
275 'virNetwork *': ('O', "virNetwork", "virNetworkPtr", "virNetworkPtr"),
276 'const virNetwork *': ('O', "virNetwork", "virNetworkPtr", "virNetworkPtr"),
278 'virInterfacePtr': ('O', "virInterface", "virInterfacePtr", "virInterfacePtr"),
279 'const virInterfacePtr': ('O', "virInterface", "virInterfacePtr", "virInterfacePtr"),
280 'virInterface *': ('O', "virInterface", "virInterfacePtr", "virInterfacePtr"),
281 'const virInterface *': ('O', "virInterface", "virInterfacePtr", "virInterfacePtr"),
283 'virStoragePoolPtr': ('O', "virStoragePool", "virStoragePoolPtr", "virStoragePoolPtr"),
284 'const virStoragePoolPtr': ('O', "virStoragePool", "virStoragePoolPtr", "virStoragePoolPtr"),
285 'virStoragePool *': ('O', "virStoragePool", "virStoragePoolPtr", "virStoragePoolPtr"),
286 'const virStoragePool *': ('O', "virStoragePool", "virStoragePoolPtr", "virStoragePoolPtr"),
288 'virStorageVolPtr': ('O', "virStorageVol", "virStorageVolPtr", "virStorageVolPtr"),
289 'const virStorageVolPtr': ('O', "virStorageVol", "virStorageVolPtr", "virStorageVolPtr"),
290 'virStorageVol *': ('O', "virStorageVol", "virStorageVolPtr", "virStorageVolPtr"),
291 'const virStorageVol *': ('O', "virStorageVol", "virStorageVolPtr", "virStorageVolPtr"),
293 'virConnectPtr': ('O', "virConnect", "virConnectPtr", "virConnectPtr"),
294 'const virConnectPtr': ('O', "virConnect", "virConnectPtr", "virConnectPtr"),
295 'virConnect *': ('O', "virConnect", "virConnectPtr", "virConnectPtr"),
296 'const virConnect *': ('O', "virConnect", "virConnectPtr", "virConnectPtr"),
298 'virNodeDevicePtr': ('O', "virNodeDevice", "virNodeDevicePtr", "virNodeDevicePtr"),
299 'const virNodeDevicePtr': ('O', "virNodeDevice", "virNodeDevicePtr", "virNodeDevicePtr"),
300 'virNodeDevice *': ('O', "virNodeDevice", "virNodeDevicePtr", "virNodeDevicePtr"),
301 'const virNodeDevice *': ('O', "virNodeDevice", "virNodeDevicePtr", "virNodeDevicePtr"),
303 'virSecretPtr': ('O', "virSecret", "virSecretPtr", "virSecretPtr"),
304 'const virSecretPtr': ('O', "virSecret", "virSecretPtr", "virSecretPtr"),
305 'virSecret *': ('O', "virSecret", "virSecretPtr", "virSecretPtr"),
306 'const virSecret *': ('O', "virSecret", "virSecretPtr", "virSecretPtr"),
308 'virNWFilterPtr': ('O', "virNWFilter", "virNWFilterPtr", "virNWFilterPtr"),
309 'const virNWFilterPtr': ('O', "virNWFilter", "virNWFilterPtr", "virNWFilterPtr"),
310 'virNWFilter *': ('O', "virNWFilter", "virNWFilterPtr", "virNWFilterPtr"),
311 'const virNWFilter *': ('O', "virNWFilter", "virNWFilterPtr", "virNWFilterPtr"),
313 'virStreamPtr': ('O', "virStream", "virStreamPtr", "virStreamPtr"),
314 'const virStreamPtr': ('O', "virStream", "virStreamPtr", "virStreamPtr"),
315 'virStream *': ('O', "virStream", "virStreamPtr", "virStreamPtr"),
316 'const virStream *': ('O', "virStream", "virStreamPtr", "virStreamPtr"),
318 'virDomainSnapshotPtr': ('O', "virDomainSnapshot", "virDomainSnapshotPtr", "virDomainSnapshotPtr"),
319 'const virDomainSnapshotPtr': ('O', "virDomainSnapshot", "virDomainSnapshotPtr", "virDomainSnapshotPtr"),
320 'virDomainSnapshot *': ('O', "virDomainSnapshot", "virDomainSnapshotPtr", "virDomainSnapshotPtr"),
321 'const virDomainSnapshot *': ('O', "virDomainSnapshot", "virDomainSnapshotPtr", "virDomainSnapshotPtr"),
324 py_return_types = {
327 unknown_types = {}
329 foreign_encoding_args = (
332 #######################################################################
334 # This part writes the C <-> Python stubs libvirt.[ch] and
335 # the table libvirt-export.c to add when registrering the Python module
337 #######################################################################
339 # Class methods which are written by hand in libvir.c but the Python-level
340 # code is still automatically generated (so they are not in skip_function()).
341 skip_impl = (
342 'virConnectGetVersion',
343 'virConnectGetLibVersion',
344 'virConnectListDomainsID',
345 'virConnectListDefinedDomains',
346 'virConnectListNetworks',
347 'virConnectListDefinedNetworks',
348 'virConnectListSecrets',
349 'virConnectListInterfaces',
350 'virConnectListStoragePools',
351 'virConnectListDefinedStoragePools',
352 'virConnectListStorageVols',
353 'virConnectListDefinedStorageVols',
354 'virConnectListDefinedInterfaces',
355 'virConnectListNWFilters',
356 'virDomainSnapshotListNames',
357 'virDomainSnapshotListChildrenNames',
358 'virConnGetLastError',
359 'virGetLastError',
360 'virDomainGetInfo',
361 'virDomainGetState',
362 'virDomainGetControlInfo',
363 'virDomainGetBlockInfo',
364 'virDomainGetJobInfo',
365 'virNodeGetInfo',
366 'virDomainGetUUID',
367 'virDomainGetUUIDString',
368 'virDomainLookupByUUID',
369 'virNetworkGetUUID',
370 'virNetworkGetUUIDString',
371 'virNetworkLookupByUUID',
372 'virDomainGetAutostart',
373 'virNetworkGetAutostart',
374 'virDomainBlockStats',
375 'virDomainInterfaceStats',
376 'virDomainMemoryStats',
377 'virNodeGetCellsFreeMemory',
378 'virDomainGetSchedulerType',
379 'virDomainGetSchedulerParameters',
380 'virDomainGetSchedulerParametersFlags',
381 'virDomainSetSchedulerParameters',
382 'virDomainSetSchedulerParametersFlags',
383 'virDomainSetBlkioParameters',
384 'virDomainGetBlkioParameters',
385 'virDomainSetMemoryParameters',
386 'virDomainGetMemoryParameters',
387 'virDomainSetNumaParameters',
388 'virDomainGetNumaParameters',
389 'virDomainGetVcpus',
390 'virDomainPinVcpu',
391 'virDomainPinVcpuFlags',
392 'virDomainGetVcpuPinInfo',
393 'virSecretGetValue',
394 'virSecretSetValue',
395 'virSecretGetUUID',
396 'virSecretGetUUIDString',
397 'virSecretLookupByUUID',
398 'virNWFilterGetUUID',
399 'virNWFilterGetUUIDString',
400 'virNWFilterLookupByUUID',
401 'virStoragePoolGetUUID',
402 'virStoragePoolGetUUIDString',
403 'virStoragePoolLookupByUUID',
404 'virStoragePoolGetInfo',
405 'virStorageVolGetInfo',
406 'virStoragePoolGetAutostart',
407 'virStoragePoolListVolumes',
408 'virDomainBlockPeek',
409 'virDomainMemoryPeek',
410 'virEventRegisterImpl',
411 'virNodeListDevices',
412 'virNodeDeviceListCaps',
413 'virConnectBaselineCPU',
414 'virDomainRevertToSnapshot',
415 'virDomainSendKey',
416 'virNodeGetCPUStats',
417 'virNodeGetMemoryStats',
418 'virDomainGetBlockJobInfo',
419 'virDomainMigrateGetMaxSpeed',
420 'virDomainBlockStatsFlags',
421 'virDomainSetBlockIoTune',
422 'virDomainGetBlockIoTune',
423 'virDomainSetInterfaceParameters',
424 'virDomainGetInterfaceParameters',
427 qemu_skip_impl = (
428 'virDomainQemuMonitorCommand',
432 # These are functions which the generator skips completly - no python
433 # or C code is generated. Generally should not be used for any more
434 # functions than those already listed
435 skip_function = (
436 'virConnectListDomains', # Python API is called virConectListDomainsID for unknown reasons
437 'virConnSetErrorFunc', # Not used in Python API XXX is this a bug ?
438 'virResetError', # Not used in Python API XXX is this a bug ?
439 'virGetVersion', # Python C code is manually written
440 'virSetErrorFunc', # Python API is called virRegisterErrorHandler for unknown reasons
441 'virConnCopyLastError', # Python API is called virConnGetLastError instead
442 'virCopyLastError', # Python API is called virGetLastError instead
443 'virConnectOpenAuth', # Python C code is manually written
444 'virDefaultErrorFunc', # Python virErrorFuncHandler impl calls this from C
445 'virDomainGetSecurityLabel', # Needs investigation...
446 'virNodeGetSecurityModel', # Needs investigation...
447 'virConnectDomainEventRegister', # overridden in virConnect.py
448 'virConnectDomainEventDeregister', # overridden in virConnect.py
449 'virConnectDomainEventRegisterAny', # overridden in virConnect.py
450 'virConnectDomainEventDeregisterAny', # overridden in virConnect.py
451 'virSaveLastError', # We have our own python error wrapper
452 'virFreeError', # Only needed if we use virSaveLastError
454 'virStreamRecvAll', # Pure python libvirt-override-virStream.py
455 'virStreamSendAll', # Pure python libvirt-override-virStream.py
456 'virStreamRecv', # overridden in libvirt-override-virStream.py
457 'virStreamSend', # overridden in libvirt-override-virStream.py
459 # 'Ref' functions have no use for bindings users.
460 "virConnectRef",
461 "virDomainRef",
462 "virInterfaceRef",
463 "virNetworkRef",
464 "virNodeDeviceRef",
465 "virSecretRef",
466 "virNWFilterRef",
467 "virStoragePoolRef",
468 "virStorageVolRef",
469 'virStreamRef',
471 # This functions shouldn't be called via the bindings (and even the docs
472 # contain an explicit warning to that effect). The equivalent should be
473 # implemented in pure python for each class
474 "virDomainGetConnect",
475 "virInterfaceGetConnect",
476 "virNetworkGetConnect",
477 "virSecretGetConnect",
478 "virNWFilterGetConnect",
479 "virStoragePoolGetConnect",
480 "virStorageVolGetConnect",
483 qemu_skip_function = (
484 #"virDomainQemuAttach",
487 # Generate C code, but skip python impl
488 function_skip_python_impl = (
489 "virStreamFree", # Needed in custom virStream __del__, but free shouldn't
490 # be exposed in bindings
493 qemu_function_skip_python_impl = ()
495 function_skip_index_one = (
496 "virDomainRevertToSnapshot",
499 def print_function_wrapper(module, name, output, export, include):
500 global py_types
501 global unknown_types
502 global functions
503 global qemu_functions
504 global skipped_modules
505 global function_skip_python_impl
507 try:
508 if module == "libvirt":
509 (desc, ret, args, file, mod, cond) = functions[name]
510 if module == "libvirt-qemu":
511 (desc, ret, args, file, mod, cond) = qemu_functions[name]
512 except:
513 print "failed to get function %s infos" % name
514 return
516 if skipped_modules.has_key(module):
517 return 0
519 if module == "libvirt":
520 if name in skip_function:
521 return 0
522 if name in skip_impl:
523 # Don't delete the function entry in the caller.
524 return 1
525 elif module == "libvirt-qemu":
526 if name in qemu_skip_function:
527 return 0
528 if name in qemu_skip_impl:
529 # Don't delete the function entry in the caller.
530 return 1
532 c_call = "";
533 format=""
534 format_args=""
535 c_args=""
536 c_return=""
537 c_convert=""
538 num_bufs=0
539 for arg in args:
540 # This should be correct
541 if arg[1][0:6] == "const ":
542 arg[1] = arg[1][6:]
543 c_args = c_args + " %s %s;\n" % (arg[1], arg[0])
544 if py_types.has_key(arg[1]):
545 (f, t, n, c) = py_types[arg[1]]
546 if (f == 'z') and (name in foreign_encoding_args) and (num_bufs == 0):
547 f = 't#'
548 if f != None:
549 format = format + f
550 if t != None:
551 format_args = format_args + ", &pyobj_%s" % (arg[0])
552 c_args = c_args + " PyObject *pyobj_%s;\n" % (arg[0])
553 c_convert = c_convert + \
554 " %s = (%s) Py%s_Get(pyobj_%s);\n" % (arg[0],
555 arg[1], t, arg[0]);
556 else:
557 format_args = format_args + ", &%s" % (arg[0])
558 if f == 't#':
559 format_args = format_args + ", &py_buffsize%d" % num_bufs
560 c_args = c_args + " int py_buffsize%d;\n" % num_bufs
561 num_bufs = num_bufs + 1
562 if c_call != "":
563 c_call = c_call + ", ";
564 c_call = c_call + "%s" % (arg[0])
565 else:
566 if skipped_types.has_key(arg[1]):
567 return 0
568 if unknown_types.has_key(arg[1]):
569 lst = unknown_types[arg[1]]
570 lst.append(name)
571 else:
572 unknown_types[arg[1]] = [name]
573 return -1
574 if format != "":
575 format = format + ":%s" % (name)
577 if ret[0] == 'void':
578 if file == "python_accessor":
579 if args[1][1] == "char *":
580 c_call = "\n free(%s->%s);\n" % (
581 args[0][0], args[1][0], args[0][0], args[1][0])
582 c_call = c_call + " %s->%s = (%s)strdup((const xmlChar *)%s);\n" % (args[0][0],
583 args[1][0], args[1][1], args[1][0])
584 else:
585 c_call = "\n %s->%s = %s;\n" % (args[0][0], args[1][0],
586 args[1][0])
587 else:
588 c_call = "\n %s(%s);\n" % (name, c_call);
589 ret_convert = " Py_INCREF(Py_None);\n return(Py_None);\n"
590 elif py_types.has_key(ret[0]):
591 (f, t, n, c) = py_types[ret[0]]
592 c_return = " %s c_retval;\n" % (ret[0])
593 if file == "python_accessor" and ret[2] != None:
594 c_call = "\n c_retval = %s->%s;\n" % (args[0][0], ret[2])
595 else:
596 c_call = "\n c_retval = %s(%s);\n" % (name, c_call);
597 ret_convert = " py_retval = libvirt_%sWrap((%s) c_retval);\n" % (n,c)
598 ret_convert = ret_convert + " return(py_retval);\n"
599 elif py_return_types.has_key(ret[0]):
600 (f, t, n, c) = py_return_types[ret[0]]
601 c_return = " %s c_retval;\n" % (ret[0])
602 c_call = "\n c_retval = %s(%s);\n" % (name, c_call);
603 ret_convert = " py_retval = libvirt_%sWrap((%s) c_retval);\n" % (n,c)
604 ret_convert = ret_convert + " return(py_retval);\n"
605 else:
606 if skipped_types.has_key(ret[0]):
607 return 0
608 if unknown_types.has_key(ret[0]):
609 lst = unknown_types[ret[0]]
610 lst.append(name)
611 else:
612 unknown_types[ret[0]] = [name]
613 return -1
615 if cond != None and cond != "":
616 include.write("#if %s\n" % cond)
617 export.write("#if %s\n" % cond)
618 output.write("#if %s\n" % cond)
620 include.write("PyObject * ")
621 if module == "libvirt":
622 include.write("libvirt_%s(PyObject *self, PyObject *args);\n" % (name));
623 export.write(" { (char *)\"%s\", libvirt_%s, METH_VARARGS, NULL },\n" %
624 (name, name))
625 elif module == "libvirt-qemu":
626 include.write("libvirt_qemu_%s(PyObject *self, PyObject *args);\n" % (name));
627 export.write(" { (char *)\"%s\", libvirt_qemu_%s, METH_VARARGS, NULL },\n" %
628 (name, name))
630 if file == "python":
631 # Those have been manually generated
632 if cond != None and cond != "":
633 include.write("#endif\n");
634 export.write("#endif\n");
635 output.write("#endif\n");
636 return 1
637 if file == "python_accessor" and ret[0] != "void" and ret[2] is None:
638 # Those have been manually generated
639 if cond != None and cond != "":
640 include.write("#endif\n");
641 export.write("#endif\n");
642 output.write("#endif\n");
643 return 1
645 output.write("PyObject *\n")
646 if module == "libvirt":
647 output.write("libvirt_%s(PyObject *self ATTRIBUTE_UNUSED," % (name))
648 elif module == "libvirt-qemu":
649 output.write("libvirt_qemu_%s(PyObject *self ATTRIBUTE_UNUSED," % (name))
650 output.write(" PyObject *args")
651 if format == "":
652 output.write(" ATTRIBUTE_UNUSED")
653 output.write(") {\n")
654 if ret[0] != 'void':
655 output.write(" PyObject *py_retval;\n")
656 if c_return != "":
657 output.write(c_return)
658 if c_args != "":
659 output.write(c_args)
660 if format != "":
661 output.write("\n if (!PyArg_ParseTuple(args, (char *)\"%s\"%s))\n" %
662 (format, format_args))
663 output.write(" return(NULL);\n")
664 if c_convert != "":
665 output.write(c_convert + "\n")
667 output.write(" LIBVIRT_BEGIN_ALLOW_THREADS;");
668 output.write(c_call);
669 output.write(" LIBVIRT_END_ALLOW_THREADS;\n");
670 output.write(ret_convert)
671 output.write("}\n\n")
672 if cond != None and cond != "":
673 include.write("#endif /* %s */\n" % cond)
674 export.write("#endif /* %s */\n" % cond)
675 output.write("#endif /* %s */\n" % cond)
677 if module == "libvirt":
678 if name in function_skip_python_impl:
679 return 0
680 elif module == "libvirt-qemu":
681 if name in qemu_function_skip_python_impl:
682 return 0
683 return 1
685 def buildStubs(module):
686 global py_types
687 global py_return_types
688 global unknown_types
690 if module not in ["libvirt", "libvirt-qemu"]:
691 print "ERROR: Unknown module type: %s" % module
692 return None
694 if module == "libvirt":
695 funcs = functions
696 funcs_failed = functions_failed
697 funcs_skipped = functions_skipped
698 elif module == "libvirt-qemu":
699 funcs = qemu_functions
700 funcs_failed = qemu_functions_failed
701 funcs_skipped = functions_skipped
703 api_xml = "%s-api.xml" % module
705 try:
706 f = open(os.path.join(srcPref,api_xml))
707 data = f.read()
708 (parser, target) = getparser()
709 parser.feed(data)
710 parser.close()
711 except IOError, msg:
712 try:
713 f = open(os.path.join(srcPref,"..","docs",api_xml))
714 data = f.read()
715 (parser, target) = getparser()
716 parser.feed(data)
717 parser.close()
718 except IOError, msg:
719 print file, ":", msg
720 sys.exit(1)
722 n = len(funcs.keys())
723 if not quiet:
724 print "Found %d functions in %s" % ((n), api_xml)
726 override_api_xml = "%s-override-api.xml" % module
727 py_types['pythonObject'] = ('O', "pythonObject", "pythonObject", "pythonObject")
729 try:
730 f = open(os.path.join(srcPref, override_api_xml))
731 data = f.read()
732 (parser, target) = getparser()
733 parser.feed(data)
734 parser.close()
735 except IOError, msg:
736 print file, ":", msg
738 if not quiet:
739 # XXX: This is not right, same function already in @functions
740 # will be overwritten.
741 print "Found %d functions in %s" % ((len(funcs.keys()) - n), override_api_xml)
742 nb_wrap = 0
743 failed = 0
744 skipped = 0
746 header_file = "%s.h" % module
747 export_file = "%s-export.c" % module
748 wrapper_file = "%s.c" % module
750 include = open(header_file, "w")
751 include.write("/* Generated */\n\n")
753 export = open(export_file, "w")
754 export.write("/* Generated */\n\n")
756 wrapper = open(wrapper_file, "w")
757 wrapper.write("/* Generated */\n\n")
758 wrapper.write("#include <Python.h>\n")
759 wrapper.write("#include <libvirt/" + module + ".h>\n")
760 wrapper.write("#include \"typewrappers.h\"\n")
761 wrapper.write("#include \"" + module + ".h\"\n\n")
763 for function in funcs.keys():
764 # Skip the functions which are not for the module
765 ret = print_function_wrapper(module, function, wrapper, export, include)
766 if ret < 0:
767 failed = failed + 1
768 funcs_failed.append(function)
769 del funcs[function]
770 if ret == 0:
771 skipped = skipped + 1
772 funcs_skipped.append(function)
773 del funcs[function]
774 if ret == 1:
775 nb_wrap = nb_wrap + 1
776 include.close()
777 export.close()
778 wrapper.close()
780 if not quiet:
781 print "Generated %d wrapper functions" % nb_wrap
783 if unknown_types:
784 print "Missing type converters: "
785 for type in unknown_types.keys():
786 print "%s:%d " % (type, len(unknown_types[type])),
788 for f in funcs_failed:
789 print "ERROR: failed %s" % f
791 if failed > 0:
792 return -1
793 if len(unknown_types) > 0:
794 return -1
795 return 0
797 #######################################################################
799 # This part writes part of the Python front-end classes based on
800 # mapping rules between types and classes and also based on function
801 # renaming to get consistent function names at the Python level
803 #######################################################################
806 # The type automatically remapped to generated classes
808 classes_type = {
809 "virDomainPtr": ("._o", "virDomain(self,_obj=%s)", "virDomain"),
810 "virDomain *": ("._o", "virDomain(self, _obj=%s)", "virDomain"),
811 "virNetworkPtr": ("._o", "virNetwork(self, _obj=%s)", "virNetwork"),
812 "virNetwork *": ("._o", "virNetwork(self, _obj=%s)", "virNetwork"),
813 "virInterfacePtr": ("._o", "virInterface(self, _obj=%s)", "virInterface"),
814 "virInterface *": ("._o", "virInterface(self, _obj=%s)", "virInterface"),
815 "virStoragePoolPtr": ("._o", "virStoragePool(self, _obj=%s)", "virStoragePool"),
816 "virStoragePool *": ("._o", "virStoragePool(self, _obj=%s)", "virStoragePool"),
817 "virStorageVolPtr": ("._o", "virStorageVol(self, _obj=%s)", "virStorageVol"),
818 "virStorageVol *": ("._o", "virStorageVol(self, _obj=%s)", "virStorageVol"),
819 "virNodeDevicePtr": ("._o", "virNodeDevice(self, _obj=%s)", "virNodeDevice"),
820 "virNodeDevice *": ("._o", "virNodeDevice(self, _obj=%s)", "virNodeDevice"),
821 "virSecretPtr": ("._o", "virSecret(self, _obj=%s)", "virSecret"),
822 "virSecret *": ("._o", "virSecret(self, _obj=%s)", "virSecret"),
823 "virNWFilterPtr": ("._o", "virNWFilter(self, _obj=%s)", "virNWFilter"),
824 "virNWFilter *": ("._o", "virNWFilter(self, _obj=%s)", "virNWFilter"),
825 "virStreamPtr": ("._o", "virStream(self, _obj=%s)", "virStream"),
826 "virStream *": ("._o", "virStream(self, _obj=%s)", "virStream"),
827 "virConnectPtr": ("._o", "virConnect(_obj=%s)", "virConnect"),
828 "virConnect *": ("._o", "virConnect(_obj=%s)", "virConnect"),
829 "virDomainSnapshotPtr": ("._o", "virDomainSnapshot(self,_obj=%s)", "virDomainSnapshot"),
830 "virDomainSnapshot *": ("._o", "virDomainSnapshot(self, _obj=%s)", "virDomainSnapshot"),
833 converter_type = {
836 primary_classes = ["virDomain", "virNetwork", "virInterface",
837 "virStoragePool", "virStorageVol",
838 "virConnect", "virNodeDevice", "virSecret",
839 "virNWFilter", "virStream", "virDomainSnapshot"]
841 classes_ancestor = {
844 classes_destructors = {
845 "virDomain": "virDomainFree",
846 "virNetwork": "virNetworkFree",
847 "virInterface": "virInterfaceFree",
848 "virStoragePool": "virStoragePoolFree",
849 "virStorageVol": "virStorageVolFree",
850 "virNodeDevice" : "virNodeDeviceFree",
851 "virSecret": "virSecretFree",
852 "virNWFilter": "virNWFilterFree",
853 "virDomainSnapshot": "virDomainSnapshotFree",
854 # We hand-craft __del__ for this one
855 #"virStream": "virStreamFree",
858 class_skip_connect_impl = {
859 "virConnect" : True,
860 "virDomainSnapshot": True,
863 class_domain_impl = {
864 "virDomainSnapshot": True,
867 functions_noexcept = {
868 'virDomainGetID': True,
869 'virDomainGetName': True,
870 'virNetworkGetName': True,
871 'virInterfaceGetName': True,
872 'virStoragePoolGetName': True,
873 'virStorageVolGetName': True,
874 'virStorageVolGetkey': True,
875 'virNodeDeviceGetName': True,
876 'virNodeDeviceGetParent': True,
877 'virSecretGetUsageType': True,
878 'virSecretGetUsageID': True,
879 'virNWFilterGetName': True,
882 reference_keepers = {
885 function_classes = {}
887 function_classes["None"] = []
889 function_post = {}
891 # Functions returning an integral type which need special rules to
892 # check for errors and raise exceptions.
893 functions_int_exception_test = {
894 'virDomainGetMaxMemory': "%s == 0",
896 functions_int_default_test = "%s == -1"
898 def is_integral_type (name):
899 return not re.search ("^(unsigned)? ?(int|long)$", name) is None
901 # Functions returning lists which need special rules to check for errors
902 # and raise exceptions.
903 functions_list_exception_test = {
905 functions_list_default_test = "%s is None"
907 def is_list_type (name):
908 whitelist = [ "virDomainBlockStats",
909 "virDomainInterfaceStats" ]
911 return name[-1:] == "*" or name in whitelist
913 def nameFixup(name, classe, type, file):
914 # avoid a desastrous clash
915 listname = classe + "List"
916 ll = len(listname)
917 l = len(classe)
918 if name[0:l] == listname:
919 func = name[l:]
920 func = string.lower(func[0:1]) + func[1:]
921 elif name[0:16] == "virNetworkDefine":
922 func = name[3:]
923 func = string.lower(func[0:1]) + func[1:]
924 elif name[0:19] == "virNetworkCreateXML":
925 func = name[3:]
926 func = string.lower(func[0:1]) + func[1:]
927 elif name[0:16] == "virNetworkLookup":
928 func = name[3:]
929 func = string.lower(func[0:1]) + func[1:]
930 elif name[0:18] == "virInterfaceDefine":
931 func = name[3:]
932 func = string.lower(func[0:1]) + func[1:]
933 elif name[0:21] == "virInterfaceCreateXML":
934 func = name[3:]
935 func = string.lower(func[0:1]) + func[1:]
936 elif name[0:18] == "virInterfaceLookup":
937 func = name[3:]
938 func = string.lower(func[0:1]) + func[1:]
939 elif name[0:15] == "virSecretDefine":
940 func = name[3:]
941 func = string.lower(func[0:1]) + func[1:]
942 elif name[0:15] == "virSecretLookup":
943 func = name[3:]
944 func = string.lower(func[0:1]) + func[1:]
945 elif name[0:17] == "virNWFilterDefine":
946 func = name[3:]
947 func = string.lower(func[0:3]) + func[3:]
948 elif name[0:17] == "virNWFilterLookup":
949 func = name[3:]
950 func = string.lower(func[0:3]) + func[3:]
951 elif name[0:20] == "virStoragePoolDefine":
952 func = name[3:]
953 func = string.lower(func[0:1]) + func[1:]
954 elif name[0:23] == "virStoragePoolCreateXML":
955 func = name[3:]
956 func = string.lower(func[0:1]) + func[1:]
957 elif name[0:20] == "virStoragePoolLookup":
958 func = name[3:]
959 func = string.lower(func[0:1]) + func[1:]
960 elif name[0:19] == "virStorageVolDefine":
961 func = name[3:]
962 func = string.lower(func[0:1]) + func[1:]
963 elif name[0:19] == "virStorageVolLookup":
964 func = name[3:]
965 func = string.lower(func[0:1]) + func[1:]
966 elif name[0:12] == "virDomainGet":
967 func = name[12:]
968 func = string.lower(func[0:1]) + func[1:]
969 elif name[0:29] == "virDomainSnapshotLookupByName":
970 func = name[9:]
971 func = string.lower(func[0:1]) + func[1:]
972 elif name[0:26] == "virDomainSnapshotListNames":
973 func = name[9:]
974 func = string.lower(func[0:1]) + func[1:]
975 elif name[0:28] == "virDomainSnapshotNumChildren":
976 func = name[17:]
977 func = string.lower(func[0:1]) + func[1:]
978 elif name[0:20] == "virDomainSnapshotNum":
979 func = name[9:]
980 func = string.lower(func[0:1]) + func[1:]
981 elif name[0:26] == "virDomainSnapshotCreateXML":
982 func = name[9:]
983 func = string.lower(func[0:1]) + func[1:]
984 elif name[0:24] == "virDomainSnapshotCurrent":
985 func = name[9:]
986 func = string.lower(func[0:1]) + func[1:]
987 elif name[0:17] == "virDomainSnapshot":
988 func = name[17:]
989 func = string.lower(func[0:1]) + func[1:]
990 elif name[0:9] == "virDomain":
991 func = name[9:]
992 func = string.lower(func[0:1]) + func[1:]
993 elif name[0:13] == "virNetworkGet":
994 func = name[13:]
995 func = string.lower(func[0:1]) + func[1:]
996 elif name[0:10] == "virNetwork":
997 func = name[10:]
998 func = string.lower(func[0:1]) + func[1:]
999 elif name[0:15] == "virInterfaceGet":
1000 func = name[15:]
1001 func = string.lower(func[0:1]) + func[1:]
1002 elif name[0:12] == "virInterface":
1003 func = name[12:]
1004 func = string.lower(func[0:1]) + func[1:]
1005 elif name[0:12] == 'virSecretGet':
1006 func = name[12:]
1007 func = string.lower(func[0:1]) + func[1:]
1008 elif name[0:9] == 'virSecret':
1009 func = name[9:]
1010 func = string.lower(func[0:1]) + func[1:]
1011 elif name[0:14] == 'virNWFilterGet':
1012 func = name[14:]
1013 func = string.lower(func[0:1]) + func[1:]
1014 elif name[0:11] == 'virNWFilter':
1015 func = name[11:]
1016 func = string.lower(func[0:1]) + func[1:]
1017 elif name[0:12] == 'virStreamNew':
1018 func = "newStream"
1019 elif name[0:9] == 'virStream':
1020 func = name[9:]
1021 func = string.lower(func[0:1]) + func[1:]
1022 elif name[0:17] == "virStoragePoolGet":
1023 func = name[17:]
1024 func = string.lower(func[0:1]) + func[1:]
1025 elif name[0:14] == "virStoragePool":
1026 func = name[14:]
1027 func = string.lower(func[0:1]) + func[1:]
1028 elif name[0:16] == "virStorageVolGet":
1029 func = name[16:]
1030 func = string.lower(func[0:1]) + func[1:]
1031 elif name[0:13] == "virStorageVol":
1032 func = name[13:]
1033 func = string.lower(func[0:1]) + func[1:]
1034 elif name[0:13] == "virNodeDevice":
1035 if name[13:16] == "Get":
1036 func = string.lower(name[16]) + name[17:]
1037 elif name[13:19] == "Lookup" or name[13:19] == "Create":
1038 func = string.lower(name[3]) + name[4:]
1039 else:
1040 func = string.lower(name[13]) + name[14:]
1041 elif name[0:7] == "virNode":
1042 func = name[7:]
1043 func = string.lower(func[0:1]) + func[1:]
1044 elif name[0:10] == "virConnect":
1045 func = name[10:]
1046 func = string.lower(func[0:1]) + func[1:]
1047 elif name[0:3] == "xml":
1048 func = name[3:]
1049 func = string.lower(func[0:1]) + func[1:]
1050 else:
1051 func = name
1052 if func == "iD":
1053 func = "ID"
1054 if func == "uUID":
1055 func = "UUID"
1056 if func == "uUIDString":
1057 func = "UUIDString"
1058 if func == "oSType":
1059 func = "OSType"
1060 if func == "xMLDesc":
1061 func = "XMLDesc"
1062 if func == "mACString":
1063 func = "MACString"
1065 return func
1068 def functionCompare(info1, info2):
1069 (index1, func1, name1, ret1, args1, file1, mod1) = info1
1070 (index2, func2, name2, ret2, args2, file2, mod2) = info2
1071 if file1 == file2:
1072 if func1 < func2:
1073 return -1
1074 if func1 > func2:
1075 return 1
1076 if file1 == "python_accessor":
1077 return -1
1078 if file2 == "python_accessor":
1079 return 1
1080 if file1 < file2:
1081 return -1
1082 if file1 > file2:
1083 return 1
1084 return 0
1086 def writeDoc(module, name, args, indent, output):
1087 if module == "libvirt":
1088 funcs = functions
1089 elif module == "libvirt-qemu":
1090 funcs = qemu_functions
1091 if funcs[name][0] is None or funcs[name][0] == "":
1092 return
1093 val = funcs[name][0]
1094 val = string.replace(val, "NULL", "None");
1095 output.write(indent)
1096 output.write('"""')
1097 i = string.find(val, "\n")
1098 while i >= 0:
1099 str = val[0:i+1]
1100 val = val[i+1:]
1101 output.write(str)
1102 i = string.find(val, "\n")
1103 output.write(indent)
1104 output.write(val)
1105 output.write(' """\n')
1107 def buildWrappers(module):
1108 global ctypes
1109 global py_types
1110 global py_return_types
1111 global unknown_types
1112 global functions
1113 global function_classes
1114 global classes_type
1115 global classes_list
1116 global converter_type
1117 global primary_classes
1118 global converter_type
1119 global classes_ancestor
1120 global converter_type
1121 global primary_classes
1122 global classes_destructors
1123 global functions_noexcept
1125 if not module == "libvirt":
1126 print "ERROR: Unknown module type: %s" % module
1127 return None
1129 for type in classes_type.keys():
1130 function_classes[classes_type[type][2]] = []
1133 # Build the list of C types to look for ordered to start
1134 # with primary classes
1136 ctypes = []
1137 classes_list = []
1138 ctypes_processed = {}
1139 classes_processed = {}
1140 for classe in primary_classes:
1141 classes_list.append(classe)
1142 classes_processed[classe] = ()
1143 for type in classes_type.keys():
1144 tinfo = classes_type[type]
1145 if tinfo[2] == classe:
1146 ctypes.append(type)
1147 ctypes_processed[type] = ()
1148 for type in classes_type.keys():
1149 if ctypes_processed.has_key(type):
1150 continue
1151 tinfo = classes_type[type]
1152 if not classes_processed.has_key(tinfo[2]):
1153 classes_list.append(tinfo[2])
1154 classes_processed[tinfo[2]] = ()
1156 ctypes.append(type)
1157 ctypes_processed[type] = ()
1159 for name in functions.keys():
1160 found = 0;
1161 (desc, ret, args, file, mod, cond) = functions[name]
1162 for type in ctypes:
1163 classe = classes_type[type][2]
1165 if name[0:3] == "vir" and len(args) >= 1 and args[0][1] == type:
1166 found = 1
1167 func = nameFixup(name, classe, type, file)
1168 info = (0, func, name, ret, args, file, mod)
1169 function_classes[classe].append(info)
1170 elif name[0:3] == "vir" and len(args) >= 2 and args[1][1] == type \
1171 and file != "python_accessor" and not name in function_skip_index_one:
1172 found = 1
1173 func = nameFixup(name, classe, type, file)
1174 info = (1, func, name, ret, args, file, mod)
1175 function_classes[classe].append(info)
1176 if found == 1:
1177 continue
1178 func = nameFixup(name, "None", file, file)
1179 info = (0, func, name, ret, args, file, mod)
1180 function_classes['None'].append(info)
1182 classes_file = "%s.py" % module
1183 extra_file = os.path.join(srcPref, "%s-override.py" % module)
1184 extra = None
1186 classes = open(classes_file, "w")
1188 if os.path.exists(extra_file):
1189 extra = open(extra_file, "r")
1190 classes.write("#! " + python + " -i\n")
1191 classes.write("#\n")
1192 classes.write("# WARNING WARNING WARNING WARNING\n")
1193 classes.write("#\n")
1194 classes.write("# This file is automatically written by generator.py. Any changes\n")
1195 classes.write("# made here will be lost.\n")
1196 classes.write("#\n")
1197 classes.write("# To change the manually written methods edit " + module + "-override.py\n")
1198 classes.write("# To change the automatically written methods edit generator.py\n")
1199 classes.write("#\n")
1200 classes.write("# WARNING WARNING WARNING WARNING\n")
1201 classes.write("#\n")
1202 if extra != None:
1203 classes.writelines(extra.readlines())
1204 classes.write("#\n")
1205 classes.write("# WARNING WARNING WARNING WARNING\n")
1206 classes.write("#\n")
1207 classes.write("# Automatically written part of python bindings for libvirt\n")
1208 classes.write("#\n")
1209 classes.write("# WARNING WARNING WARNING WARNING\n")
1210 if extra != None:
1211 extra.close()
1213 if function_classes.has_key("None"):
1214 flist = function_classes["None"]
1215 flist.sort(functionCompare)
1216 oldfile = ""
1217 for info in flist:
1218 (index, func, name, ret, args, file, mod) = info
1219 if file != oldfile:
1220 classes.write("#\n# Functions from module %s\n#\n\n" % file)
1221 oldfile = file
1222 classes.write("def %s(" % func)
1223 n = 0
1224 for arg in args:
1225 if n != 0:
1226 classes.write(", ")
1227 classes.write("%s" % arg[0])
1228 n = n + 1
1229 classes.write("):\n")
1230 writeDoc(module, name, args, ' ', classes);
1232 for arg in args:
1233 if classes_type.has_key(arg[1]):
1234 classes.write(" if %s is None: %s__o = None\n" %
1235 (arg[0], arg[0]))
1236 classes.write(" else: %s__o = %s%s\n" %
1237 (arg[0], arg[0], classes_type[arg[1]][0]))
1238 if ret[0] != "void":
1239 classes.write(" ret = ");
1240 else:
1241 classes.write(" ");
1242 classes.write("libvirtmod.%s(" % name)
1243 n = 0
1244 for arg in args:
1245 if n != 0:
1246 classes.write(", ");
1247 classes.write("%s" % arg[0])
1248 if classes_type.has_key(arg[1]):
1249 classes.write("__o");
1250 n = n + 1
1251 classes.write(")\n");
1253 if ret[0] != "void":
1254 if classes_type.has_key(ret[0]):
1256 # Raise an exception
1258 if functions_noexcept.has_key(name):
1259 classes.write(" if ret is None:return None\n");
1260 else:
1261 classes.write(
1262 " if ret is None:raise libvirtError('%s() failed')\n" %
1263 (name))
1265 classes.write(" return ");
1266 classes.write(classes_type[ret[0]][1] % ("ret"));
1267 classes.write("\n");
1269 # For functions returning an integral type there are
1270 # several things that we can do, depending on the
1271 # contents of functions_int_*:
1272 elif is_integral_type (ret[0]):
1273 if not functions_noexcept.has_key (name):
1274 if functions_int_exception_test.has_key (name):
1275 test = functions_int_exception_test[name]
1276 else:
1277 test = functions_int_default_test
1278 classes.write ((" if " + test +
1279 ": raise libvirtError ('%s() failed')\n") %
1280 ("ret", name))
1281 classes.write(" return ret\n")
1283 elif is_list_type (ret[0]):
1284 if not functions_noexcept.has_key (name):
1285 if functions_list_exception_test.has_key (name):
1286 test = functions_list_exception_test[name]
1287 else:
1288 test = functions_list_default_test
1289 classes.write ((" if " + test +
1290 ": raise libvirtError ('%s() failed')\n") %
1291 ("ret", name))
1292 classes.write(" return ret\n")
1294 else:
1295 classes.write(" return ret\n")
1297 classes.write("\n");
1299 for classname in classes_list:
1300 if classname == "None":
1301 pass
1302 else:
1303 if classes_ancestor.has_key(classname):
1304 classes.write("class %s(%s):\n" % (classname,
1305 classes_ancestor[classname]))
1306 classes.write(" def __init__(self, _obj=None):\n")
1307 if reference_keepers.has_key(classname):
1308 rlist = reference_keepers[classname]
1309 for ref in rlist:
1310 classes.write(" self.%s = None\n" % ref[1])
1311 classes.write(" self._o = _obj\n")
1312 classes.write(" %s.__init__(self, _obj=_obj)\n\n" % (
1313 classes_ancestor[classname]))
1314 else:
1315 classes.write("class %s:\n" % (classname))
1316 if classname in [ "virDomain", "virNetwork", "virInterface", "virStoragePool",
1317 "virStorageVol", "virNodeDevice", "virSecret","virStream",
1318 "virNWFilter" ]:
1319 classes.write(" def __init__(self, conn, _obj=None):\n")
1320 elif classname in [ 'virDomainSnapshot' ]:
1321 classes.write(" def __init__(self, dom, _obj=None):\n")
1322 else:
1323 classes.write(" def __init__(self, _obj=None):\n")
1324 if reference_keepers.has_key(classname):
1325 list = reference_keepers[classname]
1326 for ref in list:
1327 classes.write(" self.%s = None\n" % ref[1])
1328 if classname in [ "virDomain", "virNetwork", "virInterface",
1329 "virNodeDevice", "virSecret", "virStream",
1330 "virNWFilter" ]:
1331 classes.write(" self._conn = conn\n")
1332 elif classname in [ "virStorageVol", "virStoragePool" ]:
1333 classes.write(" self._conn = conn\n" + \
1334 " if not isinstance(conn, virConnect):\n" + \
1335 " self._conn = conn._conn\n")
1336 elif classname in [ "virDomainSnapshot" ]:
1337 classes.write(" self._dom = dom\n")
1338 classes.write(" if _obj != None:self._o = _obj;return\n")
1339 classes.write(" self._o = None\n\n");
1340 destruct=None
1341 if classes_destructors.has_key(classname):
1342 classes.write(" def __del__(self):\n")
1343 classes.write(" if self._o != None:\n")
1344 classes.write(" libvirtmod.%s(self._o)\n" %
1345 classes_destructors[classname]);
1346 classes.write(" self._o = None\n\n");
1347 destruct=classes_destructors[classname]
1349 if not class_skip_connect_impl.has_key(classname):
1350 # Build python safe 'connect' method
1351 classes.write(" def connect(self):\n")
1352 classes.write(" return self._conn\n\n")
1354 if class_domain_impl.has_key(classname):
1355 classes.write(" def domain(self):\n")
1356 classes.write(" return self._dom\n\n")
1358 flist = function_classes[classname]
1359 flist.sort(functionCompare)
1360 oldfile = ""
1361 for info in flist:
1362 (index, func, name, ret, args, file, mod) = info
1364 # Do not provide as method the destructors for the class
1365 # to avoid double free
1367 if name == destruct:
1368 continue;
1369 if file != oldfile:
1370 if file == "python_accessor":
1371 classes.write(" # accessors for %s\n" % (classname))
1372 else:
1373 classes.write(" #\n")
1374 classes.write(" # %s functions from module %s\n" % (
1375 classname, file))
1376 classes.write(" #\n\n")
1377 oldfile = file
1378 classes.write(" def %s(self" % func)
1379 n = 0
1380 for arg in args:
1381 if n != index:
1382 classes.write(", %s" % arg[0])
1383 n = n + 1
1384 classes.write("):\n")
1385 writeDoc(module, name, args, ' ', classes);
1386 n = 0
1387 for arg in args:
1388 if classes_type.has_key(arg[1]):
1389 if n != index:
1390 classes.write(" if %s is None: %s__o = None\n" %
1391 (arg[0], arg[0]))
1392 classes.write(" else: %s__o = %s%s\n" %
1393 (arg[0], arg[0], classes_type[arg[1]][0]))
1394 n = n + 1
1395 if ret[0] != "void":
1396 classes.write(" ret = ");
1397 else:
1398 classes.write(" ");
1399 n = 0
1400 classes.write("libvirtmod.%s(" % name)
1401 for arg in args:
1402 if n != 0:
1403 classes.write(", ");
1404 if n != index:
1405 classes.write("%s" % arg[0])
1406 if classes_type.has_key(arg[1]):
1407 classes.write("__o");
1408 else:
1409 classes.write("self");
1410 if classes_type.has_key(arg[1]):
1411 classes.write(classes_type[arg[1]][0])
1412 n = n + 1
1413 classes.write(")\n");
1415 if name == "virConnectClose":
1416 classes.write(" self._o = None\n")
1418 # For functions returning object types:
1419 if ret[0] != "void":
1420 if classes_type.has_key(ret[0]):
1422 # Raise an exception
1424 if functions_noexcept.has_key(name):
1425 classes.write(
1426 " if ret is None:return None\n");
1427 else:
1428 if classname == "virConnect":
1429 classes.write(
1430 " if ret is None:raise libvirtError('%s() failed', conn=self)\n" %
1431 (name))
1432 elif classname == "virDomain":
1433 classes.write(
1434 " if ret is None:raise libvirtError('%s() failed', dom=self)\n" %
1435 (name))
1436 elif classname == "virNetwork":
1437 classes.write(
1438 " if ret is None:raise libvirtError('%s() failed', net=self)\n" %
1439 (name))
1440 elif classname == "virInterface":
1441 classes.write(
1442 " if ret is None:raise libvirtError('%s() failed', net=self)\n" %
1443 (name))
1444 elif classname == "virStoragePool":
1445 classes.write(
1446 " if ret is None:raise libvirtError('%s() failed', pool=self)\n" %
1447 (name))
1448 elif classname == "virStorageVol":
1449 classes.write(
1450 " if ret is None:raise libvirtError('%s() failed', vol=self)\n" %
1451 (name))
1452 elif classname == "virDomainSnapshot":
1453 classes.write(
1454 " if ret is None:raise libvirtError('%s() failed', dom=self._dom)\n" %
1455 (name))
1456 else:
1457 classes.write(
1458 " if ret is None:raise libvirtError('%s() failed')\n" %
1459 (name))
1462 # generate the returned class wrapper for the object
1464 classes.write(" __tmp = ");
1465 classes.write(classes_type[ret[0]][1] % ("ret"));
1466 classes.write("\n");
1469 # Sometime one need to keep references of the source
1470 # class in the returned class object.
1471 # See reference_keepers for the list
1473 tclass = classes_type[ret[0]][2]
1474 if reference_keepers.has_key(tclass):
1475 list = reference_keepers[tclass]
1476 for pref in list:
1477 if pref[0] == classname:
1478 classes.write(" __tmp.%s = self\n" %
1479 pref[1])
1481 # Post-processing - just before we return.
1482 if function_post.has_key(name):
1483 classes.write(" %s\n" %
1484 (function_post[name]));
1487 # return the class
1489 classes.write(" return __tmp\n");
1490 elif converter_type.has_key(ret[0]):
1492 # Raise an exception
1494 if functions_noexcept.has_key(name):
1495 classes.write(
1496 " if ret is None:return None");
1498 # Post-processing - just before we return.
1499 if function_post.has_key(name):
1500 classes.write(" %s\n" %
1501 (function_post[name]));
1503 classes.write(" return ");
1504 classes.write(converter_type[ret[0]] % ("ret"));
1505 classes.write("\n");
1507 # For functions returning an integral type there
1508 # are several things that we can do, depending on
1509 # the contents of functions_int_*:
1510 elif is_integral_type (ret[0]):
1511 if not functions_noexcept.has_key (name):
1512 if functions_int_exception_test.has_key (name):
1513 test = functions_int_exception_test[name]
1514 else:
1515 test = functions_int_default_test
1516 if classname == "virConnect":
1517 classes.write ((" if " + test +
1518 ": raise libvirtError ('%s() failed', conn=self)\n") %
1519 ("ret", name))
1520 elif classname == "virDomain":
1521 classes.write ((" if " + test +
1522 ": raise libvirtError ('%s() failed', dom=self)\n") %
1523 ("ret", name))
1524 elif classname == "virNetwork":
1525 classes.write ((" if " + test +
1526 ": raise libvirtError ('%s() failed', net=self)\n") %
1527 ("ret", name))
1528 elif classname == "virInterface":
1529 classes.write ((" if " + test +
1530 ": raise libvirtError ('%s() failed', net=self)\n") %
1531 ("ret", name))
1532 elif classname == "virStoragePool":
1533 classes.write ((" if " + test +
1534 ": raise libvirtError ('%s() failed', pool=self)\n") %
1535 ("ret", name))
1536 elif classname == "virStorageVol":
1537 classes.write ((" if " + test +
1538 ": raise libvirtError ('%s() failed', vol=self)\n") %
1539 ("ret", name))
1540 else:
1541 classes.write ((" if " + test +
1542 ": raise libvirtError ('%s() failed')\n") %
1543 ("ret", name))
1545 # Post-processing - just before we return.
1546 if function_post.has_key(name):
1547 classes.write(" %s\n" %
1548 (function_post[name]));
1550 classes.write (" return ret\n")
1552 elif is_list_type (ret[0]):
1553 if not functions_noexcept.has_key (name):
1554 if functions_list_exception_test.has_key (name):
1555 test = functions_list_exception_test[name]
1556 else:
1557 test = functions_list_default_test
1558 if classname == "virConnect":
1559 classes.write ((" if " + test +
1560 ": raise libvirtError ('%s() failed', conn=self)\n") %
1561 ("ret", name))
1562 elif classname == "virDomain":
1563 classes.write ((" if " + test +
1564 ": raise libvirtError ('%s() failed', dom=self)\n") %
1565 ("ret", name))
1566 elif classname == "virNetwork":
1567 classes.write ((" if " + test +
1568 ": raise libvirtError ('%s() failed', net=self)\n") %
1569 ("ret", name))
1570 elif classname == "virInterface":
1571 classes.write ((" if " + test +
1572 ": raise libvirtError ('%s() failed', net=self)\n") %
1573 ("ret", name))
1574 elif classname == "virStoragePool":
1575 classes.write ((" if " + test +
1576 ": raise libvirtError ('%s() failed', pool=self)\n") %
1577 ("ret", name))
1578 elif classname == "virStorageVol":
1579 classes.write ((" if " + test +
1580 ": raise libvirtError ('%s() failed', vol=self)\n") %
1581 ("ret", name))
1582 else:
1583 classes.write ((" if " + test +
1584 ": raise libvirtError ('%s() failed')\n") %
1585 ("ret", name))
1587 # Post-processing - just before we return.
1588 if function_post.has_key(name):
1589 classes.write(" %s\n" %
1590 (function_post[name]));
1592 classes.write (" return ret\n")
1594 else:
1595 # Post-processing - just before we return.
1596 if function_post.has_key(name):
1597 classes.write(" %s\n" %
1598 (function_post[name]));
1600 classes.write(" return ret\n");
1602 classes.write("\n");
1603 # Append "<classname>.py" to class def, iff it exists
1604 try:
1605 extra = open(os.path.join(srcPref,"libvirt-override-" + classname + ".py"), "r")
1606 classes.write (" #\n")
1607 classes.write (" # %s methods from %s.py (hand coded)\n" % (classname,classname))
1608 classes.write (" #\n")
1609 classes.writelines(extra.readlines())
1610 classes.write("\n")
1611 extra.close()
1612 except:
1613 pass
1616 # Generate enum constants
1618 for type,enum in enums.items():
1619 classes.write("# %s\n" % type)
1620 items = enum.items()
1621 items.sort(lambda i1,i2: cmp(long(i1[1]),long(i2[1])))
1622 for name,value in items:
1623 classes.write("%s = %s\n" % (name,value))
1624 classes.write("\n");
1626 classes.close()
1628 def qemuBuildWrappers(module):
1629 global qemu_functions
1631 if not module == "libvirt-qemu":
1632 print "ERROR: only libvirt-qemu is supported"
1633 return None
1635 extra_file = os.path.join(srcPref, "%s-override.py" % module)
1636 extra = None
1638 fd = open("libvirt_qemu.py", "w")
1640 if os.path.exists(extra_file):
1641 extra = open(extra_file, "r")
1642 fd.write("#! " + python + " -i\n")
1643 fd.write("#\n")
1644 fd.write("# WARNING WARNING WARNING WARNING\n")
1645 fd.write("#\n")
1646 fd.write("# This file is automatically written by generator.py. Any changes\n")
1647 fd.write("# made here will be lost.\n")
1648 fd.write("#\n")
1649 fd.write("# To change the manually written methods edit " + module + "-override.py\n")
1650 fd.write("# To change the automatically written methods edit generator.py\n")
1651 fd.write("#\n")
1652 fd.write("# WARNING WARNING WARNING WARNING\n")
1653 fd.write("#\n")
1654 if extra != None:
1655 fd.writelines(extra.readlines())
1656 fd.write("#\n")
1657 fd.write("# WARNING WARNING WARNING WARNING\n")
1658 fd.write("#\n")
1659 fd.write("# Automatically written part of python bindings for libvirt\n")
1660 fd.write("#\n")
1661 fd.write("# WARNING WARNING WARNING WARNING\n")
1662 if extra != None:
1663 extra.close()
1665 fd.write("try:\n")
1666 fd.write(" import libvirtmod_qemu\n")
1667 fd.write("except ImportError, lib_e:\n")
1668 fd.write(" try:\n")
1669 fd.write(" import cygvirtmod_qemu as libvirtmod_qemu\n")
1670 fd.write(" except ImportError, cyg_e:\n")
1671 fd.write(" if str(cyg_e).count(\"No module named\"):\n")
1672 fd.write(" raise lib_e\n\n")
1674 fd.write("import libvirt\n\n");
1675 fd.write("#\n# Functions from module %s\n#\n\n" % module)
1677 # Generate functions directly, no classes
1679 for name in qemu_functions.keys():
1680 func = nameFixup(name, 'None', None, None)
1681 (desc, ret, args, file, mod, cond) = qemu_functions[name]
1682 fd.write("def %s(" % func)
1683 n = 0
1684 for arg in args:
1685 if n != 0:
1686 fd.write(", ")
1687 fd.write("%s" % arg[0])
1688 n = n + 1
1689 fd.write("):\n")
1690 writeDoc(module, name, args, ' ', fd);
1692 if ret[0] != "void":
1693 fd.write(" ret = ");
1694 else:
1695 fd.write(" ");
1696 fd.write("libvirtmod_qemu.%s(" % name)
1697 n = 0
1699 conn = None
1701 for arg in args:
1702 if arg[1] == "virConnectPtr":
1703 conn = arg[0]
1705 if n != 0:
1706 fd.write(", ");
1707 if arg[1] in ["virDomainPtr", "virConnectPtr"]:
1708 # FIXME: This might have problem if the function
1709 # has multiple args which are objects.
1710 fd.write("%s.%s" % (arg[0], "_o"))
1711 else:
1712 fd.write("%s" % arg[0])
1713 n = n + 1
1714 fd.write(")\n");
1716 if ret[0] != "void":
1717 fd.write(" if ret is None: raise libvirt.libvirtError('" + name + "() failed')\n")
1718 if ret[0] == "virDomainPtr":
1719 fd.write(" __tmp = virDomain(" + conn + ",_obj=ret)\n")
1720 fd.write(" return __tmp\n")
1721 else:
1722 fd.write(" return ret\n")
1724 fd.write("\n")
1727 # Generate enum constants
1729 for type,enum in qemu_enums.items():
1730 fd.write("# %s\n" % type)
1731 items = enum.items()
1732 items.sort(lambda i1,i2: cmp(long(i1[1]),long(i2[1])))
1733 for name,value in items:
1734 fd.write("%s = %s\n" % (name,value))
1735 fd.write("\n");
1737 fd.close()
1740 quiet = 0
1741 if buildStubs("libvirt") < 0:
1742 sys.exit(1)
1743 if buildStubs("libvirt-qemu") < 0:
1744 sys.exit(1)
1745 buildWrappers("libvirt")
1746 qemuBuildWrappers("libvirt-qemu")
1747 sys.exit(0)