3 # generate python wrappers from the XML API description
8 enums
= {} # { enumType: { enumConstant: enumValue } }
9 qemu_enums
= {} # { enumType: { enumConstant: enumValue } }
18 if __name__
== "__main__":
19 # launched as a script
20 srcPref
= os
.path
.dirname(sys
.argv
[0])
24 print "Python binary not specified"
28 srcPref
= os
.path
.dirname(__file__
)
30 #######################################################################
32 # That part if purely the API acquisition phase from the
33 # libvirt API description
35 #######################################################################
42 # Attach parser to an unmarshalling object. return both objects.
44 parser
= xml
.sax
.make_parser()
45 parser
.setContentHandler(target
)
48 class docParser(xml
.sax
.handler
.ContentHandler
):
50 self
._methodname
= None
54 self
.startElement
= self
.start
55 self
.endElement
= self
.end
56 self
.characters
= self
.data
62 def getmethodname(self
):
63 return self
._methodname
67 print "data %s" % text
68 self
._data
.append(text
)
70 def cdata(self
, text
):
72 print "data %s" % text
73 self
._data
.append(text
)
75 def start(self
, tag
, attrs
):
77 print "start %s, %s" % (tag
, attrs
)
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']
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']
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'])
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
,
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
,
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
,
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
,
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
]
171 if self
.in_function
== 1:
172 self
.function_descr
= str
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):
190 if value
== 'VIR_TYPED_PARAM_INT':
192 elif value
== 'VIR_TYPED_PARAM_UINT':
194 elif value
== 'VIR_TYPED_PARAM_LLONG':
196 elif value
== 'VIR_TYPED_PARAM_ULLONG':
198 elif value
== 'VIR_TYPED_PARAM_DOUBLE':
200 elif value
== 'VIR_TYPED_PARAM_BOOLEAN':
202 elif value
== 'VIR_DOMAIN_AFFECT_CURRENT':
204 elif value
== 'VIR_DOMAIN_AFFECT_LIVE':
206 elif value
== 'VIR_DOMAIN_AFFECT_CONFIG':
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
= []
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
253 #######################################################################
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"),
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()).
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',
363 'virDomainGetControlInfo',
364 'virDomainGetBlockInfo',
365 'virDomainGetJobInfo',
368 'virDomainGetUUIDString',
369 'virDomainLookupByUUID',
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',
392 'virDomainPinVcpuFlags',
393 'virDomainGetVcpuPinInfo',
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',
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',
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
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.
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
):
522 global qemu_functions
523 global skipped_modules
524 global function_skip_python_impl
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
]
532 print "failed to get function %s infos" % name
535 if skipped_modules
.has_key(module
):
538 if module
== "libvirt":
539 if name
in skip_function
:
541 if name
in skip_impl
:
542 # Don't delete the function entry in the caller.
544 elif module
== "libvirt-qemu":
545 if name
in qemu_skip_function
:
547 if name
in qemu_skip_impl
:
548 # Don't delete the function entry in the caller.
559 # This should be correct
560 if arg
[1][0:6] == "const ":
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):
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],
576 format_args
= format_args
+ ", &%s" % (arg
[0])
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
582 c_call
= c_call
+ ", ";
583 c_call
= c_call
+ "%s" % (arg
[0])
585 if skipped_types
.has_key(arg
[1]):
587 if unknown_types
.has_key(arg
[1]):
588 lst
= unknown_types
[arg
[1]]
591 unknown_types
[arg
[1]] = [name
]
594 format
= format
+ ":%s" % (name
)
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])
604 c_call
= "\n %s->%s = %s;\n" % (args
[0][0], args
[1][0],
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])
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"
625 if skipped_types
.has_key(ret
[0]):
627 if unknown_types
.has_key(ret
[0]):
628 lst
= unknown_types
[ret
[0]]
631 unknown_types
[ret
[0]] = [name
]
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" %
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" %
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");
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");
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")
671 output
.write(" ATTRIBUTE_UNUSED")
672 output
.write(") {\n")
674 output
.write(" PyObject *py_retval;\n")
676 output
.write(c_return
)
680 output
.write("\n if (!PyArg_ParseTuple(args, (char *)\"%s\"%s))\n" %
681 (format
, format_args
))
682 output
.write(" return NULL;\n")
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
:
699 elif module
== "libvirt-qemu":
700 if name
in qemu_function_skip_python_impl
:
704 def buildStubs(module
):
706 global py_return_types
709 if module
not in ["libvirt", "libvirt-qemu"]:
710 print "ERROR: Unknown module type: %s" % module
713 if module
== "libvirt":
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
725 f
= open(os
.path
.join(srcPref
,api_xml
))
727 (parser
, target
) = getparser()
732 f
= open(os
.path
.join(srcPref
,"..","docs",api_xml
))
734 (parser
, target
) = getparser()
741 n
= len(funcs
.keys())
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")
749 f
= open(os
.path
.join(srcPref
, override_api_xml
))
751 (parser
, target
) = getparser()
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
)
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
)
788 funcs_failed
.append(function
)
791 skipped
= skipped
+ 1
792 funcs_skipped
.append(function
)
795 nb_wrap
= nb_wrap
+ 1
801 print "Generated %d wrapper functions" % nb_wrap
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
813 if len(unknown_types
) > 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
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"),
856 primary_classes
= ["virDomain", "virNetwork", "virInterface",
857 "virStoragePool", "virStorageVol",
858 "virConnect", "virNodeDevice", "virSecret",
859 "virNWFilter", "virStream", "virDomainSnapshot"]
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
= {
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"] = []
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"
938 if name
[0:l
] == listname
:
940 func
= string
.lower(func
[0:1]) + func
[1:]
941 elif name
[0:16] == "virNetworkDefine":
943 func
= string
.lower(func
[0:1]) + func
[1:]
944 elif name
[0:19] == "virNetworkCreateXML":
946 func
= string
.lower(func
[0:1]) + func
[1:]
947 elif name
[0:16] == "virNetworkLookup":
949 func
= string
.lower(func
[0:1]) + func
[1:]
950 elif name
[0:18] == "virInterfaceDefine":
952 func
= string
.lower(func
[0:1]) + func
[1:]
953 elif name
[0:21] == "virInterfaceCreateXML":
955 func
= string
.lower(func
[0:1]) + func
[1:]
956 elif name
[0:18] == "virInterfaceLookup":
958 func
= string
.lower(func
[0:1]) + func
[1:]
959 elif name
[0:15] == "virSecretDefine":
961 func
= string
.lower(func
[0:1]) + func
[1:]
962 elif name
[0:15] == "virSecretLookup":
964 func
= string
.lower(func
[0:1]) + func
[1:]
965 elif name
[0:17] == "virNWFilterDefine":
967 func
= string
.lower(func
[0:3]) + func
[3:]
968 elif name
[0:17] == "virNWFilterLookup":
970 func
= string
.lower(func
[0:3]) + func
[3:]
971 elif name
[0:20] == "virStoragePoolDefine":
973 func
= string
.lower(func
[0:1]) + func
[1:]
974 elif name
[0:23] == "virStoragePoolCreateXML":
976 func
= string
.lower(func
[0:1]) + func
[1:]
977 elif name
[0:20] == "virStoragePoolLookup":
979 func
= string
.lower(func
[0:1]) + func
[1:]
980 elif name
[0:19] == "virStorageVolDefine":
982 func
= string
.lower(func
[0:1]) + func
[1:]
983 elif name
[0:19] == "virStorageVolLookup":
985 func
= string
.lower(func
[0:1]) + func
[1:]
986 elif name
[0:20] == "virDomainGetCPUStats":
988 func
= string
.lower(func
[0:1]) + func
[1:]
989 elif name
[0:12] == "virDomainGet":
991 func
= string
.lower(func
[0:1]) + func
[1:]
992 elif name
[0:29] == "virDomainSnapshotLookupByName":
994 func
= string
.lower(func
[0:1]) + func
[1:]
995 elif name
[0:26] == "virDomainSnapshotListNames":
997 func
= string
.lower(func
[0:1]) + func
[1:]
998 elif name
[0:28] == "virDomainSnapshotNumChildren":
1000 func
= string
.lower(func
[0:1]) + func
[1:]
1001 elif name
[0:20] == "virDomainSnapshotNum":
1003 func
= string
.lower(func
[0:1]) + func
[1:]
1004 elif name
[0:26] == "virDomainSnapshotCreateXML":
1006 func
= string
.lower(func
[0:1]) + func
[1:]
1007 elif name
[0:24] == "virDomainSnapshotCurrent":
1009 func
= string
.lower(func
[0:1]) + func
[1:]
1010 elif name
[0:17] == "virDomainSnapshot":
1012 func
= string
.lower(func
[0:1]) + func
[1:]
1013 elif name
[0:9] == "virDomain":
1015 func
= string
.lower(func
[0:1]) + func
[1:]
1016 elif name
[0:13] == "virNetworkGet":
1018 func
= string
.lower(func
[0:1]) + func
[1:]
1019 elif name
[0:10] == "virNetwork":
1021 func
= string
.lower(func
[0:1]) + func
[1:]
1022 elif name
[0:15] == "virInterfaceGet":
1024 func
= string
.lower(func
[0:1]) + func
[1:]
1025 elif name
[0:12] == "virInterface":
1027 func
= string
.lower(func
[0:1]) + func
[1:]
1028 elif name
[0:12] == 'virSecretGet':
1030 func
= string
.lower(func
[0:1]) + func
[1:]
1031 elif name
[0:9] == 'virSecret':
1033 func
= string
.lower(func
[0:1]) + func
[1:]
1034 elif name
[0:14] == 'virNWFilterGet':
1036 func
= string
.lower(func
[0:1]) + func
[1:]
1037 elif name
[0:11] == 'virNWFilter':
1039 func
= string
.lower(func
[0:1]) + func
[1:]
1040 elif name
[0:12] == 'virStreamNew':
1042 elif name
[0:9] == 'virStream':
1044 func
= string
.lower(func
[0:1]) + func
[1:]
1045 elif name
[0:17] == "virStoragePoolGet":
1047 func
= string
.lower(func
[0:1]) + func
[1:]
1048 elif name
[0:14] == "virStoragePool":
1050 func
= string
.lower(func
[0:1]) + func
[1:]
1051 elif name
[0:16] == "virStorageVolGet":
1053 func
= string
.lower(func
[0:1]) + func
[1:]
1054 elif name
[0:13] == "virStorageVol":
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:]
1063 func
= string
.lower(name
[13]) + name
[14:]
1064 elif name
[0:7] == "virNode":
1066 func
= string
.lower(func
[0:1]) + func
[1:]
1067 elif name
[0:10] == "virConnect":
1069 func
= string
.lower(func
[0:1]) + func
[1:]
1070 elif name
[0:3] == "xml":
1072 func
= string
.lower(func
[0:1]) + func
[1:]
1079 if func
== "uUIDString":
1081 if func
== "oSType":
1083 if func
== "xMLDesc":
1085 if func
== "mACString":
1091 def functionCompare(info1
, info2
):
1092 (index1
, func1
, name1
, ret1
, args1
, file1
, mod1
) = info1
1093 (index2
, func2
, name2
, ret2
, args2
, file2
, mod2
) = info2
1099 if file1
== "python_accessor":
1101 if file2
== "python_accessor":
1109 def writeDoc(module
, name
, args
, indent
, output
):
1110 if module
== "libvirt":
1112 elif module
== "libvirt-qemu":
1113 funcs
= qemu_functions
1114 if funcs
[name
][0] is None or funcs
[name
][0] == "":
1116 val
= funcs
[name
][0]
1117 val
= string
.replace(val
, "NULL", "None");
1118 output
.write(indent
)
1120 i
= string
.find(val
, "\n")
1125 i
= string
.find(val
, "\n")
1126 output
.write(indent
)
1128 output
.write(' """\n')
1130 def buildWrappers(module
):
1133 global py_return_types
1134 global unknown_types
1136 global function_classes
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
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
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
:
1170 ctypes_processed
[type] = ()
1171 for type in classes_type
.keys():
1172 if ctypes_processed
.has_key(type):
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]] = ()
1180 ctypes_processed
[type] = ()
1182 for name
in functions
.keys():
1184 (desc
, ret
, args
, file, mod
, cond
) = functions
[name
]
1186 classe
= classes_type
[type][2]
1188 if name
[0:3] == "vir" and len(args
) >= 1 and args
[0][1] == type:
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
:
1196 func
= nameFixup(name
, classe
, type, file)
1197 info
= (1, func
, name
, ret
, args
, file, mod
)
1198 function_classes
[classe
].append(info
)
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
)
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")
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")
1236 if function_classes
.has_key("None"):
1237 flist
= function_classes
["None"]
1238 flist
.sort(functionCompare
)
1241 (index
, func
, name
, ret
, args
, file, mod
) = info
1243 classes
.write("#\n# Functions from module %s\n#\n\n" % file)
1245 classes
.write("def %s(" % func
)
1250 classes
.write("%s" % arg
[0])
1252 classes
.write("):\n")
1253 writeDoc(module
, name
, args
, ' ', classes
);
1256 if classes_type
.has_key(arg
[1]):
1257 classes
.write(" if %s is None: %s__o = None\n" %
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 = ");
1265 classes
.write("libvirtmod.%s(" % name
)
1269 classes
.write(", ");
1270 classes
.write("%s" % arg
[0])
1271 if classes_type
.has_key(arg
[1]):
1272 classes
.write("__o");
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");
1285 " if ret is None:raise libvirtError('%s() failed')\n" %
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
]
1300 test
= functions_int_default_test
1301 classes
.write ((" if " + test
+
1302 ": raise libvirtError ('%s() failed')\n") %
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
]
1311 test
= functions_list_default_test
1312 classes
.write ((" if " + test
+
1313 ": raise libvirtError ('%s() failed')\n") %
1315 classes
.write(" return ret\n")
1318 classes
.write(" return ret\n")
1320 classes
.write("\n");
1322 for classname
in classes_list
:
1323 if classname
== "None":
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
]
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
]))
1338 classes
.write("class %s:\n" % (classname
))
1339 if classname
in [ "virDomain", "virNetwork", "virInterface", "virStoragePool",
1340 "virStorageVol", "virNodeDevice", "virSecret","virStream",
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")
1346 classes
.write(" def __init__(self, _obj=None):\n")
1347 if reference_keepers
.has_key(classname
):
1348 list = reference_keepers
[classname
]
1350 classes
.write(" self.%s = None\n" % ref
[1])
1351 if classname
in [ "virDomain", "virNetwork", "virInterface",
1352 "virNodeDevice", "virSecret", "virStream",
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");
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
)
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
:
1393 if file == "python_accessor":
1394 classes
.write(" # accessors for %s\n" % (classname
))
1396 classes
.write(" #\n")
1397 classes
.write(" # %s functions from module %s\n" % (
1399 classes
.write(" #\n\n")
1401 classes
.write(" def %s(self" % func
)
1405 classes
.write(", %s" % arg
[0])
1407 classes
.write("):\n")
1408 writeDoc(module
, name
, args
, ' ', classes
);
1411 if classes_type
.has_key(arg
[1]):
1413 classes
.write(" if %s is None: %s__o = None\n" %
1415 classes
.write(" else: %s__o = %s%s\n" %
1416 (arg
[0], arg
[0], classes_type
[arg
[1]][0]))
1418 if ret
[0] != "void":
1419 classes
.write(" ret = ");
1423 classes
.write("libvirtmod.%s(" % name
)
1426 classes
.write(", ");
1428 classes
.write("%s" % arg
[0])
1429 if classes_type
.has_key(arg
[1]):
1430 classes
.write("__o");
1432 classes
.write("self");
1433 if classes_type
.has_key(arg
[1]):
1434 classes
.write(classes_type
[arg
[1]][0])
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
):
1449 " if ret is None:return None\n");
1451 if classname
== "virConnect":
1453 " if ret is None:raise libvirtError('%s() failed', conn=self)\n" %
1455 elif classname
== "virDomain":
1457 " if ret is None:raise libvirtError('%s() failed', dom=self)\n" %
1459 elif classname
== "virNetwork":
1461 " if ret is None:raise libvirtError('%s() failed', net=self)\n" %
1463 elif classname
== "virInterface":
1465 " if ret is None:raise libvirtError('%s() failed', net=self)\n" %
1467 elif classname
== "virStoragePool":
1469 " if ret is None:raise libvirtError('%s() failed', pool=self)\n" %
1471 elif classname
== "virStorageVol":
1473 " if ret is None:raise libvirtError('%s() failed', vol=self)\n" %
1475 elif classname
== "virDomainSnapshot":
1477 " if ret is None:raise libvirtError('%s() failed', dom=self._dom)\n" %
1481 " if ret is None:raise libvirtError('%s() failed')\n" %
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
]
1500 if pref
[0] == classname
:
1501 classes
.write(" __tmp.%s = self\n" %
1504 # Post-processing - just before we return.
1505 if function_post
.has_key(name
):
1506 classes
.write(" %s\n" %
1507 (function_post
[name
]));
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
):
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
]
1538 test
= functions_int_default_test
1539 if classname
== "virConnect":
1540 classes
.write ((" if " + test
+
1541 ": raise libvirtError ('%s() failed', conn=self)\n") %
1543 elif classname
== "virDomain":
1544 classes
.write ((" if " + test
+
1545 ": raise libvirtError ('%s() failed', dom=self)\n") %
1547 elif classname
== "virNetwork":
1548 classes
.write ((" if " + test
+
1549 ": raise libvirtError ('%s() failed', net=self)\n") %
1551 elif classname
== "virInterface":
1552 classes
.write ((" if " + test
+
1553 ": raise libvirtError ('%s() failed', net=self)\n") %
1555 elif classname
== "virStoragePool":
1556 classes
.write ((" if " + test
+
1557 ": raise libvirtError ('%s() failed', pool=self)\n") %
1559 elif classname
== "virStorageVol":
1560 classes
.write ((" if " + test
+
1561 ": raise libvirtError ('%s() failed', vol=self)\n") %
1564 classes
.write ((" if " + test
+
1565 ": raise libvirtError ('%s() failed')\n") %
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
]
1580 test
= functions_list_default_test
1581 if classname
== "virConnect":
1582 classes
.write ((" if " + test
+
1583 ": raise libvirtError ('%s() failed', conn=self)\n") %
1585 elif classname
== "virDomain":
1586 classes
.write ((" if " + test
+
1587 ": raise libvirtError ('%s() failed', dom=self)\n") %
1589 elif classname
== "virNetwork":
1590 classes
.write ((" if " + test
+
1591 ": raise libvirtError ('%s() failed', net=self)\n") %
1593 elif classname
== "virInterface":
1594 classes
.write ((" if " + test
+
1595 ": raise libvirtError ('%s() failed', net=self)\n") %
1597 elif classname
== "virStoragePool":
1598 classes
.write ((" if " + test
+
1599 ": raise libvirtError ('%s() failed', pool=self)\n") %
1601 elif classname
== "virStorageVol":
1602 classes
.write ((" if " + test
+
1603 ": raise libvirtError ('%s() failed', vol=self)\n") %
1606 classes
.write ((" if " + test
+
1607 ": raise libvirtError ('%s() failed')\n") %
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")
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
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())
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");
1651 def qemuBuildWrappers(module
):
1652 global qemu_functions
1654 if not module
== "libvirt-qemu":
1655 print "ERROR: only libvirt-qemu is supported"
1658 extra_file
= os
.path
.join(srcPref
, "%s-override.py" % module
)
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")
1667 fd
.write("# WARNING WARNING WARNING WARNING\n")
1669 fd
.write("# This file is automatically written by generator.py. Any changes\n")
1670 fd
.write("# made here will be lost.\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")
1675 fd
.write("# WARNING WARNING WARNING WARNING\n")
1678 fd
.writelines(extra
.readlines())
1680 fd
.write("# WARNING WARNING WARNING WARNING\n")
1682 fd
.write("# Automatically written part of python bindings for libvirt\n")
1684 fd
.write("# WARNING WARNING WARNING WARNING\n")
1689 fd
.write(" import libvirtmod_qemu\n")
1690 fd
.write("except ImportError, lib_e:\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
)
1710 fd
.write("%s" % arg
[0])
1713 writeDoc(module
, name
, args
, ' ', fd
);
1715 if ret
[0] != "void":
1716 fd
.write(" ret = ");
1719 fd
.write("libvirtmod_qemu.%s(" % name
)
1725 if arg
[1] == "virConnectPtr":
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"))
1735 fd
.write("%s" % arg
[0])
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")
1745 fd
.write(" return ret\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
))
1764 if buildStubs("libvirt") < 0:
1766 if buildStubs("libvirt-qemu") < 0:
1768 buildWrappers("libvirt")
1769 qemuBuildWrappers("libvirt-qemu")