Release of libvirt-python-4.10.0
[libvirt-python/ericb.git] / generator.py
blob6cb923fc4cb30fb8e6687b9b171ea9301e63a0fb
1 #!/usr/bin/env python
3 # generate python wrappers from the XML API description
6 functions = {}
7 lxc_functions = {}
8 qemu_functions = {}
9 enums = {} # { enumType: { enumConstant: enumValue } }
10 lxc_enums = {} # { enumType: { enumConstant: enumValue } }
11 qemu_enums = {} # { enumType: { enumConstant: enumValue } }
12 event_ids = []
13 params = [] # [ (parameName, paramValue)... ]
15 import os
16 import sys
17 import string
18 import re
20 quiet=True
22 #######################################################################
24 # That part if purely the API acquisition phase from the
25 # libvirt API description
27 #######################################################################
28 import os
29 import xml.sax
31 debug = 0
32 onlyOverrides = False
34 libvirt_headers = [
35 "libvirt",
36 "libvirt-common",
37 "libvirt-domain",
38 "libvirt-domain-snapshot",
39 "libvirt-event",
40 "libvirt-host",
41 "libvirt-interface",
42 "libvirt-network",
43 "libvirt-nodedev",
44 "libvirt-nwfilter",
45 "libvirt-secret",
46 "libvirt-storage",
47 "libvirt-stream",
50 def getparser():
51 # Attach parser to an unmarshalling object. return both objects.
52 target = docParser()
53 parser = xml.sax.make_parser()
54 parser.setContentHandler(target)
55 return parser, target
57 class docParser(xml.sax.handler.ContentHandler):
58 def __init__(self):
59 self._methodname = None
60 self._data = []
61 self.in_function = 0
63 self.startElement = self.start
64 self.endElement = self.end
65 self.characters = self.data
67 def close(self):
68 if debug:
69 print("close")
71 def getmethodname(self):
72 return self._methodname
74 def data(self, text):
75 if debug:
76 print("data %s" % text)
77 self._data.append(text)
79 def cdata(self, text):
80 if debug:
81 print("data %s" % text)
82 self._data.append(text)
84 def start(self, tag, attrs):
85 if debug:
86 print("start %s, %s" % (tag, attrs))
87 if tag == 'function':
88 self._data = []
89 self.in_function = 1
90 self.function = None
91 self.function_cond = None
92 self.function_args = []
93 self.function_descr = None
94 self.function_return = None
95 self.function_file = None
96 self.function_module= None
97 if 'name' in attrs.keys():
98 self.function = attrs['name']
99 if 'file' in attrs.keys():
100 self.function_file = attrs['file']
101 if 'module' in attrs.keys():
102 self.function_module= attrs['module']
103 elif tag == 'cond':
104 self._data = []
105 elif tag == 'info':
106 self._data = []
107 elif tag == 'arg':
108 if self.in_function == 1:
109 self.function_arg_name = None
110 self.function_arg_type = None
111 self.function_arg_info = None
112 if 'name' in attrs.keys():
113 self.function_arg_name = attrs['name']
114 if self.function_arg_name == 'from':
115 self.function_arg_name = 'frm'
116 if 'type' in attrs.keys():
117 self.function_arg_type = attrs['type']
118 if 'info' in attrs.keys():
119 self.function_arg_info = attrs['info']
120 elif tag == 'return':
121 if self.in_function == 1:
122 self.function_return_type = None
123 self.function_return_info = None
124 self.function_return_field = None
125 if 'type' in attrs.keys():
126 self.function_return_type = attrs['type']
127 if 'info' in attrs.keys():
128 self.function_return_info = attrs['info']
129 if 'field' in attrs.keys():
130 self.function_return_field = attrs['field']
131 elif tag == 'enum':
132 # enums come from header files, hence virterror.h
133 if attrs['file'] in libvirt_headers + ["virerror", "virterror"]:
134 enum(attrs['type'],attrs['name'],attrs['value'])
135 elif attrs['file'] == "libvirt-lxc":
136 lxc_enum(attrs['type'],attrs['name'],attrs['value'])
137 elif attrs['file'] == "libvirt-qemu":
138 qemu_enum(attrs['type'],attrs['name'],attrs['value'])
139 elif tag == "macro":
140 if "string" in attrs.keys():
141 params.append((attrs['name'], attrs['string']))
143 def end(self, tag):
144 if debug:
145 print("end %s" % tag)
146 if tag == 'function':
147 # fuctions come from source files, hence 'virerror.c'
148 if self.function is not None:
149 if self.function_module in libvirt_headers + \
150 ["event", "virevent", "virerror", "virterror"]:
151 function(self.function, self.function_descr,
152 self.function_return, self.function_args,
153 self.function_file, self.function_module,
154 self.function_cond)
155 elif self.function_module == "libvirt-lxc":
156 lxc_function(self.function, self.function_descr,
157 self.function_return, self.function_args,
158 self.function_file, self.function_module,
159 self.function_cond)
160 elif self.function_module == "libvirt-qemu":
161 qemu_function(self.function, self.function_descr,
162 self.function_return, self.function_args,
163 self.function_file, self.function_module,
164 self.function_cond)
165 elif self.function_file == "python":
166 function(self.function, self.function_descr,
167 self.function_return, self.function_args,
168 self.function_file, self.function_module,
169 self.function_cond)
170 elif self.function_file == "python-lxc":
171 lxc_function(self.function, self.function_descr,
172 self.function_return, self.function_args,
173 self.function_file, self.function_module,
174 self.function_cond)
175 elif self.function_file == "python-qemu":
176 qemu_function(self.function, self.function_descr,
177 self.function_return, self.function_args,
178 self.function_file, self.function_module,
179 self.function_cond)
180 self.in_function = 0
181 elif tag == 'arg':
182 if self.in_function == 1:
183 self.function_args.append([self.function_arg_name,
184 self.function_arg_type,
185 self.function_arg_info])
186 elif tag == 'return':
187 if self.in_function == 1:
188 self.function_return = [self.function_return_type,
189 self.function_return_info,
190 self.function_return_field]
191 elif tag == 'info':
192 str = ''
193 for c in self._data:
194 str = str + c
195 if self.in_function == 1:
196 self.function_descr = str
197 elif tag == 'cond':
198 str = ''
199 for c in self._data:
200 str = str + c
201 if self.in_function == 1:
202 self.function_cond = str
205 def function(name, desc, ret, args, file, module, cond):
206 global onlyOverrides
207 if onlyOverrides and name not in functions:
208 return
209 if name == "virConnectListDomains":
210 name = "virConnectListDomainsID"
211 functions[name] = (desc, ret, args, file, module, cond)
213 def qemu_function(name, desc, ret, args, file, module, cond):
214 global onlyOverrides
215 if onlyOverrides and name not in qemu_functions:
216 return
217 qemu_functions[name] = (desc, ret, args, file, module, cond)
219 def lxc_function(name, desc, ret, args, file, module, cond):
220 global onlyOverrides
221 if onlyOverrides and name not in lxc_functions:
222 return
223 lxc_functions[name] = (desc, ret, args, file, module, cond)
225 def enum(type, name, value):
226 if type not in enums:
227 enums[type] = {}
228 if (name.startswith('VIR_DOMAIN_EVENT_ID_') or
229 name.startswith('VIR_NETWORK_EVENT_ID_')):
230 event_ids.append(name)
231 if value == 'VIR_TYPED_PARAM_INT':
232 value = 1
233 elif value == 'VIR_TYPED_PARAM_UINT':
234 value = 2
235 elif value == 'VIR_TYPED_PARAM_LLONG':
236 value = 3
237 elif value == 'VIR_TYPED_PARAM_ULLONG':
238 value = 4
239 elif value == 'VIR_TYPED_PARAM_DOUBLE':
240 value = 5
241 elif value == 'VIR_TYPED_PARAM_BOOLEAN':
242 value = 6
243 elif value == 'VIR_DOMAIN_AFFECT_CURRENT':
244 value = 0
245 elif value == 'VIR_DOMAIN_AFFECT_LIVE':
246 value = 1
247 elif value == 'VIR_DOMAIN_AFFECT_CONFIG':
248 value = 2
249 if onlyOverrides and name not in enums[type]:
250 return
251 enums[type][name] = value
253 def lxc_enum(type, name, value):
254 if type not in lxc_enums:
255 lxc_enums[type] = {}
256 if onlyOverrides and name not in lxc_enums[type]:
257 return
258 lxc_enums[type][name] = value
260 def qemu_enum(type, name, value):
261 if type not in qemu_enums:
262 qemu_enums[type] = {}
263 if onlyOverrides and name not in qemu_enums[type]:
264 return
265 qemu_enums[type][name] = value
268 #######################################################################
270 # Some filtering rukes to drop functions/types which should not
271 # be exposed as-is on the Python interface
273 #######################################################################
275 functions_failed = []
276 lxc_functions_failed = []
277 qemu_functions_failed = []
278 functions_skipped = [
279 "virConnectListDomains",
281 lxc_functions_skipped = []
282 qemu_functions_skipped = []
284 skipped_modules = {
287 skipped_types = {
288 # 'int *': "usually a return type",
289 'virConnectDomainEventCallback': "No function types in python",
290 'virConnectDomainEventGenericCallback': "No function types in python",
291 'virConnectDomainEventRTCChangeCallback': "No function types in python",
292 'virConnectDomainEventWatchdogCallback': "No function types in python",
293 'virConnectDomainEventIOErrorCallback': "No function types in python",
294 'virConnectDomainEventGraphicsCallback': "No function types in python",
295 'virConnectDomainQemuMonitorEventCallback': "No function types in python",
296 'virStreamEventCallback': "No function types in python",
297 'virEventHandleCallback': "No function types in python",
298 'virEventTimeoutCallback': "No function types in python",
299 'virDomainBlockJobInfoPtr': "Not implemented yet",
302 #######################################################################
304 # Table of remapping to/from the python type or class to the C
305 # counterpart.
307 #######################################################################
309 py_types = {
310 'void': (None, None, None, None),
311 'int': ('i', None, "int", "int"),
312 'long': ('l', None, "long", "long"),
313 'double': ('d', None, "double", "double"),
314 'unsigned int': ('I', None, "int", "int"),
315 'unsigned long': ('l', None, "long", "long"),
316 'long long': ('L', None, "longlong", "long long"),
317 'unsigned long long': ('L', None, "longlong", "long long"),
318 'unsigned char *': ('z', None, "charPtr", "char *"),
319 'char *': ('z', None, "charPtr", "char *"),
320 'const char *': ('z', None, "constcharPtr", "const char *"),
321 'size_t': ('n', None, "size_t", "size_t"),
323 'virDomainPtr': ('O', "virDomain", "virDomainPtr", "virDomainPtr"),
324 'virDomain *': ('O', "virDomain", "virDomainPtr", "virDomainPtr"),
325 'const virDomain *': ('O', "virDomain", "virDomainPtr", "virDomainPtr"),
327 'virNetworkPtr': ('O', "virNetwork", "virNetworkPtr", "virNetworkPtr"),
328 'virNetwork *': ('O', "virNetwork", "virNetworkPtr", "virNetworkPtr"),
329 'const virNetwork *': ('O', "virNetwork", "virNetworkPtr", "virNetworkPtr"),
331 'virInterfacePtr': ('O', "virInterface", "virInterfacePtr", "virInterfacePtr"),
332 'virInterface *': ('O', "virInterface", "virInterfacePtr", "virInterfacePtr"),
333 'const virInterface *': ('O', "virInterface", "virInterfacePtr", "virInterfacePtr"),
335 'virStoragePoolPtr': ('O', "virStoragePool", "virStoragePoolPtr", "virStoragePoolPtr"),
336 'virStoragePool *': ('O', "virStoragePool", "virStoragePoolPtr", "virStoragePoolPtr"),
337 'const virStoragePool *': ('O', "virStoragePool", "virStoragePoolPtr", "virStoragePoolPtr"),
339 'virStorageVolPtr': ('O', "virStorageVol", "virStorageVolPtr", "virStorageVolPtr"),
340 'virStorageVol *': ('O', "virStorageVol", "virStorageVolPtr", "virStorageVolPtr"),
341 'const virStorageVol *': ('O', "virStorageVol", "virStorageVolPtr", "virStorageVolPtr"),
343 'virConnectPtr': ('O', "virConnect", "virConnectPtr", "virConnectPtr"),
344 'virConnect *': ('O', "virConnect", "virConnectPtr", "virConnectPtr"),
345 'const virConnect *': ('O', "virConnect", "virConnectPtr", "virConnectPtr"),
347 'virNodeDevicePtr': ('O', "virNodeDevice", "virNodeDevicePtr", "virNodeDevicePtr"),
348 'virNodeDevice *': ('O', "virNodeDevice", "virNodeDevicePtr", "virNodeDevicePtr"),
349 'const virNodeDevice *': ('O', "virNodeDevice", "virNodeDevicePtr", "virNodeDevicePtr"),
351 'virSecretPtr': ('O', "virSecret", "virSecretPtr", "virSecretPtr"),
352 'virSecret *': ('O', "virSecret", "virSecretPtr", "virSecretPtr"),
353 'const virSecret *': ('O', "virSecret", "virSecretPtr", "virSecretPtr"),
355 'virNWFilterPtr': ('O', "virNWFilter", "virNWFilterPtr", "virNWFilterPtr"),
356 'virNWFilter *': ('O', "virNWFilter", "virNWFilterPtr", "virNWFilterPtr"),
357 'const virNWFilter *': ('O', "virNWFilter", "virNWFilterPtr", "virNWFilterPtr"),
359 'virNWFilterBindingPtr': ('O', "virNWFilterBinding", "virNWFilterBindingPtr", "virNWFilterBindingPtr"),
360 'virNWFilterBinding *': ('O', "virNWFilterBinding", "virNWFilterBindingPtr", "virNWFilterBindingPtr"),
361 'const virNWFilterBinding *': ('O', "virNWFilterBinding", "virNWFilterBindingPtr", "virNWFilterBindingPtr"),
363 'virStreamPtr': ('O', "virStream", "virStreamPtr", "virStreamPtr"),
364 'virStream *': ('O', "virStream", "virStreamPtr", "virStreamPtr"),
365 'const virStream *': ('O', "virStream", "virStreamPtr", "virStreamPtr"),
367 'virDomainSnapshotPtr': ('O', "virDomainSnapshot", "virDomainSnapshotPtr", "virDomainSnapshotPtr"),
368 'virDomainSnapshot *': ('O', "virDomainSnapshot", "virDomainSnapshotPtr", "virDomainSnapshotPtr"),
369 'const virDomainSnapshot *': ('O', "virDomainSnapshot", "virDomainSnapshotPtr", "virDomainSnapshotPtr"),
372 unknown_types = {}
374 #######################################################################
376 # This part writes the C <-> Python stubs libvirt.[ch] and
377 # the table libvirt-export.c to add when registrering the Python module
379 #######################################################################
381 # Class methods which are written by hand in libvirt.c but the Python-level
382 # code is still automatically generated (so they are not in skip_function()).
383 skip_impl = (
384 'virConnectGetVersion',
385 'virConnectGetLibVersion',
386 'virConnectListDomainsID',
387 'virConnectListDefinedDomains',
388 'virConnectListNetworks',
389 'virConnectListDefinedNetworks',
390 'virConnectListSecrets',
391 'virConnectListInterfaces',
392 'virConnectListStoragePools',
393 'virConnectListDefinedStoragePools',
394 'virConnectListStorageVols',
395 'virConnectListDefinedStorageVols',
396 'virConnectListDefinedInterfaces',
397 'virConnectListNWFilters',
398 'virDomainSnapshotListNames',
399 'virDomainSnapshotListChildrenNames',
400 'virConnGetLastError',
401 'virGetLastError',
402 'virDomainGetInfo',
403 'virDomainGetState',
404 'virDomainGetControlInfo',
405 'virDomainGetBlockInfo',
406 'virDomainGetJobInfo',
407 'virDomainGetJobStats',
408 'virNodeGetInfo',
409 'virNodeGetSecurityModel',
410 'virDomainGetSecurityLabel',
411 'virDomainGetSecurityLabelList',
412 'virDomainGetUUID',
413 'virDomainGetUUIDString',
414 'virDomainLookupByUUID',
415 'virNetworkGetUUID',
416 'virNetworkGetUUIDString',
417 'virNetworkLookupByUUID',
418 'virDomainGetAutostart',
419 'virNetworkGetAutostart',
420 'virDomainBlockStats',
421 'virDomainInterfaceStats',
422 'virDomainMemoryStats',
423 'virNodeGetCellsFreeMemory',
424 'virDomainGetSchedulerType',
425 'virDomainGetSchedulerParameters',
426 'virDomainGetSchedulerParametersFlags',
427 'virDomainSetSchedulerParameters',
428 'virDomainSetSchedulerParametersFlags',
429 'virDomainSetBlkioParameters',
430 'virDomainGetBlkioParameters',
431 'virDomainSetMemoryParameters',
432 'virDomainGetMemoryParameters',
433 'virDomainSetNumaParameters',
434 'virDomainGetNumaParameters',
435 'virDomainGetVcpus',
436 'virDomainPinVcpu',
437 'virDomainPinVcpuFlags',
438 'virDomainGetVcpuPinInfo',
439 'virDomainGetEmulatorPinInfo',
440 'virDomainPinEmulator',
441 'virDomainGetIOThreadInfo',
442 'virDomainPinIOThread',
443 'virDomainSetIOThreadParams',
444 'virSecretGetValue',
445 'virSecretSetValue',
446 'virSecretGetUUID',
447 'virSecretGetUUIDString',
448 'virSecretLookupByUUID',
449 'virNWFilterGetUUID',
450 'virNWFilterGetUUIDString',
451 'virNWFilterLookupByUUID',
452 'virStoragePoolGetUUID',
453 'virStoragePoolGetUUIDString',
454 'virStoragePoolLookupByUUID',
455 'virStoragePoolGetInfo',
456 'virStorageVolGetInfo',
457 'virStorageVolGetInfoFlags',
458 'virStoragePoolGetAutostart',
459 'virStoragePoolListVolumes',
460 'virDomainBlockPeek',
461 'virDomainMemoryPeek',
462 'virEventRegisterImpl',
463 'virNodeListDevices',
464 'virNodeDeviceListCaps',
465 'virConnectBaselineCPU',
466 'virDomainRevertToSnapshot',
467 'virDomainSendKey',
468 'virNodeGetCPUStats',
469 'virNodeGetMemoryStats',
470 'virDomainGetBlockJobInfo',
471 'virDomainMigrateGetCompressionCache',
472 'virDomainMigrateGetMaxSpeed',
473 'virDomainMigrateGetMaxDowntime',
474 'virDomainBlockStatsFlags',
475 'virDomainSetBlockIoTune',
476 'virDomainGetBlockIoTune',
477 'virDomainSetInterfaceParameters',
478 'virDomainGetInterfaceParameters',
479 'virDomainGetCPUStats',
480 'virDomainGetDiskErrors',
481 'virNodeGetMemoryParameters',
482 'virNodeSetMemoryParameters',
483 'virNodeGetCPUMap',
484 'virDomainMigrate3',
485 'virDomainMigrateToURI3',
486 'virConnectGetCPUModelNames',
487 'virNodeGetFreePages',
488 'virNetworkGetDHCPLeases',
489 'virDomainBlockCopy',
490 'virNodeAllocPages',
491 'virDomainGetFSInfo',
492 'virDomainInterfaceAddresses',
493 'virDomainGetPerfEvents',
494 'virDomainSetPerfEvents',
495 'virDomainGetGuestVcpus',
496 'virConnectBaselineHypervisorCPU',
497 'virDomainGetLaunchSecurityInfo',
498 'virNodeGetSEVInfo',
501 lxc_skip_impl = (
502 'virDomainLxcOpenNamespace',
505 qemu_skip_impl = (
506 'virDomainQemuMonitorCommand',
507 'virDomainQemuAgentCommand',
511 # These are functions which the generator skips completly - no python
512 # or C code is generated. Generally should not be used for any more
513 # functions than those already listed
514 skip_function = (
515 'virConnectListDomains', # Python API is called virConectListDomainsID for unknown reasons
516 'virConnSetErrorFunc', # Not used in Python API XXX is this a bug ?
517 'virResetError', # Not used in Python API XXX is this a bug ?
518 'virGetVersion', # Python C code is manually written
519 'virSetErrorFunc', # Python API is called virRegisterErrorHandler for unknown reasons
520 'virConnCopyLastError', # Python API is called virConnGetLastError instead
521 'virCopyLastError', # Python API is called virGetLastError instead
522 'virConnectOpenAuth', # Python C code is manually written
523 'virDefaultErrorFunc', # Python virErrorFuncHandler impl calls this from C
524 'virConnectDomainEventRegister', # overridden in virConnect.py
525 'virConnectDomainEventDeregister', # overridden in virConnect.py
526 'virConnectDomainEventRegisterAny', # overridden in virConnect.py
527 'virConnectDomainEventDeregisterAny', # overridden in virConnect.py
528 'virConnectNetworkEventRegisterAny', # overridden in virConnect.py
529 'virConnectNetworkEventDeregisterAny', # overridden in virConnect.py
530 'virConnectStoragePoolEventRegisterAny', # overridden in virConnect.py
531 'virConnectStoragePoolEventDeregisterAny', # overridden in virConnect.py
532 'virConnectNodeDeviceEventRegisterAny', # overridden in virConnect.py
533 'virConnectNodeDeviceEventDeregisterAny', # overridden in virConnect.py
534 'virConnectSecretEventRegisterAny', # overridden in virConnect.py
535 'virConnectSecretEventDeregisterAny', # overridden in virConnect.py
536 'virSaveLastError', # We have our own python error wrapper
537 'virFreeError', # Only needed if we use virSaveLastError
538 'virConnectListAllDomains', # overridden in virConnect.py
539 'virDomainListAllSnapshots', # overridden in virDomain.py
540 'virDomainSnapshotListAllChildren', # overridden in virDomainSnapshot.py
541 'virConnectListAllStoragePools', # overridden in virConnect.py
542 'virStoragePoolListAllVolumes', # overridden in virStoragePool.py
543 'virConnectListAllNetworks', # overridden in virConnect.py
544 'virConnectListAllInterfaces', # overridden in virConnect.py
545 'virConnectListAllNodeDevices', # overridden in virConnect.py
546 'virConnectListAllNWFilters', # overridden in virConnect.py
547 'virConnectListAllNWFilterBindings', # overridden in virConnect.py
548 'virConnectListAllSecrets', # overridden in virConnect.py
549 'virConnectGetAllDomainStats', # overridden in virConnect.py
550 'virDomainListGetStats', # overriden in virConnect.py
552 'virStreamRecvAll', # Pure python libvirt-override-virStream.py
553 'virStreamSendAll', # Pure python libvirt-override-virStream.py
554 'virStreamRecv', # overridden in libvirt-override-virStream.py
555 'virStreamSend', # overridden in libvirt-override-virStream.py
556 'virStreamRecvHole', # overridden in libvirt-override-virStream.py
557 'virStreamSendHole', # overridden in libvirt-override-virStream.py
558 'virStreamRecvFlags', # overridden in libvirt-override-virStream.py
559 'virStreamSparseRecvAll', # overridden in libvirt-override-virStream.py
560 'virStreamSparseSendAll', # overridden in libvirt-override-virStream.py
562 'virConnectUnregisterCloseCallback', # overridden in virConnect.py
563 'virConnectRegisterCloseCallback', # overridden in virConnect.py
565 'virDomainCreateXMLWithFiles', # overridden in virConnect.py
566 'virDomainCreateWithFiles', # overridden in virDomain.py
568 'virDomainFSFreeze', # overridden in virDomain.py
569 'virDomainFSThaw', # overridden in virDomain.py
570 'virDomainGetTime', # overridden in virDomain.py
571 'virDomainSetTime', # overridden in virDomain.py
573 # 'Ref' functions have no use for bindings users.
574 "virConnectRef",
575 "virDomainRef",
576 "virInterfaceRef",
577 "virNetworkRef",
578 "virNodeDeviceRef",
579 "virSecretRef",
580 "virNWFilterRef",
581 "virNWFilterBindingRef",
582 "virStoragePoolRef",
583 "virStorageVolRef",
584 "virStreamRef",
585 "virDomainSnapshotRef",
587 # This functions shouldn't be called via the bindings (and even the docs
588 # contain an explicit warning to that effect). The equivalent should be
589 # implemented in pure python for each class
590 "virDomainGetConnect",
591 "virInterfaceGetConnect",
592 "virNetworkGetConnect",
593 "virSecretGetConnect",
594 "virNWFilterGetConnect",
595 "virStoragePoolGetConnect",
596 "virStorageVolGetConnect",
597 "virDomainSnapshotGetConnect",
598 "virDomainSnapshotGetDomain",
600 # only useful in C code, python code uses dict for typed parameters
601 "virTypedParamsAddBoolean",
602 "virTypedParamsAddDouble",
603 "virTypedParamsAddFromString",
604 "virTypedParamsAddInt",
605 "virTypedParamsAddLLong",
606 "virTypedParamsAddString",
607 "virTypedParamsAddUInt",
608 "virTypedParamsAddULLong",
609 "virTypedParamsClear",
610 "virTypedParamsFree",
611 "virTypedParamsGet",
612 "virTypedParamsGetBoolean",
613 "virTypedParamsGetDouble",
614 "virTypedParamsGetInt",
615 "virTypedParamsGetLLong",
616 "virTypedParamsGetString",
617 "virTypedParamsGetUInt",
618 "virTypedParamsGetULLong",
620 'virNetworkDHCPLeaseFree', # only useful in C, python code uses list
621 'virDomainStatsRecordListFree', # only useful in C, python uses dict
622 'virDomainFSInfoFree', # only useful in C, python code uses list
623 'virDomainIOThreadInfoFree', # only useful in C, python code uses list
624 'virDomainInterfaceFree', # only useful in C, python code uses list
627 lxc_skip_function = (
628 "virDomainLxcEnterNamespace",
629 "virDomainLxcEnterSecurityLabel",
631 qemu_skip_function = (
632 #"virDomainQemuAttach",
633 'virConnectDomainQemuMonitorEventRegister', # overridden in -qemu.py
634 'virConnectDomainQemuMonitorEventDeregister', # overridden in -qemu.py
637 # Generate C code, but skip python impl
638 function_skip_python_impl = (
639 "virStreamFree", # Needed in custom virStream __del__, but free shouldn't
640 # be exposed in bindings
643 lxc_function_skip_python_impl = ()
644 qemu_function_skip_python_impl = ()
646 function_skip_index_one = (
647 "virDomainRevertToSnapshot",
650 def print_function_wrapper(module, name, output, export, include):
651 global py_types
652 global unknown_types
653 global functions
654 global lxc_functions
655 global qemu_functions
656 global skipped_modules
657 global function_skip_python_impl
659 try:
660 if module == "libvirt":
661 (desc, ret, args, file, mod, cond) = functions[name]
662 if module == "libvirt-lxc":
663 (desc, ret, args, file, mod, cond) = lxc_functions[name]
664 if module == "libvirt-qemu":
665 (desc, ret, args, file, mod, cond) = qemu_functions[name]
666 except:
667 print("failed to get function %s infos" % name)
668 return
670 if module in skipped_modules:
671 return 0
673 if module == "libvirt":
674 if name in skip_function:
675 return 0
676 if name in skip_impl:
677 # Don't delete the function entry in the caller.
678 return 1
679 elif module == "libvirt-lxc":
680 if name in lxc_skip_function:
681 return 0
682 if name in lxc_skip_impl:
683 # Don't delete the function entry in the caller.
684 return 1
685 elif module == "libvirt-qemu":
686 if name in qemu_skip_function:
687 return 0
688 if name in qemu_skip_impl:
689 # Don't delete the function entry in the caller.
690 return 1
692 c_call = ""
693 format=""
694 format_args=""
695 c_args=""
696 c_return=""
697 c_convert=""
698 num_bufs=0
699 for arg in args:
700 # This should be correct
701 if arg[1][0:6] == "const ":
702 arg[1] = arg[1][6:]
703 c_args = c_args + " %s %s;\n" % (arg[1], arg[0])
704 if arg[1] in py_types:
705 (f, t, n, c) = py_types[arg[1]]
706 if f is not None:
707 format = format + f
708 if t is not None:
709 format_args = format_args + ", &pyobj_%s" % (arg[0])
710 c_args = c_args + " PyObject *pyobj_%s;\n" % (arg[0])
711 c_convert = c_convert + \
712 " %s = (%s) Py%s_Get(pyobj_%s);\n" % (arg[0],
713 arg[1], t, arg[0])
714 else:
715 format_args = format_args + ", &%s" % (arg[0])
716 if f == 't#':
717 format_args = format_args + ", &py_buffsize%d" % num_bufs
718 c_args = c_args + " int py_buffsize%d;\n" % num_bufs
719 num_bufs = num_bufs + 1
720 if c_call != "":
721 c_call = c_call + ", "
722 c_call = c_call + "%s" % (arg[0])
723 else:
724 if arg[1] in skipped_types:
725 return 0
726 if arg[1] in unknown_types:
727 lst = unknown_types[arg[1]]
728 lst.append(name)
729 else:
730 unknown_types[arg[1]] = [name]
731 return -1
732 if format != "":
733 format = format + ":%s" % (name)
735 if ret[0] == 'void':
736 if file == "python_accessor":
737 if args[1][1] == "char *":
738 c_call = "\n VIR_FREE(%s->%s);\n" % (
739 args[0][0], args[1][0], args[0][0], args[1][0])
740 c_call = c_call + " %s->%s = (%s)strdup((const xmlChar *)%s);\n" % (args[0][0],
741 args[1][0], args[1][1], args[1][0])
742 else:
743 c_call = "\n %s->%s = %s;\n" % (args[0][0], args[1][0],
744 args[1][0])
745 else:
746 c_call = "\n %s(%s);\n" % (name, c_call)
747 ret_convert = " Py_INCREF(Py_None);\n return Py_None;\n"
748 elif ret[0] in py_types:
749 (f, t, n, c) = py_types[ret[0]]
750 c_return = " %s c_retval;\n" % (ret[0])
751 if file == "python_accessor" and ret[2] is not None:
752 c_call = "\n c_retval = %s->%s;\n" % (args[0][0], ret[2])
753 else:
754 c_call = "\n c_retval = %s(%s);\n" % (name, c_call)
755 ret_convert = " py_retval = libvirt_%sWrap((%s) c_retval);\n" % (n,c)
756 if n == "charPtr":
757 ret_convert = ret_convert + " free(c_retval);\n"
758 ret_convert = ret_convert + " return py_retval;\n"
759 else:
760 if ret[0] in skipped_types:
761 return 0
762 if ret[0] in unknown_types:
763 lst = unknown_types[ret[0]]
764 lst.append(name)
765 else:
766 unknown_types[ret[0]] = [name]
767 return -1
769 if cond is not None and cond != "":
770 include.write("#if %s\n" % cond)
771 export.write("#if %s\n" % cond)
772 output.write("#if %s\n" % cond)
774 include.write("PyObject * ")
775 if module == "libvirt":
776 include.write("libvirt_%s(PyObject *self, PyObject *args);\n" % (name))
777 export.write(" { (char *)\"%s\", libvirt_%s, METH_VARARGS, NULL },\n" %
778 (name, name))
779 elif module == "libvirt-lxc":
780 include.write("libvirt_lxc_%s(PyObject *self, PyObject *args);\n" % (name))
781 export.write(" { (char *)\"%s\", libvirt_lxc_%s, METH_VARARGS, NULL },\n" %
782 (name, name))
783 elif module == "libvirt-qemu":
784 include.write("libvirt_qemu_%s(PyObject *self, PyObject *args);\n" % (name))
785 export.write(" { (char *)\"%s\", libvirt_qemu_%s, METH_VARARGS, NULL },\n" %
786 (name, name))
788 if file == "python":
789 # Those have been manually generated
790 if cond is not None and cond != "":
791 include.write("#endif\n")
792 export.write("#endif\n")
793 output.write("#endif\n")
794 return 1
795 if file == "python_accessor" and ret[0] != "void" and ret[2] is None:
796 # Those have been manually generated
797 if cond is not None and cond != "":
798 include.write("#endif\n")
799 export.write("#endif\n")
800 output.write("#endif\n")
801 return 1
803 output.write("PyObject *\n")
804 if module == "libvirt":
805 output.write("libvirt_%s(PyObject *self ATTRIBUTE_UNUSED," % (name))
806 elif module == "libvirt-lxc":
807 output.write("libvirt_lxc_%s(PyObject *self ATTRIBUTE_UNUSED," % (name))
808 elif module == "libvirt-qemu":
809 output.write("libvirt_qemu_%s(PyObject *self ATTRIBUTE_UNUSED," % (name))
810 output.write(" PyObject *args")
811 if format == "":
812 output.write(" ATTRIBUTE_UNUSED")
813 output.write(") {\n")
814 if ret[0] != 'void':
815 output.write(" PyObject *py_retval;\n")
816 if c_return != "":
817 output.write(c_return)
818 if c_args != "":
819 output.write(c_args)
820 if format != "":
821 output.write("\n if (!PyArg_ParseTuple(args, (char *)\"%s\"%s))\n" %
822 (format, format_args))
823 output.write(" return NULL;\n")
824 if c_convert != "":
825 output.write(c_convert + "\n")
827 output.write(" LIBVIRT_BEGIN_ALLOW_THREADS;")
828 output.write(c_call)
829 output.write(" LIBVIRT_END_ALLOW_THREADS;\n")
830 output.write(ret_convert)
831 output.write("}\n\n")
832 if cond is not None and cond != "":
833 include.write("#endif /* %s */\n" % cond)
834 export.write("#endif /* %s */\n" % cond)
835 output.write("#endif /* %s */\n" % cond)
837 if module == "libvirt":
838 if name in function_skip_python_impl:
839 return 0
840 elif module == "libvirt-lxc":
841 if name in lxc_function_skip_python_impl:
842 return 0
843 elif module == "libvirt-qemu":
844 if name in qemu_function_skip_python_impl:
845 return 0
846 return 1
848 def print_c_pointer(classname, output, export, include):
849 output.write("PyObject *\n")
850 output.write("libvirt_%s_pointer(PyObject *self ATTRIBUTE_UNUSED, PyObject *args)\n" % classname)
851 output.write("{\n")
852 output.write(" %sPtr ptr;\n" % classname)
853 output.write(" PyObject *pyptr;\n")
854 output.write(" PyObject *pylong;\n")
855 output.write("\n")
856 output.write(" if (!PyArg_ParseTuple(args, (char *) \"O\", &pyptr))\n")
857 output.write(" return NULL;\n")
858 output.write(" ptr = (%sPtr) Py%s_Get(pyptr);\n" % (classname, classname))
859 output.write(" pylong = PyLong_FromVoidPtr(ptr);\n")
860 output.write(" return pylong;\n")
861 output.write("}\n")
862 output.write("\n")
864 include.write("PyObject *libvirt_%s_pointer(PyObject *self, PyObject *args);\n" % classname)
866 export.write(" { (char *)\"%s_pointer\", libvirt_%s_pointer, METH_VARARGS, NULL },\n" %
867 (classname, classname))
869 def buildStubs(module, api_xml):
870 global py_types
871 global unknown_types
872 global onlyOverrides
874 if module not in ["libvirt", "libvirt-qemu", "libvirt-lxc"]:
875 print("ERROR: Unknown module type: %s" % module)
876 return None
878 if module == "libvirt":
879 funcs = functions
880 funcs_failed = functions_failed
881 funcs_skipped = functions_skipped
882 elif module == "libvirt-lxc":
883 funcs = lxc_functions
884 funcs_failed = lxc_functions_failed
885 funcs_skipped = lxc_functions_skipped
886 elif module == "libvirt-qemu":
887 funcs = qemu_functions
888 funcs_failed = qemu_functions_failed
889 funcs_skipped = qemu_functions_skipped
891 try:
892 f = open(api_xml)
893 data = f.read()
894 f.close()
895 onlyOverrides = False
896 (parser, target) = getparser()
897 parser.feed(data)
898 parser.close()
899 except IOError:
900 msg = sys.exc_info()[1]
901 print(file, ":", msg)
902 sys.exit(1)
904 n = len(list(funcs.keys()))
905 if not quiet:
906 print("Found %d functions in %s" % ((n), api_xml))
908 override_api_xml = "%s-override-api.xml" % module
909 py_types['pythonObject'] = ('O', "pythonObject", "pythonObject", "pythonObject")
911 try:
912 f = open(override_api_xml)
913 data = f.read()
914 f.close()
915 onlyOverrides = True
916 (parser, target) = getparser()
917 parser.feed(data)
918 parser.close()
919 except IOError:
920 msg = sys.exc_info()[1]
921 print(file, ":", msg)
923 if not quiet:
924 # XXX: This is not right, same function already in @functions
925 # will be overwritten.
926 print("Found %d functions in %s" % ((len(list(funcs.keys())) - n), override_api_xml))
927 nb_wrap = 0
928 failed = 0
929 skipped = 0
931 header_file = "build/%s.h" % module
932 export_file = "build/%s-export.c" % module
933 wrapper_file = "build/%s.c" % module
935 include = open(header_file, "w")
936 include.write("/* Generated by generator.py */\n\n")
938 export = open(export_file, "w")
939 export.write("/* Generated by generator.py */\n\n")
941 wrapper = open(wrapper_file, "w")
942 wrapper.write("/* Generated by generator.py */\n\n")
943 wrapper.write("#include <Python.h>\n")
944 wrapper.write("#include <libvirt/" + module + ".h>\n")
945 wrapper.write("#include \"typewrappers.h\"\n")
946 wrapper.write("#include \"build/" + module + ".h\"\n\n")
948 for function in sorted(funcs.keys()):
949 # Skip the functions which are not for the module
950 ret = print_function_wrapper(module, function, wrapper, export, include)
951 if ret < 0:
952 failed = failed + 1
953 funcs_failed.append(function)
954 del funcs[function]
955 if ret == 0:
956 skipped = skipped + 1
957 funcs_skipped.append(function)
958 del funcs[function]
959 if ret == 1:
960 nb_wrap = nb_wrap + 1
962 if module == "libvirt":
963 # Write C pointer conversion functions.
964 for classname in primary_classes:
965 print_c_pointer(classname, wrapper, export, include)
966 # Write define wrappers around event id enums, so that the
967 # preprocessor can see which enums were available.
968 for event_id in event_ids:
969 include.write("#define %s %s\n" % (event_id, event_id))
971 include.close()
972 export.close()
973 wrapper.close()
975 if not quiet:
976 print("Generated %d wrapper functions" % nb_wrap)
978 if unknown_types:
979 print("Missing type converters: ")
980 for type in list(unknown_types.keys()):
981 print("%s:%d " % (type, len(unknown_types[type])))
983 for f in funcs_failed:
984 print("ERROR: failed %s" % f)
986 if failed > 0:
987 return -1
988 if len(unknown_types) > 0:
989 return -1
990 return 0
992 #######################################################################
994 # This part writes part of the Python front-end classes based on
995 # mapping rules between types and classes and also based on function
996 # renaming to get consistent function names at the Python level
998 #######################################################################
1001 # The type automatically remapped to generated classes
1003 classes_type = {
1004 "virDomainPtr": ("._o", "virDomain(self,_obj=%s)", "virDomain"),
1005 "virDomain *": ("._o", "virDomain(self, _obj=%s)", "virDomain"),
1006 "virNetworkPtr": ("._o", "virNetwork(self, _obj=%s)", "virNetwork"),
1007 "virNetwork *": ("._o", "virNetwork(self, _obj=%s)", "virNetwork"),
1008 "virInterfacePtr": ("._o", "virInterface(self, _obj=%s)", "virInterface"),
1009 "virInterface *": ("._o", "virInterface(self, _obj=%s)", "virInterface"),
1010 "virStoragePoolPtr": ("._o", "virStoragePool(self, _obj=%s)", "virStoragePool"),
1011 "virStoragePool *": ("._o", "virStoragePool(self, _obj=%s)", "virStoragePool"),
1012 "virStorageVolPtr": ("._o", "virStorageVol(self, _obj=%s)", "virStorageVol"),
1013 "virStorageVol *": ("._o", "virStorageVol(self, _obj=%s)", "virStorageVol"),
1014 "virNodeDevicePtr": ("._o", "virNodeDevice(self, _obj=%s)", "virNodeDevice"),
1015 "virNodeDevice *": ("._o", "virNodeDevice(self, _obj=%s)", "virNodeDevice"),
1016 "virSecretPtr": ("._o", "virSecret(self, _obj=%s)", "virSecret"),
1017 "virSecret *": ("._o", "virSecret(self, _obj=%s)", "virSecret"),
1018 "virNWFilterPtr": ("._o", "virNWFilter(self, _obj=%s)", "virNWFilter"),
1019 "virNWFilter *": ("._o", "virNWFilter(self, _obj=%s)", "virNWFilter"),
1020 "virNWFilterBindingPtr": ("._o", "virNWFilterBinding(self, _obj=%s)", "virNWFilterBinding"),
1021 "virNWFilterBinding *": ("._o", "virNWFilterBinding(self, _obj=%s)", "virNWFilterBinding"),
1022 "virStreamPtr": ("._o", "virStream(self, _obj=%s)", "virStream"),
1023 "virStream *": ("._o", "virStream(self, _obj=%s)", "virStream"),
1024 "virConnectPtr": ("._o", "virConnect(_obj=%s)", "virConnect"),
1025 "virConnect *": ("._o", "virConnect(_obj=%s)", "virConnect"),
1026 "virDomainSnapshotPtr": ("._o", "virDomainSnapshot(self,_obj=%s)", "virDomainSnapshot"),
1027 "virDomainSnapshot *": ("._o", "virDomainSnapshot(self, _obj=%s)", "virDomainSnapshot"),
1030 primary_classes = ["virDomain", "virNetwork", "virInterface",
1031 "virStoragePool", "virStorageVol",
1032 "virConnect", "virNodeDevice", "virSecret",
1033 "virNWFilter", "virNWFilterBinding",
1034 "virStream", "virDomainSnapshot"]
1036 classes_destructors = {
1037 "virDomain": "virDomainFree",
1038 "virNetwork": "virNetworkFree",
1039 "virInterface": "virInterfaceFree",
1040 "virStoragePool": "virStoragePoolFree",
1041 "virStorageVol": "virStorageVolFree",
1042 "virNodeDevice" : "virNodeDeviceFree",
1043 "virSecret": "virSecretFree",
1044 "virNWFilter": "virNWFilterFree",
1045 "virNWFilterBinding": "virNWFilterBindingFree",
1046 "virDomainSnapshot": "virDomainSnapshotFree",
1047 # We hand-craft __del__ for this one
1048 #"virStream": "virStreamFree",
1051 class_skip_connect_impl = {
1052 "virConnect" : True,
1055 class_domain_impl = {
1056 "virDomainSnapshot": True,
1059 functions_noexcept = {
1060 'virDomainGetID': True,
1061 'virDomainGetName': True,
1062 'virNetworkGetName': True,
1063 'virInterfaceGetName': True,
1064 'virStoragePoolGetName': True,
1065 'virStorageVolGetName': True,
1066 'virStorageVolGetkey': True,
1067 'virNodeDeviceGetName': True,
1068 'virNodeDeviceGetParent': True,
1069 'virSecretGetUsageType': True,
1070 'virSecretGetUsageID': True,
1071 'virNWFilterGetName': True,
1072 'virNWFilterBindingGetFilterName': True,
1073 'virNWFilterBindingGetPortDev': True,
1076 function_classes = {}
1078 function_classes["None"] = []
1080 # Functions returning an integral type which need special rules to
1081 # check for errors and raise exceptions.
1082 functions_int_exception_test = {
1083 'virDomainGetMaxMemory': "%s == 0",
1085 functions_int_default_test = "%s == -1"
1087 def is_integral_type (name):
1088 return not re.search ("^(unsigned)? ?(int|long)$", name) is None
1090 def is_optional_arg(info):
1091 return re.search("^\(?optional\)?", info) is not None
1093 def is_python_noninteger_type (name):
1095 return name[-1:] == "*"
1097 def nameFixup(name, classe, type, file):
1098 # avoid a desastrous clash
1099 listname = classe + "List"
1100 ll = len(listname)
1101 l = len(classe)
1102 if name[0:l] == listname:
1103 func = name[l:]
1104 func = func[0:1].lower() + func[1:]
1105 elif name[0:16] == "virNetworkDefine":
1106 func = name[3:]
1107 func = func[0:1].lower() + func[1:]
1108 elif name[0:19] == "virNetworkCreateXML":
1109 func = name[3:]
1110 func = func[0:1].lower() + func[1:]
1111 elif name[0:16] == "virNetworkLookup":
1112 func = name[3:]
1113 func = func[0:1].lower() + func[1:]
1114 elif name[0:18] == "virInterfaceDefine":
1115 func = name[3:]
1116 func = func[0:1].lower() + func[1:]
1117 elif name[0:21] == "virInterfaceCreateXML":
1118 func = name[3:]
1119 func = func[0:1].lower() + func[1:]
1120 elif name[0:18] == "virInterfaceLookup":
1121 func = name[3:]
1122 func = func[0:1].lower() + func[1:]
1123 elif name[0:15] == "virSecretDefine":
1124 func = name[3:]
1125 func = func[0:1].lower() + func[1:]
1126 elif name[0:15] == "virSecretLookup":
1127 func = name[3:]
1128 func = func[0:1].lower() + func[1:]
1129 elif name[0:27] == "virNWFilterBindingCreateXML":
1130 func = name[3:]
1131 func = func[0:3].lower() + func[3:]
1132 elif name[0:24] == "virNWFilterBindingLookup":
1133 func = name[3:]
1134 func = func[0:3].lower() + func[3:]
1135 elif name[0:24] == "virNWFilterBindingDefine":
1136 func = name[3:]
1137 func = func[0:3].lower() + func[3:]
1138 elif name[0:24] == "virNWFilterBindingLookup":
1139 func = name[3:]
1140 func = func[0:3].lower() + func[3:]
1141 elif name[0:17] == "virNWFilterDefine":
1142 func = name[3:]
1143 func = func[0:3].lower() + func[3:]
1144 elif name[0:17] == "virNWFilterLookup":
1145 func = name[3:]
1146 func = func[0:3].lower() + func[3:]
1147 elif name[0:20] == "virStoragePoolDefine":
1148 func = name[3:]
1149 func = func[0:1].lower() + func[1:]
1150 elif name[0:23] == "virStoragePoolCreateXML":
1151 func = name[3:]
1152 func = func[0:1].lower() + func[1:]
1153 elif name[0:20] == "virStoragePoolLookup":
1154 func = name[3:]
1155 func = func[0:1].lower() + func[1:]
1156 elif name[0:19] == "virStorageVolDefine":
1157 func = name[3:]
1158 func = func[0:1].lower() + func[1:]
1159 elif name[0:19] == "virStorageVolLookup":
1160 func = name[3:]
1161 func = func[0:1].lower() + func[1:]
1162 elif name[0:20] == "virDomainGetCPUStats":
1163 func = name[9:]
1164 func = func[0:1].lower() + func[1:]
1165 elif name[0:24] == "virDomainGetIOThreadInfo":
1166 func = name[12:]
1167 func = func[0:2].lower() + func[2:]
1168 elif name[0:18] == "virDomainGetFSInfo":
1169 func = name[12:]
1170 func = func[0:2].lower() + func[2:]
1171 elif name[0:12] == "virDomainGet":
1172 func = name[12:]
1173 func = func[0:1].lower() + func[1:]
1174 elif name[0:29] == "virDomainSnapshotLookupByName":
1175 func = name[9:]
1176 func = func[0:1].lower() + func[1:]
1177 elif name[0:26] == "virDomainSnapshotListNames":
1178 func = name[9:]
1179 func = func[0:1].lower() + func[1:]
1180 elif name[0:28] == "virDomainSnapshotNumChildren":
1181 func = name[17:]
1182 func = func[0:1].lower() + func[1:]
1183 elif name[0:20] == "virDomainSnapshotNum":
1184 func = name[9:]
1185 func = func[0:1].lower() + func[1:]
1186 elif name[0:26] == "virDomainSnapshotCreateXML":
1187 func = name[9:]
1188 func = func[0:1].lower() + func[1:]
1189 elif name[0:24] == "virDomainSnapshotCurrent":
1190 func = name[9:]
1191 func = func[0:1].lower() + func[1:]
1192 elif name[0:17] == "virDomainSnapshot":
1193 func = name[17:]
1194 func = func[0:1].lower() + func[1:]
1195 elif name[0:9] == "virDomain":
1196 func = name[9:]
1197 func = func[0:1].lower() + func[1:]
1198 elif name[0:13] == "virNetworkGet":
1199 func = name[13:]
1200 func = func[0:1].lower() + func[1:]
1201 func = func.replace("dHCP", "DHCP")
1202 elif name[0:10] == "virNetwork":
1203 func = name[10:]
1204 func = func[0:1].lower() + func[1:]
1205 elif name[0:15] == "virInterfaceGet":
1206 func = name[15:]
1207 func = func[0:1].lower() + func[1:]
1208 elif name[0:12] == "virInterface":
1209 func = name[12:]
1210 func = func[0:1].lower() + func[1:]
1211 elif name[0:12] == 'virSecretGet':
1212 func = name[12:]
1213 func = func[0:1].lower() + func[1:]
1214 elif name[0:9] == 'virSecret':
1215 func = name[9:]
1216 func = func[0:1].lower() + func[1:]
1217 elif name[0:21] == 'virNWFilterBindingGet':
1218 func = name[21:]
1219 func = func[0:1].lower() + func[1:]
1220 elif name[0:18] == 'virNWFilterBinding':
1221 func = name[18:]
1222 func = func[0:1].lower() + func[1:]
1223 elif name[0:14] == 'virNWFilterGet':
1224 func = name[14:]
1225 func = func[0:1].lower() + func[1:]
1226 elif name[0:11] == 'virNWFilter':
1227 func = name[11:]
1228 func = func[0:1].lower() + func[1:]
1229 elif name[0:12] == 'virStreamNew':
1230 func = "newStream"
1231 elif name[0:9] == 'virStream':
1232 func = name[9:]
1233 func = func[0:1].lower() + func[1:]
1234 elif name[0:17] == "virStoragePoolGet":
1235 func = name[17:]
1236 func = func[0:1].lower() + func[1:]
1237 elif name[0:14] == "virStoragePool":
1238 func = name[14:]
1239 func = func[0:1].lower() + func[1:]
1240 elif name[0:16] == "virStorageVolGet":
1241 func = name[16:]
1242 func = func[0:1].lower() + func[1:]
1243 elif name[0:13] == "virStorageVol":
1244 func = name[13:]
1245 func = func[0:1].lower() + func[1:]
1246 elif name[0:13] == "virNodeDevice":
1247 if name[13:16] == "Get":
1248 func = name[16].lower() + name[17:]
1249 elif name[13:19] == "Lookup" or name[13:19] == "Create":
1250 func = name[3].lower() + name[4:]
1251 else:
1252 func = name[13].lower() + name[14:]
1253 elif name[0:7] == "virNode":
1254 func = name[7:]
1255 func = func[0:1].lower() + func[1:]
1256 elif name[0:10] == "virConnect":
1257 func = name[10:]
1258 func = func[0:1].lower() + func[1:]
1259 elif name[0:3] == "xml":
1260 func = name[3:]
1261 func = func[0:1].lower() + func[1:]
1262 else:
1263 func = name
1264 if func == "iD":
1265 func = "ID"
1266 if func == "uUID":
1267 func = "UUID"
1268 if func == "uUIDString":
1269 func = "UUIDString"
1270 if func == "oSType":
1271 func = "OSType"
1272 if func == "xMLDesc":
1273 func = "XMLDesc"
1274 if func == "mACString":
1275 func = "MACString"
1277 return func
1280 def functionSortKey(info):
1281 (index, func, name, ret, args, filename, mod) = info
1282 return func, filename
1284 def writeDoc(module, name, args, indent, output):
1285 if module == "libvirt":
1286 funcs = functions
1287 elif module == "libvirt-lxc":
1288 funcs = lxc_functions
1289 elif module == "libvirt-qemu":
1290 funcs = qemu_functions
1291 if funcs[name][0] is None or funcs[name][0] == "":
1292 return
1293 val = funcs[name][0]
1294 val = val.replace("NULL", "None")
1295 output.write(indent)
1296 output.write('"""')
1297 i = val.find("\n")
1298 while i >= 0:
1299 str = val[0:i+1]
1300 val = val[i+1:]
1301 output.write(str)
1302 i = val.find("\n")
1303 output.write(indent)
1304 output.write(val)
1305 output.write(' """\n')
1307 def buildWrappers(module):
1308 global ctypes
1309 global py_types
1310 global unknown_types
1311 global functions
1312 global function_classes
1313 global classes_type
1314 global classes_list
1315 global primary_classes
1316 global classes_destructors
1317 global functions_noexcept
1319 if not module == "libvirt":
1320 print("ERROR: Unknown module type: %s" % module)
1321 return None
1323 for type in list(classes_type.keys()):
1324 function_classes[classes_type[type][2]] = []
1327 # Build the list of C types to look for ordered to start
1328 # with primary classes
1330 ctypes = []
1331 classes_list = []
1332 ctypes_processed = {}
1333 classes_processed = {}
1334 for classe in primary_classes:
1335 classes_list.append(classe)
1336 classes_processed[classe] = ()
1337 for type in list(classes_type.keys()):
1338 tinfo = classes_type[type]
1339 if tinfo[2] == classe:
1340 ctypes.append(type)
1341 ctypes_processed[type] = ()
1342 for type in list(classes_type.keys()):
1343 if type in ctypes_processed:
1344 continue
1345 tinfo = classes_type[type]
1346 if tinfo[2] not in classes_processed:
1347 classes_list.append(tinfo[2])
1348 classes_processed[tinfo[2]] = ()
1350 ctypes.append(type)
1351 ctypes_processed[type] = ()
1353 for name in list(functions.keys()):
1354 found = 0
1355 (desc, ret, args, file, mod, cond) = functions[name]
1356 for type in ctypes:
1357 classe = classes_type[type][2]
1359 if name[0:3] == "vir" and len(args) >= 1 and args[0][1] == type:
1360 found = 1
1361 func = nameFixup(name, classe, type, file)
1362 info = (0, func, name, ret, args, file, mod)
1363 function_classes[classe].append(info)
1364 break
1365 elif name[0:3] == "vir" and len(args) >= 2 and args[1][1] == type \
1366 and file != "python_accessor" and not name in function_skip_index_one:
1367 found = 1
1368 func = nameFixup(name, classe, type, file)
1369 info = (1, func, name, ret, args, file, mod)
1370 function_classes[classe].append(info)
1371 break
1372 if found == 1:
1373 continue
1374 func = nameFixup(name, "None", file, file)
1375 info = (0, func, name, ret, args, file, mod)
1376 function_classes['None'].append(info)
1378 classes_file = "build/%s.py" % module
1379 extra_file = "%s-override.py" % module
1380 extra = None
1382 classes = open(classes_file, "w")
1384 if os.path.exists(extra_file):
1385 extra = open(extra_file, "r")
1386 classes.write("#\n")
1387 classes.write("# WARNING WARNING WARNING WARNING\n")
1388 classes.write("#\n")
1389 classes.write("# This file is automatically written by generator.py. Any changes\n")
1390 classes.write("# made here will be lost.\n")
1391 classes.write("#\n")
1392 classes.write("# To change the manually written methods edit " + module + "-override.py\n")
1393 classes.write("# To change the automatically written methods edit generator.py\n")
1394 classes.write("#\n")
1395 classes.write("# WARNING WARNING WARNING WARNING\n")
1396 classes.write("#\n")
1397 if extra is not None:
1398 classes.writelines(extra.readlines())
1399 classes.write("#\n")
1400 classes.write("# WARNING WARNING WARNING WARNING\n")
1401 classes.write("#\n")
1402 classes.write("# Automatically written part of python bindings for libvirt\n")
1403 classes.write("#\n")
1404 classes.write("# WARNING WARNING WARNING WARNING\n")
1405 if extra is not None:
1406 extra.close()
1408 if "None" in function_classes:
1409 flist = function_classes["None"]
1410 flist.sort(key=functionSortKey)
1411 oldfile = ""
1412 for info in flist:
1413 (index, func, name, ret, args, file, mod) = info
1414 if file != oldfile:
1415 classes.write("#\n# Functions from module %s\n#\n\n" % file)
1416 oldfile = file
1417 classes.write("def %s(" % func)
1418 n = 0
1419 for arg in args:
1420 if n != 0:
1421 classes.write(", ")
1422 classes.write("%s" % arg[0])
1423 if arg[0] == "flags" or is_optional_arg(arg[2]):
1424 if is_integral_type(arg[1]):
1425 classes.write("=0")
1426 else:
1427 classes.write("=None")
1428 n = n + 1
1429 classes.write("):\n")
1430 writeDoc(module, name, args, ' ', classes)
1432 for arg in args:
1433 if arg[1] in classes_type:
1434 classes.write(" if %s is None: %s__o = None\n" %
1435 (arg[0], arg[0]))
1436 classes.write(" else: %s__o = %s%s\n" %
1437 (arg[0], arg[0], classes_type[arg[1]][0]))
1438 if ret[0] != "void":
1439 classes.write(" ret = ")
1440 else:
1441 classes.write(" ")
1442 classes.write("libvirtmod.%s(" % name)
1443 n = 0
1444 for arg in args:
1445 if n != 0:
1446 classes.write(", ")
1447 classes.write("%s" % arg[0])
1448 if arg[1] in classes_type:
1449 classes.write("__o")
1450 n = n + 1
1451 classes.write(")\n")
1453 if ret[0] != "void":
1454 if ret[0] in classes_type:
1456 # Raise an exception
1458 if name in functions_noexcept:
1459 classes.write(" if ret is None:return None\n")
1460 else:
1461 classes.write(
1462 " if ret is None:raise libvirtError('%s() failed')\n" %
1463 (name))
1465 classes.write(" return ")
1466 classes.write(classes_type[ret[0]][1] % ("ret"))
1467 classes.write("\n")
1469 # For functions returning an integral type there are
1470 # several things that we can do, depending on the
1471 # contents of functions_int_*:
1472 elif is_integral_type (ret[0]):
1473 if name not in functions_noexcept:
1474 if name in functions_int_exception_test:
1475 test = functions_int_exception_test[name]
1476 else:
1477 test = functions_int_default_test
1478 classes.write ((" if " + test +
1479 ": raise libvirtError ('%s() failed')\n") %
1480 ("ret", name))
1481 classes.write(" return ret\n")
1483 elif is_python_noninteger_type (ret[0]):
1484 if name not in functions_noexcept:
1485 classes.write ((" if %s is None" +
1486 ": raise libvirtError ('%s() failed')\n") %
1487 ("ret", name))
1488 classes.write(" return ret\n")
1490 else:
1491 classes.write(" return ret\n")
1493 classes.write("\n")
1495 for classname in classes_list:
1496 if classname == "None":
1497 pass
1498 else:
1499 classes.write("class %s(object):\n" % (classname))
1500 if classname in [ "virDomain", "virNetwork", "virInterface", "virStoragePool",
1501 "virStorageVol", "virNodeDevice", "virSecret","virStream",
1502 "virNWFilter", "virNWFilterBinding" ]:
1503 classes.write(" def __init__(self, conn, _obj=None):\n")
1504 elif classname in [ 'virDomainSnapshot' ]:
1505 classes.write(" def __init__(self, dom, _obj=None):\n")
1506 else:
1507 classes.write(" def __init__(self, _obj=None):\n")
1508 if classname in [ "virDomain", "virNetwork", "virInterface",
1509 "virNodeDevice", "virSecret", "virStream",
1510 "virNWFilter", "virNWFilterBinding" ]:
1511 classes.write(" self._conn = conn\n")
1512 elif classname in [ "virStorageVol", "virStoragePool" ]:
1513 classes.write(" self._conn = conn\n" + \
1514 " if not isinstance(conn, virConnect):\n" + \
1515 " self._conn = conn._conn\n")
1516 elif classname in [ "virDomainSnapshot" ]:
1517 classes.write(" self._dom = dom\n")
1518 classes.write(" self._conn = dom.connect()\n")
1519 classes.write(" if type(_obj).__name__ not in [\"PyCapsule\", \"PyCObject\"]:\n")
1520 classes.write(" raise Exception(\"Expected a wrapped C Object but got %s\" % type(_obj))\n")
1521 classes.write(" self._o = _obj\n\n")
1522 destruct=None
1523 if classname in classes_destructors:
1524 classes.write(" def __del__(self):\n")
1525 classes.write(" if self._o is not None:\n")
1526 classes.write(" libvirtmod.%s(self._o)\n" %
1527 classes_destructors[classname])
1528 classes.write(" self._o = None\n\n")
1529 destruct=classes_destructors[classname]
1531 if classname not in class_skip_connect_impl:
1532 # Build python safe 'connect' method
1533 classes.write(" def connect(self):\n")
1534 classes.write(" return self._conn\n\n")
1536 if classname in class_domain_impl:
1537 classes.write(" def domain(self):\n")
1538 classes.write(" return self._dom\n\n")
1540 classes.write(" def c_pointer(self):\n")
1541 classes.write(" \"\"\"Get C pointer to underlying object\"\"\"\n")
1542 classes.write(" return libvirtmod.%s_pointer(self._o)\n\n" %
1543 classname)
1545 flist = function_classes[classname]
1546 flist.sort(key=functionSortKey)
1547 oldfile = ""
1548 for info in flist:
1549 (index, func, name, ret, args, file, mod) = info
1551 # Do not provide as method the destructors for the class
1552 # to avoid double free
1554 if name == destruct:
1555 continue
1556 if file != oldfile:
1557 if file == "python_accessor":
1558 classes.write(" # accessors for %s\n" % (classname))
1559 else:
1560 classes.write(" #\n")
1561 classes.write(" # %s functions from module %s\n" % (
1562 classname, file))
1563 classes.write(" #\n\n")
1564 oldfile = file
1565 classes.write(" def %s(self" % func)
1566 n = 0
1567 for arg in args:
1568 if n != index:
1569 classes.write(", %s" % arg[0])
1570 if arg[0] == "flags" or is_optional_arg(arg[2]):
1571 if is_integral_type(arg[1]):
1572 classes.write("=0")
1573 else:
1574 classes.write("=None")
1575 n = n + 1
1576 classes.write("):\n")
1577 writeDoc(module, name, args, ' ', classes)
1578 n = 0
1579 for arg in args:
1580 if arg[1] in classes_type:
1581 if n != index:
1582 classes.write(" if %s is None: %s__o = None\n" %
1583 (arg[0], arg[0]))
1584 classes.write(" else: %s__o = %s%s\n" %
1585 (arg[0], arg[0], classes_type[arg[1]][0]))
1586 n = n + 1
1587 if ret[0] != "void":
1588 classes.write(" ret = ")
1589 else:
1590 classes.write(" ")
1591 n = 0
1592 classes.write("libvirtmod.%s(" % name)
1593 for arg in args:
1594 if n != 0:
1595 classes.write(", ")
1596 if n != index:
1597 classes.write("%s" % arg[0])
1598 if arg[1] in classes_type:
1599 classes.write("__o")
1600 else:
1601 classes.write("self")
1602 if arg[1] in classes_type:
1603 classes.write(classes_type[arg[1]][0])
1604 n = n + 1
1605 classes.write(")\n")
1607 if name == "virConnectClose":
1608 classes.write(" self._o = None\n")
1610 # For functions returning object types:
1611 if ret[0] != "void":
1612 if ret[0] in classes_type:
1614 # Raise an exception
1616 if name in functions_noexcept:
1617 classes.write(
1618 " if ret is None:return None\n")
1619 else:
1620 if classname == "virConnect":
1621 classes.write(
1622 " if ret is None:raise libvirtError('%s() failed', conn=self)\n" %
1623 (name))
1624 elif classname == "virDomain":
1625 classes.write(
1626 " if ret is None:raise libvirtError('%s() failed', dom=self)\n" %
1627 (name))
1628 elif classname == "virNetwork":
1629 classes.write(
1630 " if ret is None:raise libvirtError('%s() failed', net=self)\n" %
1631 (name))
1632 elif classname == "virInterface":
1633 classes.write(
1634 " if ret is None:raise libvirtError('%s() failed', net=self)\n" %
1635 (name))
1636 elif classname == "virStoragePool":
1637 classes.write(
1638 " if ret is None:raise libvirtError('%s() failed', pool=self)\n" %
1639 (name))
1640 elif classname == "virStorageVol":
1641 classes.write(
1642 " if ret is None:raise libvirtError('%s() failed', vol=self)\n" %
1643 (name))
1644 elif classname == "virDomainSnapshot":
1645 classes.write(
1646 " if ret is None:raise libvirtError('%s() failed', dom=self._dom)\n" %
1647 (name))
1648 else:
1649 classes.write(
1650 " if ret is None:raise libvirtError('%s() failed')\n" %
1651 (name))
1654 # generate the returned class wrapper for the object
1656 classes.write(" __tmp = ")
1657 classes.write(classes_type[ret[0]][1] % ("ret"))
1658 classes.write("\n")
1661 # return the class
1663 classes.write(" return __tmp\n")
1665 # For functions returning an integral type there
1666 # are several things that we can do, depending on
1667 # the contents of functions_int_*:
1668 elif is_integral_type (ret[0]):
1669 if name not in functions_noexcept:
1670 if name in functions_int_exception_test:
1671 test = functions_int_exception_test[name]
1672 else:
1673 test = functions_int_default_test
1674 if classname == "virConnect":
1675 classes.write ((" if " + test +
1676 ": raise libvirtError ('%s() failed', conn=self)\n") %
1677 ("ret", name))
1678 elif classname == "virDomain":
1679 classes.write ((" if " + test +
1680 ": raise libvirtError ('%s() failed', dom=self)\n") %
1681 ("ret", name))
1682 elif classname == "virNetwork":
1683 classes.write ((" if " + test +
1684 ": raise libvirtError ('%s() failed', net=self)\n") %
1685 ("ret", name))
1686 elif classname == "virInterface":
1687 classes.write ((" if " + test +
1688 ": raise libvirtError ('%s() failed', net=self)\n") %
1689 ("ret", name))
1690 elif classname == "virStoragePool":
1691 classes.write ((" if " + test +
1692 ": raise libvirtError ('%s() failed', pool=self)\n") %
1693 ("ret", name))
1694 elif classname == "virStorageVol":
1695 classes.write ((" if " + test +
1696 ": raise libvirtError ('%s() failed', vol=self)\n") %
1697 ("ret", name))
1698 else:
1699 classes.write ((" if " + test +
1700 ": raise libvirtError ('%s() failed')\n") %
1701 ("ret", name))
1703 classes.write (" return ret\n")
1705 elif is_python_noninteger_type (ret[0]):
1706 if name not in functions_noexcept:
1707 if classname == "virConnect":
1708 classes.write ((" if %s is None" +
1709 ": raise libvirtError ('%s() failed', conn=self)\n") %
1710 ("ret", name))
1711 elif classname == "virDomain":
1712 classes.write ((" if %s is None" +
1713 ": raise libvirtError ('%s() failed', dom=self)\n") %
1714 ("ret", name))
1715 elif classname == "virNetwork":
1716 classes.write ((" if %s is None" +
1717 ": raise libvirtError ('%s() failed', net=self)\n") %
1718 ("ret", name))
1719 elif classname == "virInterface":
1720 classes.write ((" if %s is None" +
1721 ": raise libvirtError ('%s() failed', net=self)\n") %
1722 ("ret", name))
1723 elif classname == "virStoragePool":
1724 classes.write ((" if %s is None" +
1725 ": raise libvirtError ('%s() failed', pool=self)\n") %
1726 ("ret", name))
1727 elif classname == "virStorageVol":
1728 classes.write ((" if %s is None" +
1729 ": raise libvirtError ('%s() failed', vol=self)\n") %
1730 ("ret", name))
1731 else:
1732 classes.write ((" if %s is None" +
1733 ": raise libvirtError ('%s() failed')\n") %
1734 ("ret", name))
1736 classes.write (" return ret\n")
1737 else:
1738 classes.write(" return ret\n")
1740 classes.write("\n")
1741 # Append "<classname>.py" to class def, iff it exists
1742 try:
1743 wantfuncs = []
1744 extra = open("libvirt-override-" + classname + ".py", "r")
1745 classes.write (" #\n")
1746 classes.write (" # %s methods from %s.py (hand coded)\n" % (classname,classname))
1747 classes.write (" #\n")
1748 cached = None
1751 # Since we compile with older libvirt, we don't want to pull
1752 # in manually written python methods which call C methods
1753 # that don't exist. This code attempts to detect which
1754 # methods to skip by looking at the libvirtmod.XXXX calls
1756 def shouldSkip(lines):
1757 for line in lines:
1758 offset = line.find("libvirtmod.")
1759 if offset != -1:
1760 func = line[offset + 11:]
1761 offset = func.find("(")
1762 func = func[0:offset]
1763 if func not in functions_skipped:
1764 return True
1765 return False
1767 for line in extra.readlines():
1768 offset = line.find(" def ")
1769 if offset != -1:
1770 name = line[offset+5:]
1771 offset = name.find("(")
1772 name = name[0:offset]
1773 if cached is not None:
1774 if not shouldSkip(cached):
1775 classes.writelines(cached)
1776 if name == "__del__":
1777 cached = None
1778 classes.write(line)
1779 else:
1780 cached = [line]
1781 else:
1782 if cached is not None:
1783 cached.append(line)
1784 else:
1785 classes.write(line)
1786 if not shouldSkip(cached):
1787 classes.writelines(cached)
1788 classes.write("\n")
1789 extra.close()
1790 except:
1791 pass
1794 # Generate enum constants
1796 def enumsSortKey(data):
1797 value = data[1]
1798 try:
1799 value = int(value)
1800 except ValueError:
1801 value = float('inf')
1802 return value, data[0]
1804 # Resolve only one level of reference
1805 def resolveEnum(enum, data):
1806 for name,val in enum.items():
1807 try:
1808 int(val)
1809 except ValueError:
1810 enum[name] = data[val]
1811 return enum
1813 enumvals = list(enums.items())
1814 # convert list of dicts to one dict
1815 enumData = {}
1816 for type,enum in enumvals:
1817 enumData.update(enum)
1819 if enumvals is not None:
1820 enumvals.sort(key=lambda x: x[0])
1821 for type,enum in enumvals:
1822 classes.write("# %s\n" % type)
1823 items = list(resolveEnum(enum, enumData).items())
1824 items.sort(key=enumsSortKey)
1825 if items[-1][0].endswith('_LAST'):
1826 del items[-1]
1827 for name,value in items:
1828 classes.write("%s = %s\n" % (name,value))
1829 classes.write("\n")
1831 classes.write("# typed parameter names\n")
1832 for name, value in params:
1833 classes.write("%s = \"%s\"\n" % (name, value))
1835 classes.close()
1837 def qemuBuildWrappers(module):
1838 global qemu_functions
1840 if not module == "libvirt-qemu":
1841 print("ERROR: only libvirt-qemu is supported")
1842 return None
1844 extra_file = "%s-override.py" % module
1845 extra = None
1847 fd = open("build/libvirt_qemu.py", "w")
1849 if os.path.exists(extra_file):
1850 extra = open(extra_file, "r")
1851 fd.write("#\n")
1852 fd.write("# WARNING WARNING WARNING WARNING\n")
1853 fd.write("#\n")
1854 fd.write("# This file is automatically written by generator.py. Any changes\n")
1855 fd.write("# made here will be lost.\n")
1856 fd.write("#\n")
1857 fd.write("# To change the manually written methods edit " + module + "-override.py\n")
1858 fd.write("# To change the automatically written methods edit generator.py\n")
1859 fd.write("#\n")
1860 fd.write("# WARNING WARNING WARNING WARNING\n")
1861 fd.write("#\n")
1862 fd.write("# Automatically written part of python bindings for libvirt\n")
1863 fd.write("#\n")
1865 fd.write("import sys\n")
1867 fd.write("try:\n")
1868 fd.write(" import libvirtmod_qemu\n")
1869 fd.write("except ImportError:\n")
1870 fd.write(" lib_e = sys.exc_info()[1]\n")
1871 fd.write(" try:\n")
1872 fd.write(" import cygvirtmod_qemu as libvirtmod_qemu\n")
1873 fd.write(" except ImportError:\n")
1874 fd.write(" cyg_e = sys.exc_info()[1]\n")
1875 fd.write(" if str(cyg_e).count(\"No module named\"):\n")
1876 fd.write(" raise lib_e\n\n")
1878 fd.write("import libvirt\n\n")
1879 fd.write("# WARNING WARNING WARNING WARNING\n")
1880 fd.write("#\n")
1881 if extra is not None:
1882 fd.writelines(extra.readlines())
1883 fd.write("#\n")
1884 if extra is not None:
1885 extra.close()
1887 fd.write("# WARNING WARNING WARNING WARNING\n")
1888 fd.write("#\n")
1889 fd.write("#\n# Functions from module %s\n#\n\n" % module)
1891 # Generate functions directly, no classes
1893 for name in sorted(qemu_functions.keys()):
1894 func = nameFixup(name, 'None', None, None)
1895 (desc, ret, args, file, mod, cond) = qemu_functions[name]
1896 fd.write("def %s(" % func)
1897 n = 0
1898 for arg in args:
1899 if n != 0:
1900 fd.write(", ")
1901 fd.write("%s" % arg[0])
1902 n = n + 1
1903 fd.write("):\n")
1904 writeDoc(module, name, args, ' ', fd)
1906 if ret[0] != "void":
1907 fd.write(" ret = ")
1908 else:
1909 fd.write(" ")
1910 fd.write("libvirtmod_qemu.%s(" % name)
1911 n = 0
1913 conn = None
1915 for arg in args:
1916 if arg[1] == "virConnectPtr":
1917 conn = arg[0]
1919 if n != 0:
1920 fd.write(", ")
1921 if arg[1] in ["virDomainPtr", "virConnectPtr"]:
1922 # FIXME: This might have problem if the function
1923 # has multiple args which are objects.
1924 fd.write("%s.%s" % (arg[0], "_o"))
1925 else:
1926 fd.write("%s" % arg[0])
1927 n = n + 1
1928 fd.write(")\n")
1930 if ret[0] != "void":
1931 fd.write(" if ret is None: raise libvirt.libvirtError('" + name + "() failed')\n")
1932 if ret[0] == "virDomainPtr":
1933 fd.write(" __tmp = libvirt.virDomain(" + conn + ", _obj=ret)\n")
1934 fd.write(" return __tmp\n")
1935 else:
1936 fd.write(" return ret\n")
1938 fd.write("\n")
1941 # Generate enum constants
1943 for type,enum in sorted(qemu_enums.items()):
1944 fd.write("# %s\n" % type)
1945 items = list(enum.items())
1946 items.sort(key=lambda i: (int(i[1]), i[0]))
1947 for name,value in items:
1948 fd.write("%s = %s\n" % (name,value))
1949 fd.write("\n")
1951 fd.close()
1954 def lxcBuildWrappers(module):
1955 global lxc_functions
1957 if not module == "libvirt-lxc":
1958 print("ERROR: only libvirt-lxc is supported")
1959 return None
1961 extra_file = "%s-override.py" % module
1962 extra = None
1964 fd = open("build/libvirt_lxc.py", "w")
1966 if os.path.exists(extra_file):
1967 extra = open(extra_file, "r")
1968 fd.write("#\n")
1969 fd.write("# WARNING WARNING WARNING WARNING\n")
1970 fd.write("#\n")
1971 fd.write("# This file is automatically written by generator.py. Any changes\n")
1972 fd.write("# made here will be lost.\n")
1973 fd.write("#\n")
1974 fd.write("# To change the manually written methods edit " + module + "-override.py\n")
1975 fd.write("# To change the automatically written methods edit generator.py\n")
1976 fd.write("#\n")
1977 fd.write("# WARNING WARNING WARNING WARNING\n")
1978 fd.write("#\n")
1979 if extra is not None:
1980 fd.writelines(extra.readlines())
1981 fd.write("#\n")
1982 fd.write("# WARNING WARNING WARNING WARNING\n")
1983 fd.write("#\n")
1984 fd.write("# Automatically written part of python bindings for libvirt\n")
1985 fd.write("#\n")
1986 fd.write("# WARNING WARNING WARNING WARNING\n")
1987 if extra is not None:
1988 extra.close()
1990 fd.write("import sys\n")
1992 fd.write("try:\n")
1993 fd.write(" import libvirtmod_lxc\n")
1994 fd.write("except ImportError:\n")
1995 fd.write(" lib_e = sys.exc_info()[1]\n")
1996 fd.write(" try:\n")
1997 fd.write(" import cygvirtmod_lxc as libvirtmod_lxc\n")
1998 fd.write(" except ImportError:\n")
1999 fd.write(" cyg_e = sys.exc_info()[1]\n")
2000 fd.write(" if str(cyg_e).count(\"No module named\"):\n")
2001 fd.write(" raise lib_e\n\n")
2003 fd.write("import libvirt\n\n")
2004 fd.write("#\n# Functions from module %s\n#\n\n" % module)
2006 # Generate functions directly, no classes
2008 for name in sorted(lxc_functions.keys()):
2009 func = nameFixup(name, 'None', None, None)
2010 (desc, ret, args, file, mod, cond) = lxc_functions[name]
2011 fd.write("def %s(" % func)
2012 n = 0
2013 for arg in args:
2014 if n != 0:
2015 fd.write(", ")
2016 fd.write("%s" % arg[0])
2017 n = n + 1
2018 fd.write("):\n")
2019 writeDoc(module, name, args, ' ', fd)
2021 if ret[0] != "void":
2022 fd.write(" ret = ")
2023 else:
2024 fd.write(" ")
2025 fd.write("libvirtmod_lxc.%s(" % name)
2026 n = 0
2028 conn = None
2030 for arg in args:
2031 if arg[1] == "virConnectPtr":
2032 conn = arg[0]
2034 if n != 0:
2035 fd.write(", ")
2036 if arg[1] in ["virDomainPtr", "virConnectPtr"]:
2037 # FIXME: This might have problem if the function
2038 # has multiple args which are objects.
2039 fd.write("%s.%s" % (arg[0], "_o"))
2040 else:
2041 fd.write("%s" % arg[0])
2042 n = n + 1
2043 fd.write(")\n")
2045 if ret[0] != "void":
2046 fd.write(" if ret is None: raise libvirt.libvirtError('" + name + "() failed')\n")
2047 if ret[0] == "virDomainPtr":
2048 fd.write(" __tmp = libvirt.virDomain(" + conn + ", _obj=ret)\n")
2049 fd.write(" return __tmp\n")
2050 else:
2051 fd.write(" return ret\n")
2053 fd.write("\n")
2056 # Generate enum constants
2058 for type,enum in sorted(lxc_enums.items()):
2059 fd.write("# %s\n" % type)
2060 items = list(enum.items())
2061 items.sort(key=lambda i: (int(i[1]), i[0]))
2062 for name,value in items:
2063 fd.write("%s = %s\n" % (name,value))
2064 fd.write("\n")
2066 fd.close()
2069 quiet = 0
2070 if not os.path.exists("build"):
2071 os.mkdir("build")
2073 if buildStubs(sys.argv[1], sys.argv[2]) < 0:
2074 sys.exit(1)
2076 if sys.argv[1] == "libvirt":
2077 buildWrappers(sys.argv[1])
2078 elif sys.argv[1] == "libvirt-lxc":
2079 lxcBuildWrappers(sys.argv[1])
2080 elif sys.argv[1] == "libvirt-qemu":
2081 qemuBuildWrappers(sys.argv[1])
2082 else:
2083 print("ERROR: unknown module %s" % sys.argv[1])
2084 sys.exit(1)
2086 sys.exit(0)