Fix regression in lxcOpenNamespace
[libvirt-python/ericb.git] / generator.py
blob9dedc18f75a86ed02755bd16821d542049da2b00
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 'virNetworkPortPtr': ('O', "virNetworkPort", "virNetworkPortPtr", "virNetworkPortPtr"),
332 'virNetworkPort *': ('O', "virNetworkPort", "virNetworkPortPtr", "virNetworkPortPtr"),
333 'const virNetworkPort *': ('O', "virNetworkPort", "virNetworkPortPtr", "virNetworkPortPtr"),
335 'virInterfacePtr': ('O', "virInterface", "virInterfacePtr", "virInterfacePtr"),
336 'virInterface *': ('O', "virInterface", "virInterfacePtr", "virInterfacePtr"),
337 'const virInterface *': ('O', "virInterface", "virInterfacePtr", "virInterfacePtr"),
339 'virStoragePoolPtr': ('O', "virStoragePool", "virStoragePoolPtr", "virStoragePoolPtr"),
340 'virStoragePool *': ('O', "virStoragePool", "virStoragePoolPtr", "virStoragePoolPtr"),
341 'const virStoragePool *': ('O', "virStoragePool", "virStoragePoolPtr", "virStoragePoolPtr"),
343 'virStorageVolPtr': ('O', "virStorageVol", "virStorageVolPtr", "virStorageVolPtr"),
344 'virStorageVol *': ('O', "virStorageVol", "virStorageVolPtr", "virStorageVolPtr"),
345 'const virStorageVol *': ('O', "virStorageVol", "virStorageVolPtr", "virStorageVolPtr"),
347 'virConnectPtr': ('O', "virConnect", "virConnectPtr", "virConnectPtr"),
348 'virConnect *': ('O', "virConnect", "virConnectPtr", "virConnectPtr"),
349 'const virConnect *': ('O', "virConnect", "virConnectPtr", "virConnectPtr"),
351 'virNodeDevicePtr': ('O', "virNodeDevice", "virNodeDevicePtr", "virNodeDevicePtr"),
352 'virNodeDevice *': ('O', "virNodeDevice", "virNodeDevicePtr", "virNodeDevicePtr"),
353 'const virNodeDevice *': ('O', "virNodeDevice", "virNodeDevicePtr", "virNodeDevicePtr"),
355 'virSecretPtr': ('O', "virSecret", "virSecretPtr", "virSecretPtr"),
356 'virSecret *': ('O', "virSecret", "virSecretPtr", "virSecretPtr"),
357 'const virSecret *': ('O', "virSecret", "virSecretPtr", "virSecretPtr"),
359 'virNWFilterPtr': ('O', "virNWFilter", "virNWFilterPtr", "virNWFilterPtr"),
360 'virNWFilter *': ('O', "virNWFilter", "virNWFilterPtr", "virNWFilterPtr"),
361 'const virNWFilter *': ('O', "virNWFilter", "virNWFilterPtr", "virNWFilterPtr"),
363 'virNWFilterBindingPtr': ('O', "virNWFilterBinding", "virNWFilterBindingPtr", "virNWFilterBindingPtr"),
364 'virNWFilterBinding *': ('O', "virNWFilterBinding", "virNWFilterBindingPtr", "virNWFilterBindingPtr"),
365 'const virNWFilterBinding *': ('O', "virNWFilterBinding", "virNWFilterBindingPtr", "virNWFilterBindingPtr"),
367 'virStreamPtr': ('O', "virStream", "virStreamPtr", "virStreamPtr"),
368 'virStream *': ('O', "virStream", "virStreamPtr", "virStreamPtr"),
369 'const virStream *': ('O', "virStream", "virStreamPtr", "virStreamPtr"),
371 'virDomainSnapshotPtr': ('O', "virDomainSnapshot", "virDomainSnapshotPtr", "virDomainSnapshotPtr"),
372 'virDomainSnapshot *': ('O', "virDomainSnapshot", "virDomainSnapshotPtr", "virDomainSnapshotPtr"),
373 'const virDomainSnapshot *': ('O', "virDomainSnapshot", "virDomainSnapshotPtr", "virDomainSnapshotPtr"),
376 unknown_types = {}
378 #######################################################################
380 # This part writes the C <-> Python stubs libvirt.[ch] and
381 # the table libvirt-export.c to add when registrering the Python module
383 #######################################################################
385 # Class methods which are written by hand in libvirt.c but the Python-level
386 # code is still automatically generated (so they are not in skip_function()).
387 skip_impl = (
388 'virConnectGetVersion',
389 'virConnectGetLibVersion',
390 'virConnectListDomainsID',
391 'virConnectListDefinedDomains',
392 'virConnectListNetworks',
393 'virConnectListDefinedNetworks',
394 'virConnectListSecrets',
395 'virConnectListInterfaces',
396 'virConnectListStoragePools',
397 'virConnectListDefinedStoragePools',
398 'virConnectListStorageVols',
399 'virConnectListDefinedStorageVols',
400 'virConnectListDefinedInterfaces',
401 'virConnectListNWFilters',
402 'virDomainSnapshotListNames',
403 'virDomainSnapshotListChildrenNames',
404 'virConnGetLastError',
405 'virGetLastError',
406 'virDomainGetInfo',
407 'virDomainGetState',
408 'virDomainGetControlInfo',
409 'virDomainGetBlockInfo',
410 'virDomainGetJobInfo',
411 'virDomainGetJobStats',
412 'virNodeGetInfo',
413 'virNodeGetSecurityModel',
414 'virDomainGetSecurityLabel',
415 'virDomainGetSecurityLabelList',
416 'virDomainGetUUID',
417 'virDomainGetUUIDString',
418 'virDomainLookupByUUID',
419 'virNetworkGetUUID',
420 'virNetworkGetUUIDString',
421 'virNetworkLookupByUUID',
422 'virDomainGetAutostart',
423 'virNetworkGetAutostart',
424 'virDomainBlockStats',
425 'virDomainInterfaceStats',
426 'virDomainMemoryStats',
427 'virNodeGetCellsFreeMemory',
428 'virDomainGetSchedulerType',
429 'virDomainGetSchedulerParameters',
430 'virDomainGetSchedulerParametersFlags',
431 'virDomainSetSchedulerParameters',
432 'virDomainSetSchedulerParametersFlags',
433 'virDomainSetBlkioParameters',
434 'virDomainGetBlkioParameters',
435 'virDomainSetMemoryParameters',
436 'virDomainGetMemoryParameters',
437 'virDomainSetNumaParameters',
438 'virDomainGetNumaParameters',
439 'virDomainGetVcpus',
440 'virDomainPinVcpu',
441 'virDomainPinVcpuFlags',
442 'virDomainGetVcpuPinInfo',
443 'virDomainGetEmulatorPinInfo',
444 'virDomainPinEmulator',
445 'virDomainGetIOThreadInfo',
446 'virDomainPinIOThread',
447 'virDomainSetIOThreadParams',
448 'virSecretGetValue',
449 'virSecretSetValue',
450 'virSecretGetUUID',
451 'virSecretGetUUIDString',
452 'virSecretLookupByUUID',
453 'virNWFilterGetUUID',
454 'virNWFilterGetUUIDString',
455 'virNWFilterLookupByUUID',
456 'virStoragePoolGetUUID',
457 'virStoragePoolGetUUIDString',
458 'virStoragePoolLookupByUUID',
459 'virStoragePoolGetInfo',
460 'virStorageVolGetInfo',
461 'virStorageVolGetInfoFlags',
462 'virStoragePoolGetAutostart',
463 'virStoragePoolListVolumes',
464 'virDomainBlockPeek',
465 'virDomainMemoryPeek',
466 'virEventRegisterImpl',
467 'virNodeListDevices',
468 'virNodeDeviceListCaps',
469 'virConnectBaselineCPU',
470 'virDomainRevertToSnapshot',
471 'virDomainSendKey',
472 'virNodeGetCPUStats',
473 'virNodeGetMemoryStats',
474 'virDomainGetBlockJobInfo',
475 'virDomainMigrateGetCompressionCache',
476 'virDomainMigrateGetMaxSpeed',
477 'virDomainMigrateGetMaxDowntime',
478 'virDomainBlockStatsFlags',
479 'virDomainSetBlockIoTune',
480 'virDomainGetBlockIoTune',
481 'virDomainSetInterfaceParameters',
482 'virDomainGetInterfaceParameters',
483 'virDomainGetCPUStats',
484 'virDomainGetDiskErrors',
485 'virNodeGetMemoryParameters',
486 'virNodeSetMemoryParameters',
487 'virNodeGetCPUMap',
488 'virDomainMigrate3',
489 'virDomainMigrateToURI3',
490 'virConnectGetCPUModelNames',
491 'virNodeGetFreePages',
492 'virNetworkGetDHCPLeases',
493 'virDomainBlockCopy',
494 'virNodeAllocPages',
495 'virDomainGetFSInfo',
496 'virDomainInterfaceAddresses',
497 'virDomainGetPerfEvents',
498 'virDomainSetPerfEvents',
499 'virDomainGetGuestVcpus',
500 'virConnectBaselineHypervisorCPU',
501 'virDomainGetLaunchSecurityInfo',
502 'virNodeGetSEVInfo',
503 'virNetworkPortGetParameters',
504 'virNetworkPortSetParameters',
507 lxc_skip_impl = (
508 'virDomainLxcOpenNamespace',
511 qemu_skip_impl = (
512 'virDomainQemuMonitorCommand',
513 'virDomainQemuAgentCommand',
517 # These are functions which the generator skips completly - no python
518 # or C code is generated. Generally should not be used for any more
519 # functions than those already listed
520 skip_function = (
521 'virConnectListDomains', # Python API is called virConectListDomainsID for unknown reasons
522 'virConnSetErrorFunc', # Not used in Python API XXX is this a bug ?
523 'virResetError', # Not used in Python API XXX is this a bug ?
524 'virGetVersion', # Python C code is manually written
525 'virSetErrorFunc', # Python API is called virRegisterErrorHandler for unknown reasons
526 'virConnCopyLastError', # Python API is called virConnGetLastError instead
527 'virCopyLastError', # Python API is called virGetLastError instead
528 'virConnectOpenAuth', # Python C code is manually written
529 'virDefaultErrorFunc', # Python virErrorFuncHandler impl calls this from C
530 'virConnectDomainEventRegister', # overridden in virConnect.py
531 'virConnectDomainEventDeregister', # overridden in virConnect.py
532 'virConnectDomainEventRegisterAny', # overridden in virConnect.py
533 'virConnectDomainEventDeregisterAny', # overridden in virConnect.py
534 'virConnectNetworkEventRegisterAny', # overridden in virConnect.py
535 'virConnectNetworkEventDeregisterAny', # overridden in virConnect.py
536 'virConnectStoragePoolEventRegisterAny', # overridden in virConnect.py
537 'virConnectStoragePoolEventDeregisterAny', # overridden in virConnect.py
538 'virConnectNodeDeviceEventRegisterAny', # overridden in virConnect.py
539 'virConnectNodeDeviceEventDeregisterAny', # overridden in virConnect.py
540 'virConnectSecretEventRegisterAny', # overridden in virConnect.py
541 'virConnectSecretEventDeregisterAny', # overridden in virConnect.py
542 'virSaveLastError', # We have our own python error wrapper
543 'virFreeError', # Only needed if we use virSaveLastError
544 'virConnectListAllDomains', # overridden in virConnect.py
545 'virDomainListAllSnapshots', # overridden in virDomain.py
546 'virDomainSnapshotListAllChildren', # overridden in virDomainSnapshot.py
547 'virConnectListAllStoragePools', # overridden in virConnect.py
548 'virStoragePoolListAllVolumes', # overridden in virStoragePool.py
549 'virConnectListAllNetworks', # overridden in virConnect.py
550 'virNetworkListAllPorts', # overridden in virConnect.py
551 'virConnectListAllInterfaces', # overridden in virConnect.py
552 'virConnectListAllNodeDevices', # overridden in virConnect.py
553 'virConnectListAllNWFilters', # overridden in virConnect.py
554 'virConnectListAllNWFilterBindings', # overridden in virConnect.py
555 'virConnectListAllSecrets', # overridden in virConnect.py
556 'virConnectGetAllDomainStats', # overridden in virConnect.py
557 'virDomainListGetStats', # overriden in virConnect.py
559 'virStreamRecvAll', # Pure python libvirt-override-virStream.py
560 'virStreamSendAll', # Pure python libvirt-override-virStream.py
561 'virStreamRecv', # overridden in libvirt-override-virStream.py
562 'virStreamSend', # overridden in libvirt-override-virStream.py
563 'virStreamRecvHole', # overridden in libvirt-override-virStream.py
564 'virStreamSendHole', # overridden in libvirt-override-virStream.py
565 'virStreamRecvFlags', # overridden in libvirt-override-virStream.py
566 'virStreamSparseRecvAll', # overridden in libvirt-override-virStream.py
567 'virStreamSparseSendAll', # overridden in libvirt-override-virStream.py
569 'virConnectUnregisterCloseCallback', # overridden in virConnect.py
570 'virConnectRegisterCloseCallback', # overridden in virConnect.py
572 'virDomainCreateXMLWithFiles', # overridden in virConnect.py
573 'virDomainCreateWithFiles', # overridden in virDomain.py
575 'virDomainFSFreeze', # overridden in virDomain.py
576 'virDomainFSThaw', # overridden in virDomain.py
577 'virDomainGetTime', # overridden in virDomain.py
578 'virDomainSetTime', # overridden in virDomain.py
580 # 'Ref' functions have no use for bindings users.
581 "virConnectRef",
582 "virDomainRef",
583 "virInterfaceRef",
584 "virNetworkRef",
585 "virNetworkPortRef",
586 "virNodeDeviceRef",
587 "virSecretRef",
588 "virNWFilterRef",
589 "virNWFilterBindingRef",
590 "virStoragePoolRef",
591 "virStorageVolRef",
592 "virStreamRef",
593 "virDomainSnapshotRef",
595 # This functions shouldn't be called via the bindings (and even the docs
596 # contain an explicit warning to that effect). The equivalent should be
597 # implemented in pure python for each class
598 "virDomainGetConnect",
599 "virInterfaceGetConnect",
600 "virNetworkGetConnect",
601 "virNetworkPortGetNetwork",
602 "virSecretGetConnect",
603 "virNWFilterGetConnect",
604 "virStoragePoolGetConnect",
605 "virStorageVolGetConnect",
606 "virDomainSnapshotGetConnect",
607 "virDomainSnapshotGetDomain",
609 # only useful in C code, python code uses dict for typed parameters
610 "virTypedParamsAddBoolean",
611 "virTypedParamsAddDouble",
612 "virTypedParamsAddFromString",
613 "virTypedParamsAddInt",
614 "virTypedParamsAddLLong",
615 "virTypedParamsAddString",
616 "virTypedParamsAddUInt",
617 "virTypedParamsAddULLong",
618 "virTypedParamsClear",
619 "virTypedParamsFree",
620 "virTypedParamsGet",
621 "virTypedParamsGetBoolean",
622 "virTypedParamsGetDouble",
623 "virTypedParamsGetInt",
624 "virTypedParamsGetLLong",
625 "virTypedParamsGetString",
626 "virTypedParamsGetUInt",
627 "virTypedParamsGetULLong",
629 'virNetworkDHCPLeaseFree', # only useful in C, python code uses list
630 'virDomainStatsRecordListFree', # only useful in C, python uses dict
631 'virDomainFSInfoFree', # only useful in C, python code uses list
632 'virDomainIOThreadInfoFree', # only useful in C, python code uses list
633 'virDomainInterfaceFree', # only useful in C, python code uses list
636 lxc_skip_function = (
637 "virDomainLxcEnterNamespace",
638 "virDomainLxcEnterSecurityLabel",
640 qemu_skip_function = (
641 #"virDomainQemuAttach",
642 'virConnectDomainQemuMonitorEventRegister', # overridden in -qemu.py
643 'virConnectDomainQemuMonitorEventDeregister', # overridden in -qemu.py
646 # Generate C code, but skip python impl
647 function_skip_python_impl = (
648 "virStreamFree", # Needed in custom virStream __del__, but free shouldn't
649 # be exposed in bindings
652 lxc_function_skip_python_impl = ()
653 qemu_function_skip_python_impl = ()
655 function_skip_index_one = (
656 "virDomainRevertToSnapshot",
659 def print_function_wrapper(module, name, output, export, include):
660 global py_types
661 global unknown_types
662 global functions
663 global lxc_functions
664 global qemu_functions
665 global skipped_modules
666 global function_skip_python_impl
668 try:
669 if module == "libvirt":
670 (desc, ret, args, file, mod, cond) = functions[name]
671 if module == "libvirt-lxc":
672 (desc, ret, args, file, mod, cond) = lxc_functions[name]
673 if module == "libvirt-qemu":
674 (desc, ret, args, file, mod, cond) = qemu_functions[name]
675 except:
676 print("failed to get function %s infos" % name)
677 return
679 if module in skipped_modules:
680 return 0
682 if module == "libvirt":
683 if name in skip_function:
684 return 0
685 if name in skip_impl:
686 # Don't delete the function entry in the caller.
687 return 1
688 elif module == "libvirt-lxc":
689 if name in lxc_skip_function:
690 return 0
691 if name in lxc_skip_impl:
692 # Don't delete the function entry in the caller.
693 return 1
694 elif module == "libvirt-qemu":
695 if name in qemu_skip_function:
696 return 0
697 if name in qemu_skip_impl:
698 # Don't delete the function entry in the caller.
699 return 1
701 c_call = ""
702 format=""
703 format_args=""
704 c_args=""
705 c_return=""
706 c_convert=""
707 num_bufs=0
708 for arg in args:
709 # This should be correct
710 if arg[1][0:6] == "const ":
711 arg[1] = arg[1][6:]
712 c_args = c_args + " %s %s;\n" % (arg[1], arg[0])
713 if arg[1] in py_types:
714 (f, t, n, c) = py_types[arg[1]]
715 if f is not None:
716 format = format + f
717 if t is not None:
718 format_args = format_args + ", &pyobj_%s" % (arg[0])
719 c_args = c_args + " PyObject *pyobj_%s;\n" % (arg[0])
720 c_convert = c_convert + \
721 " %s = (%s) Py%s_Get(pyobj_%s);\n" % (arg[0],
722 arg[1], t, arg[0])
723 else:
724 format_args = format_args + ", &%s" % (arg[0])
725 if f == 't#':
726 format_args = format_args + ", &py_buffsize%d" % num_bufs
727 c_args = c_args + " int py_buffsize%d;\n" % num_bufs
728 num_bufs = num_bufs + 1
729 if c_call != "":
730 c_call = c_call + ", "
731 c_call = c_call + "%s" % (arg[0])
732 else:
733 if arg[1] in skipped_types:
734 return 0
735 if arg[1] in unknown_types:
736 lst = unknown_types[arg[1]]
737 lst.append(name)
738 else:
739 unknown_types[arg[1]] = [name]
740 return -1
741 if format != "":
742 format = format + ":%s" % (name)
744 if ret[0] == 'void':
745 if file == "python_accessor":
746 if args[1][1] == "char *":
747 c_call = "\n VIR_FREE(%s->%s);\n" % (
748 args[0][0], args[1][0], args[0][0], args[1][0])
749 c_call = c_call + " %s->%s = (%s)strdup((const xmlChar *)%s);\n" % (args[0][0],
750 args[1][0], args[1][1], args[1][0])
751 else:
752 c_call = "\n %s->%s = %s;\n" % (args[0][0], args[1][0],
753 args[1][0])
754 else:
755 c_call = "\n %s(%s);\n" % (name, c_call)
756 ret_convert = " Py_INCREF(Py_None);\n return Py_None;\n"
757 elif ret[0] in py_types:
758 (f, t, n, c) = py_types[ret[0]]
759 c_return = " %s c_retval;\n" % (ret[0])
760 if file == "python_accessor" and ret[2] is not None:
761 c_call = "\n c_retval = %s->%s;\n" % (args[0][0], ret[2])
762 else:
763 c_call = "\n c_retval = %s(%s);\n" % (name, c_call)
764 ret_convert = " py_retval = libvirt_%sWrap((%s) c_retval);\n" % (n,c)
765 if n == "charPtr":
766 ret_convert = ret_convert + " free(c_retval);\n"
767 ret_convert = ret_convert + " return py_retval;\n"
768 else:
769 if ret[0] in skipped_types:
770 return 0
771 if ret[0] in unknown_types:
772 lst = unknown_types[ret[0]]
773 lst.append(name)
774 else:
775 unknown_types[ret[0]] = [name]
776 return -1
778 if cond is not None and cond != "":
779 include.write("#if %s\n" % cond)
780 export.write("#if %s\n" % cond)
781 output.write("#if %s\n" % cond)
783 include.write("PyObject * ")
784 if module == "libvirt":
785 include.write("libvirt_%s(PyObject *self, PyObject *args);\n" % (name))
786 export.write(" { (char *)\"%s\", libvirt_%s, METH_VARARGS, NULL },\n" %
787 (name, name))
788 elif module == "libvirt-lxc":
789 include.write("libvirt_lxc_%s(PyObject *self, PyObject *args);\n" % (name))
790 export.write(" { (char *)\"%s\", libvirt_lxc_%s, METH_VARARGS, NULL },\n" %
791 (name, name))
792 elif module == "libvirt-qemu":
793 include.write("libvirt_qemu_%s(PyObject *self, PyObject *args);\n" % (name))
794 export.write(" { (char *)\"%s\", libvirt_qemu_%s, METH_VARARGS, NULL },\n" %
795 (name, name))
797 if file == "python":
798 # Those have been manually generated
799 if cond is not None and cond != "":
800 include.write("#endif\n")
801 export.write("#endif\n")
802 output.write("#endif\n")
803 return 1
804 if file == "python_accessor" and ret[0] != "void" and ret[2] is None:
805 # Those have been manually generated
806 if cond is not None and cond != "":
807 include.write("#endif\n")
808 export.write("#endif\n")
809 output.write("#endif\n")
810 return 1
812 output.write("PyObject *\n")
813 if module == "libvirt":
814 output.write("libvirt_%s(PyObject *self ATTRIBUTE_UNUSED," % (name))
815 elif module == "libvirt-lxc":
816 output.write("libvirt_lxc_%s(PyObject *self ATTRIBUTE_UNUSED," % (name))
817 elif module == "libvirt-qemu":
818 output.write("libvirt_qemu_%s(PyObject *self ATTRIBUTE_UNUSED," % (name))
819 output.write(" PyObject *args")
820 if format == "":
821 output.write(" ATTRIBUTE_UNUSED")
822 output.write(") {\n")
823 if ret[0] != 'void':
824 output.write(" PyObject *py_retval;\n")
825 if c_return != "":
826 output.write(c_return)
827 if c_args != "":
828 output.write(c_args)
829 if format != "":
830 output.write("\n if (!PyArg_ParseTuple(args, (char *)\"%s\"%s))\n" %
831 (format, format_args))
832 output.write(" return NULL;\n")
833 if c_convert != "":
834 output.write(c_convert + "\n")
836 output.write(" LIBVIRT_BEGIN_ALLOW_THREADS;")
837 output.write(c_call)
838 output.write(" LIBVIRT_END_ALLOW_THREADS;\n")
839 output.write(ret_convert)
840 output.write("}\n\n")
841 if cond is not None and cond != "":
842 include.write("#endif /* %s */\n" % cond)
843 export.write("#endif /* %s */\n" % cond)
844 output.write("#endif /* %s */\n" % cond)
846 if module == "libvirt":
847 if name in function_skip_python_impl:
848 return 0
849 elif module == "libvirt-lxc":
850 if name in lxc_function_skip_python_impl:
851 return 0
852 elif module == "libvirt-qemu":
853 if name in qemu_function_skip_python_impl:
854 return 0
855 return 1
857 def print_c_pointer(classname, output, export, include):
858 output.write("PyObject *\n")
859 output.write("libvirt_%s_pointer(PyObject *self ATTRIBUTE_UNUSED, PyObject *args)\n" % classname)
860 output.write("{\n")
861 output.write(" %sPtr ptr;\n" % classname)
862 output.write(" PyObject *pyptr;\n")
863 output.write(" PyObject *pylong;\n")
864 output.write("\n")
865 output.write(" if (!PyArg_ParseTuple(args, (char *) \"O\", &pyptr))\n")
866 output.write(" return NULL;\n")
867 output.write(" ptr = (%sPtr) Py%s_Get(pyptr);\n" % (classname, classname))
868 output.write(" pylong = PyLong_FromVoidPtr(ptr);\n")
869 output.write(" return pylong;\n")
870 output.write("}\n")
871 output.write("\n")
873 include.write("PyObject *libvirt_%s_pointer(PyObject *self, PyObject *args);\n" % classname)
875 export.write(" { (char *)\"%s_pointer\", libvirt_%s_pointer, METH_VARARGS, NULL },\n" %
876 (classname, classname))
878 def buildStubs(module, api_xml):
879 global py_types
880 global unknown_types
881 global onlyOverrides
883 if module not in ["libvirt", "libvirt-qemu", "libvirt-lxc"]:
884 print("ERROR: Unknown module type: %s" % module)
885 return None
887 if module == "libvirt":
888 funcs = functions
889 funcs_failed = functions_failed
890 funcs_skipped = functions_skipped
891 elif module == "libvirt-lxc":
892 funcs = lxc_functions
893 funcs_failed = lxc_functions_failed
894 funcs_skipped = lxc_functions_skipped
895 elif module == "libvirt-qemu":
896 funcs = qemu_functions
897 funcs_failed = qemu_functions_failed
898 funcs_skipped = qemu_functions_skipped
900 try:
901 f = open(api_xml)
902 data = f.read()
903 f.close()
904 onlyOverrides = False
905 (parser, target) = getparser()
906 parser.feed(data)
907 parser.close()
908 except IOError:
909 msg = sys.exc_info()[1]
910 print(file, ":", msg)
911 sys.exit(1)
913 n = len(list(funcs.keys()))
914 if not quiet:
915 print("Found %d functions in %s" % ((n), api_xml))
917 override_api_xml = "%s-override-api.xml" % module
918 py_types['pythonObject'] = ('O', "pythonObject", "pythonObject", "pythonObject")
920 try:
921 f = open(override_api_xml)
922 data = f.read()
923 f.close()
924 onlyOverrides = True
925 (parser, target) = getparser()
926 parser.feed(data)
927 parser.close()
928 except IOError:
929 msg = sys.exc_info()[1]
930 print(file, ":", msg)
932 if not quiet:
933 # XXX: This is not right, same function already in @functions
934 # will be overwritten.
935 print("Found %d functions in %s" % ((len(list(funcs.keys())) - n), override_api_xml))
936 nb_wrap = 0
937 failed = 0
938 skipped = 0
940 header_file = "build/%s.h" % module
941 export_file = "build/%s-export.c" % module
942 wrapper_file = "build/%s.c" % module
944 include = open(header_file, "w")
945 include.write("/* Generated by generator.py */\n\n")
947 export = open(export_file, "w")
948 export.write("/* Generated by generator.py */\n\n")
950 wrapper = open(wrapper_file, "w")
951 wrapper.write("/* Generated by generator.py */\n\n")
952 wrapper.write("#include <Python.h>\n")
953 wrapper.write("#include <libvirt/" + module + ".h>\n")
954 wrapper.write("#include \"typewrappers.h\"\n")
955 wrapper.write("#include \"build/" + module + ".h\"\n\n")
957 for function in sorted(funcs.keys()):
958 # Skip the functions which are not for the module
959 ret = print_function_wrapper(module, function, wrapper, export, include)
960 if ret < 0:
961 failed = failed + 1
962 funcs_failed.append(function)
963 del funcs[function]
964 if ret == 0:
965 skipped = skipped + 1
966 funcs_skipped.append(function)
967 del funcs[function]
968 if ret == 1:
969 nb_wrap = nb_wrap + 1
971 if module == "libvirt":
972 # Write C pointer conversion functions.
973 for classname in primary_classes:
974 print_c_pointer(classname, wrapper, export, include)
975 # Write define wrappers around event id enums, so that the
976 # preprocessor can see which enums were available.
977 for event_id in event_ids:
978 include.write("#define %s %s\n" % (event_id, event_id))
980 include.close()
981 export.close()
982 wrapper.close()
984 if not quiet:
985 print("Generated %d wrapper functions" % nb_wrap)
987 if unknown_types:
988 print("Missing type converters: ")
989 for type in list(unknown_types.keys()):
990 print("%s:%d " % (type, len(unknown_types[type])))
992 for f in funcs_failed:
993 print("ERROR: failed %s" % f)
995 if failed > 0:
996 return -1
997 if len(unknown_types) > 0:
998 return -1
999 return 0
1001 #######################################################################
1003 # This part writes part of the Python front-end classes based on
1004 # mapping rules between types and classes and also based on function
1005 # renaming to get consistent function names at the Python level
1007 #######################################################################
1010 # The type automatically remapped to generated classes
1012 classes_type = {
1013 "virDomainPtr": ("._o", "virDomain(self,_obj=%s)", "virDomain"),
1014 "virDomain *": ("._o", "virDomain(self, _obj=%s)", "virDomain"),
1015 "virNetworkPtr": ("._o", "virNetwork(self, _obj=%s)", "virNetwork"),
1016 "virNetwork *": ("._o", "virNetwork(self, _obj=%s)", "virNetwork"),
1017 "virNetworkPortPtr": ("._o", "virNetworkPort(self, _obj=%s)", "virNetworkPort"),
1018 "virNetworkPort *": ("._o", "virNetworkPort(self, _obj=%s)", "virNetworkPort"),
1019 "virInterfacePtr": ("._o", "virInterface(self, _obj=%s)", "virInterface"),
1020 "virInterface *": ("._o", "virInterface(self, _obj=%s)", "virInterface"),
1021 "virStoragePoolPtr": ("._o", "virStoragePool(self, _obj=%s)", "virStoragePool"),
1022 "virStoragePool *": ("._o", "virStoragePool(self, _obj=%s)", "virStoragePool"),
1023 "virStorageVolPtr": ("._o", "virStorageVol(self, _obj=%s)", "virStorageVol"),
1024 "virStorageVol *": ("._o", "virStorageVol(self, _obj=%s)", "virStorageVol"),
1025 "virNodeDevicePtr": ("._o", "virNodeDevice(self, _obj=%s)", "virNodeDevice"),
1026 "virNodeDevice *": ("._o", "virNodeDevice(self, _obj=%s)", "virNodeDevice"),
1027 "virSecretPtr": ("._o", "virSecret(self, _obj=%s)", "virSecret"),
1028 "virSecret *": ("._o", "virSecret(self, _obj=%s)", "virSecret"),
1029 "virNWFilterPtr": ("._o", "virNWFilter(self, _obj=%s)", "virNWFilter"),
1030 "virNWFilter *": ("._o", "virNWFilter(self, _obj=%s)", "virNWFilter"),
1031 "virNWFilterBindingPtr": ("._o", "virNWFilterBinding(self, _obj=%s)", "virNWFilterBinding"),
1032 "virNWFilterBinding *": ("._o", "virNWFilterBinding(self, _obj=%s)", "virNWFilterBinding"),
1033 "virStreamPtr": ("._o", "virStream(self, _obj=%s)", "virStream"),
1034 "virStream *": ("._o", "virStream(self, _obj=%s)", "virStream"),
1035 "virConnectPtr": ("._o", "virConnect(_obj=%s)", "virConnect"),
1036 "virConnect *": ("._o", "virConnect(_obj=%s)", "virConnect"),
1037 "virDomainSnapshotPtr": ("._o", "virDomainSnapshot(self,_obj=%s)", "virDomainSnapshot"),
1038 "virDomainSnapshot *": ("._o", "virDomainSnapshot(self, _obj=%s)", "virDomainSnapshot"),
1041 primary_classes = ["virDomain", "virNetwork", "virNetworkPort",
1042 "virInterface", "virStoragePool", "virStorageVol",
1043 "virConnect", "virNodeDevice", "virSecret",
1044 "virNWFilter", "virNWFilterBinding",
1045 "virStream", "virDomainSnapshot"]
1047 classes_destructors = {
1048 "virDomain": "virDomainFree",
1049 "virNetwork": "virNetworkFree",
1050 "virNetworkPort": "virNetworkPortFree",
1051 "virInterface": "virInterfaceFree",
1052 "virStoragePool": "virStoragePoolFree",
1053 "virStorageVol": "virStorageVolFree",
1054 "virNodeDevice" : "virNodeDeviceFree",
1055 "virSecret": "virSecretFree",
1056 "virNWFilter": "virNWFilterFree",
1057 "virNWFilterBinding": "virNWFilterBindingFree",
1058 "virDomainSnapshot": "virDomainSnapshotFree",
1059 # We hand-craft __del__ for this one
1060 #"virStream": "virStreamFree",
1063 class_skip_connect_impl = {
1064 "virConnect" : True,
1067 class_domain_impl = {
1068 "virDomainSnapshot": True,
1071 functions_noexcept = {
1072 'virDomainGetID': True,
1073 'virDomainGetName': True,
1074 'virNetworkGetName': True,
1075 'virInterfaceGetName': True,
1076 'virStoragePoolGetName': True,
1077 'virStorageVolGetName': True,
1078 'virStorageVolGetkey': True,
1079 'virNodeDeviceGetName': True,
1080 'virNodeDeviceGetParent': True,
1081 'virSecretGetUsageType': True,
1082 'virSecretGetUsageID': True,
1083 'virNWFilterGetName': True,
1084 'virNWFilterBindingGetFilterName': True,
1085 'virNWFilterBindingGetPortDev': True,
1088 function_classes = {}
1090 function_classes["None"] = []
1092 # Functions returning an integral type which need special rules to
1093 # check for errors and raise exceptions.
1094 functions_int_exception_test = {
1095 'virDomainGetMaxMemory': "%s == 0",
1097 functions_int_default_test = "%s == -1"
1099 def is_integral_type (name):
1100 return not re.search ("^(unsigned)? ?(int|long)$", name) is None
1102 def is_optional_arg(info):
1103 return re.search("^\(?optional\)?", info) is not None
1105 def is_python_noninteger_type (name):
1107 return name[-1:] == "*"
1109 def nameFixup(name, classe, type, file):
1110 # avoid a disastrous clash
1111 listname = classe + "List"
1112 ll = len(listname)
1113 l = len(classe)
1114 if name[0:l] == listname:
1115 func = name[l:]
1116 func = func[0:1].lower() + func[1:]
1117 elif name[0:16] == "virNetworkDefine":
1118 func = name[3:]
1119 func = func[0:1].lower() + func[1:]
1120 elif name[0:19] == "virNetworkCreateXML":
1121 func = name[3:]
1122 func = func[0:1].lower() + func[1:]
1123 elif name[0:16] == "virNetworkLookup":
1124 func = name[3:]
1125 func = func[0:1].lower() + func[1:]
1126 elif name[0:23] == "virNetworkPortCreateXML":
1127 func = name[10:]
1128 func = func[0:1].lower() + func[1:]
1129 elif name[0:20] == "virNetworkPortLookup":
1130 func = name[10:]
1131 func = func[0:1].lower() + func[1:]
1132 elif name[0:18] == "virInterfaceDefine":
1133 func = name[3:]
1134 func = func[0:1].lower() + func[1:]
1135 elif name[0:21] == "virInterfaceCreateXML":
1136 func = name[3:]
1137 func = func[0:1].lower() + func[1:]
1138 elif name[0:18] == "virInterfaceLookup":
1139 func = name[3:]
1140 func = func[0:1].lower() + func[1:]
1141 elif name[0:15] == "virSecretDefine":
1142 func = name[3:]
1143 func = func[0:1].lower() + func[1:]
1144 elif name[0:15] == "virSecretLookup":
1145 func = name[3:]
1146 func = func[0:1].lower() + func[1:]
1147 elif name[0:27] == "virNWFilterBindingCreateXML":
1148 func = name[3:]
1149 func = func[0:3].lower() + func[3:]
1150 elif name[0:24] == "virNWFilterBindingLookup":
1151 func = name[3:]
1152 func = func[0:3].lower() + func[3:]
1153 elif name[0:24] == "virNWFilterBindingDefine":
1154 func = name[3:]
1155 func = func[0:3].lower() + func[3:]
1156 elif name[0:24] == "virNWFilterBindingLookup":
1157 func = name[3:]
1158 func = func[0:3].lower() + func[3:]
1159 elif name[0:17] == "virNWFilterDefine":
1160 func = name[3:]
1161 func = func[0:3].lower() + func[3:]
1162 elif name[0:17] == "virNWFilterLookup":
1163 func = name[3:]
1164 func = func[0:3].lower() + func[3:]
1165 elif name[0:20] == "virStoragePoolDefine":
1166 func = name[3:]
1167 func = func[0:1].lower() + func[1:]
1168 elif name[0:23] == "virStoragePoolCreateXML":
1169 func = name[3:]
1170 func = func[0:1].lower() + func[1:]
1171 elif name[0:20] == "virStoragePoolLookup":
1172 func = name[3:]
1173 func = func[0:1].lower() + func[1:]
1174 elif name[0:19] == "virStorageVolDefine":
1175 func = name[3:]
1176 func = func[0:1].lower() + func[1:]
1177 elif name[0:19] == "virStorageVolLookup":
1178 func = name[3:]
1179 func = func[0:1].lower() + func[1:]
1180 elif name[0:20] == "virDomainGetCPUStats":
1181 func = name[9:]
1182 func = func[0:1].lower() + func[1:]
1183 elif name[0:24] == "virDomainGetIOThreadInfo":
1184 func = name[12:]
1185 func = func[0:2].lower() + func[2:]
1186 elif name[0:18] == "virDomainGetFSInfo":
1187 func = name[12:]
1188 func = func[0:2].lower() + func[2:]
1189 elif name[0:12] == "virDomainGet":
1190 func = name[12:]
1191 func = func[0:1].lower() + func[1:]
1192 elif name[0:29] == "virDomainSnapshotLookupByName":
1193 func = name[9:]
1194 func = func[0:1].lower() + func[1:]
1195 elif name[0:26] == "virDomainSnapshotListNames":
1196 func = name[9:]
1197 func = func[0:1].lower() + func[1:]
1198 elif name[0:28] == "virDomainSnapshotNumChildren":
1199 func = name[17:]
1200 func = func[0:1].lower() + func[1:]
1201 elif name[0:20] == "virDomainSnapshotNum":
1202 func = name[9:]
1203 func = func[0:1].lower() + func[1:]
1204 elif name[0:26] == "virDomainSnapshotCreateXML":
1205 func = name[9:]
1206 func = func[0:1].lower() + func[1:]
1207 elif name[0:24] == "virDomainSnapshotCurrent":
1208 func = name[9:]
1209 func = func[0:1].lower() + func[1:]
1210 elif name[0:17] == "virDomainSnapshot":
1211 func = name[17:]
1212 func = func[0:1].lower() + func[1:]
1213 elif name[0:9] == "virDomain":
1214 func = name[9:]
1215 func = func[0:1].lower() + func[1:]
1216 elif name[0:17] == "virNetworkPortGet":
1217 func = name[17:]
1218 func = func[0:1].lower() + func[1:]
1219 elif name[0:13] == "virNetworkGet":
1220 func = name[13:]
1221 func = func[0:1].lower() + func[1:]
1222 func = func.replace("dHCP", "DHCP")
1223 elif name[0:14] == "virNetworkPort":
1224 func = name[14:]
1225 func = func[0:1].lower() + func[1:]
1226 elif name[0:10] == "virNetwork":
1227 func = name[10:]
1228 func = func[0:1].lower() + func[1:]
1229 elif name[0:15] == "virInterfaceGet":
1230 func = name[15:]
1231 func = func[0:1].lower() + func[1:]
1232 elif name[0:12] == "virInterface":
1233 func = name[12:]
1234 func = func[0:1].lower() + func[1:]
1235 elif name[0:12] == 'virSecretGet':
1236 func = name[12:]
1237 func = func[0:1].lower() + func[1:]
1238 elif name[0:9] == 'virSecret':
1239 func = name[9:]
1240 func = func[0:1].lower() + func[1:]
1241 elif name[0:21] == 'virNWFilterBindingGet':
1242 func = name[21:]
1243 func = func[0:1].lower() + func[1:]
1244 elif name[0:18] == 'virNWFilterBinding':
1245 func = name[18:]
1246 func = func[0:1].lower() + func[1:]
1247 elif name[0:14] == 'virNWFilterGet':
1248 func = name[14:]
1249 func = func[0:1].lower() + func[1:]
1250 elif name[0:11] == 'virNWFilter':
1251 func = name[11:]
1252 func = func[0:1].lower() + func[1:]
1253 elif name[0:12] == 'virStreamNew':
1254 func = "newStream"
1255 elif name[0:9] == 'virStream':
1256 func = name[9:]
1257 func = func[0:1].lower() + func[1:]
1258 elif name[0:17] == "virStoragePoolGet":
1259 func = name[17:]
1260 func = func[0:1].lower() + func[1:]
1261 elif name[0:14] == "virStoragePool":
1262 func = name[14:]
1263 func = func[0:1].lower() + func[1:]
1264 elif name[0:16] == "virStorageVolGet":
1265 func = name[16:]
1266 func = func[0:1].lower() + func[1:]
1267 elif name[0:13] == "virStorageVol":
1268 func = name[13:]
1269 func = func[0:1].lower() + func[1:]
1270 elif name[0:13] == "virNodeDevice":
1271 if name[13:16] == "Get":
1272 func = name[16].lower() + name[17:]
1273 elif name[13:19] == "Lookup" or name[13:19] == "Create":
1274 func = name[3].lower() + name[4:]
1275 else:
1276 func = name[13].lower() + name[14:]
1277 elif name[0:7] == "virNode":
1278 func = name[7:]
1279 func = func[0:1].lower() + func[1:]
1280 elif name[0:10] == "virConnect":
1281 func = name[10:]
1282 func = func[0:1].lower() + func[1:]
1283 elif name[0:3] == "xml":
1284 func = name[3:]
1285 func = func[0:1].lower() + func[1:]
1286 else:
1287 func = name
1288 if func == "iD":
1289 func = "ID"
1290 if func == "uUID":
1291 func = "UUID"
1292 if func == "uUIDString":
1293 func = "UUIDString"
1294 if func == "oSType":
1295 func = "OSType"
1296 if func == "xMLDesc":
1297 func = "XMLDesc"
1298 if func == "mACString":
1299 func = "MACString"
1301 return func
1304 def functionSortKey(info):
1305 (index, func, name, ret, args, filename, mod) = info
1306 return func, filename
1308 def writeDoc(module, name, args, indent, output):
1309 if module == "libvirt":
1310 funcs = functions
1311 elif module == "libvirt-lxc":
1312 funcs = lxc_functions
1313 elif module == "libvirt-qemu":
1314 funcs = qemu_functions
1315 if funcs[name][0] is None or funcs[name][0] == "":
1316 return
1317 val = funcs[name][0]
1318 val = val.replace("NULL", "None")
1319 output.write(indent)
1320 output.write('"""')
1321 i = val.find("\n")
1322 while i >= 0:
1323 str = val[0:i+1]
1324 val = val[i+1:]
1325 output.write(str)
1326 i = val.find("\n")
1327 output.write(indent)
1328 output.write(val)
1329 output.write(' """\n')
1331 def buildWrappers(module):
1332 global ctypes
1333 global py_types
1334 global unknown_types
1335 global functions
1336 global function_classes
1337 global classes_type
1338 global classes_list
1339 global primary_classes
1340 global classes_destructors
1341 global functions_noexcept
1343 if not module == "libvirt":
1344 print("ERROR: Unknown module type: %s" % module)
1345 return None
1347 for type in list(classes_type.keys()):
1348 function_classes[classes_type[type][2]] = []
1351 # Build the list of C types to look for ordered to start
1352 # with primary classes
1354 ctypes = []
1355 classes_list = []
1356 ctypes_processed = {}
1357 classes_processed = {}
1358 for classe in primary_classes:
1359 classes_list.append(classe)
1360 classes_processed[classe] = ()
1361 for type in list(classes_type.keys()):
1362 tinfo = classes_type[type]
1363 if tinfo[2] == classe:
1364 ctypes.append(type)
1365 ctypes_processed[type] = ()
1366 for type in list(classes_type.keys()):
1367 if type in ctypes_processed:
1368 continue
1369 tinfo = classes_type[type]
1370 if tinfo[2] not in classes_processed:
1371 classes_list.append(tinfo[2])
1372 classes_processed[tinfo[2]] = ()
1374 ctypes.append(type)
1375 ctypes_processed[type] = ()
1377 for name in list(functions.keys()):
1378 found = 0
1379 (desc, ret, args, file, mod, cond) = functions[name]
1380 for type in ctypes:
1381 classe = classes_type[type][2]
1383 if name[0:3] == "vir" and len(args) >= 1 and args[0][1] == type:
1384 found = 1
1385 func = nameFixup(name, classe, type, file)
1386 info = (0, func, name, ret, args, file, mod)
1387 function_classes[classe].append(info)
1388 break
1389 elif name[0:3] == "vir" and len(args) >= 2 and args[1][1] == type \
1390 and file != "python_accessor" and not name in function_skip_index_one:
1391 found = 1
1392 func = nameFixup(name, classe, type, file)
1393 info = (1, func, name, ret, args, file, mod)
1394 function_classes[classe].append(info)
1395 break
1396 if found == 1:
1397 continue
1398 func = nameFixup(name, "None", file, file)
1399 info = (0, func, name, ret, args, file, mod)
1400 function_classes['None'].append(info)
1402 classes_file = "build/%s.py" % module
1403 extra_file = "%s-override.py" % module
1404 extra = None
1406 classes = open(classes_file, "w")
1408 if os.path.exists(extra_file):
1409 extra = open(extra_file, "r")
1410 classes.write("#\n")
1411 classes.write("# WARNING WARNING WARNING WARNING\n")
1412 classes.write("#\n")
1413 classes.write("# This file is automatically written by generator.py. Any changes\n")
1414 classes.write("# made here will be lost.\n")
1415 classes.write("#\n")
1416 classes.write("# To change the manually written methods edit " + module + "-override.py\n")
1417 classes.write("# To change the automatically written methods edit generator.py\n")
1418 classes.write("#\n")
1419 classes.write("# WARNING WARNING WARNING WARNING\n")
1420 classes.write("#\n")
1421 if extra is not None:
1422 classes.writelines(extra.readlines())
1423 classes.write("#\n")
1424 classes.write("# WARNING WARNING WARNING WARNING\n")
1425 classes.write("#\n")
1426 classes.write("# Automatically written part of python bindings for libvirt\n")
1427 classes.write("#\n")
1428 classes.write("# WARNING WARNING WARNING WARNING\n")
1429 if extra is not None:
1430 extra.close()
1432 if "None" in function_classes:
1433 flist = function_classes["None"]
1434 flist.sort(key=functionSortKey)
1435 oldfile = ""
1436 for info in flist:
1437 (index, func, name, ret, args, file, mod) = info
1438 if file != oldfile:
1439 classes.write("#\n# Functions from module %s\n#\n\n" % file)
1440 oldfile = file
1441 classes.write("def %s(" % func)
1442 n = 0
1443 for arg in args:
1444 if n != 0:
1445 classes.write(", ")
1446 classes.write("%s" % arg[0])
1447 if arg[0] == "flags" or is_optional_arg(arg[2]):
1448 if is_integral_type(arg[1]):
1449 classes.write("=0")
1450 else:
1451 classes.write("=None")
1452 n = n + 1
1453 classes.write("):\n")
1454 writeDoc(module, name, args, ' ', classes)
1456 for arg in args:
1457 if arg[1] in classes_type:
1458 classes.write(" if %s is None: %s__o = None\n" %
1459 (arg[0], arg[0]))
1460 classes.write(" else: %s__o = %s%s\n" %
1461 (arg[0], arg[0], classes_type[arg[1]][0]))
1462 if ret[0] != "void":
1463 classes.write(" ret = ")
1464 else:
1465 classes.write(" ")
1466 classes.write("libvirtmod.%s(" % name)
1467 n = 0
1468 for arg in args:
1469 if n != 0:
1470 classes.write(", ")
1471 classes.write("%s" % arg[0])
1472 if arg[1] in classes_type:
1473 classes.write("__o")
1474 n = n + 1
1475 classes.write(")\n")
1477 if ret[0] != "void":
1478 if ret[0] in classes_type:
1480 # Raise an exception
1482 if name in functions_noexcept:
1483 classes.write(" if ret is None:return None\n")
1484 else:
1485 classes.write(
1486 " if ret is None:raise libvirtError('%s() failed')\n" %
1487 (name))
1489 classes.write(" return ")
1490 classes.write(classes_type[ret[0]][1] % ("ret"))
1491 classes.write("\n")
1493 # For functions returning an integral type there are
1494 # several things that we can do, depending on the
1495 # contents of functions_int_*:
1496 elif is_integral_type (ret[0]):
1497 if name not in functions_noexcept:
1498 if name in functions_int_exception_test:
1499 test = functions_int_exception_test[name]
1500 else:
1501 test = functions_int_default_test
1502 classes.write ((" if " + test +
1503 ": raise libvirtError ('%s() failed')\n") %
1504 ("ret", name))
1505 classes.write(" return ret\n")
1507 elif is_python_noninteger_type (ret[0]):
1508 if name not in functions_noexcept:
1509 classes.write ((" if %s is None" +
1510 ": raise libvirtError ('%s() failed')\n") %
1511 ("ret", name))
1512 classes.write(" return ret\n")
1514 else:
1515 classes.write(" return ret\n")
1517 classes.write("\n")
1519 for classname in classes_list:
1520 if classname == "None":
1521 pass
1522 else:
1523 classes.write("class %s(object):\n" % (classname))
1524 if classname in [ "virDomain", "virNetwork", "virInterface", "virStoragePool",
1525 "virStorageVol", "virNodeDevice", "virSecret","virStream",
1526 "virNWFilter", "virNWFilterBinding" ]:
1527 classes.write(" def __init__(self, conn, _obj=None):\n")
1528 elif classname in [ 'virDomainSnapshot' ]:
1529 classes.write(" def __init__(self, dom, _obj=None):\n")
1530 else:
1531 classes.write(" def __init__(self, _obj=None):\n")
1532 if classname in [ "virDomain", "virNetwork", "virInterface",
1533 "virNodeDevice", "virSecret", "virStream",
1534 "virNWFilter", "virNWFilterBinding" ]:
1535 classes.write(" self._conn = conn\n")
1536 elif classname in [ "virStorageVol", "virStoragePool" ]:
1537 classes.write(" self._conn = conn\n" + \
1538 " if not isinstance(conn, virConnect):\n" + \
1539 " self._conn = conn._conn\n")
1540 elif classname in [ "virDomainSnapshot" ]:
1541 classes.write(" self._dom = dom\n")
1542 classes.write(" self._conn = dom.connect()\n")
1543 classes.write(" if type(_obj).__name__ not in [\"PyCapsule\", \"PyCObject\"]:\n")
1544 classes.write(" raise Exception(\"Expected a wrapped C Object but got %s\" % type(_obj))\n")
1545 classes.write(" self._o = _obj\n\n")
1546 destruct=None
1547 if classname in classes_destructors:
1548 classes.write(" def __del__(self):\n")
1549 classes.write(" if self._o is not None:\n")
1550 classes.write(" libvirtmod.%s(self._o)\n" %
1551 classes_destructors[classname])
1552 classes.write(" self._o = None\n\n")
1553 destruct=classes_destructors[classname]
1555 if classname not in class_skip_connect_impl:
1556 # Build python safe 'connect' method
1557 classes.write(" def connect(self):\n")
1558 classes.write(" return self._conn\n\n")
1560 if classname in class_domain_impl:
1561 classes.write(" def domain(self):\n")
1562 classes.write(" return self._dom\n\n")
1564 classes.write(" def c_pointer(self):\n")
1565 classes.write(" \"\"\"Get C pointer to underlying object\"\"\"\n")
1566 classes.write(" return libvirtmod.%s_pointer(self._o)\n\n" %
1567 classname)
1569 flist = function_classes[classname]
1570 flist.sort(key=functionSortKey)
1571 oldfile = ""
1572 for info in flist:
1573 (index, func, name, ret, args, file, mod) = info
1575 # Do not provide as method the destructors for the class
1576 # to avoid double free
1578 if name == destruct:
1579 continue
1580 if file != oldfile:
1581 if file == "python_accessor":
1582 classes.write(" # accessors for %s\n" % (classname))
1583 else:
1584 classes.write(" #\n")
1585 classes.write(" # %s functions from module %s\n" % (
1586 classname, file))
1587 classes.write(" #\n\n")
1588 oldfile = file
1589 classes.write(" def %s(self" % func)
1590 n = 0
1591 for arg in args:
1592 if n != index:
1593 classes.write(", %s" % arg[0])
1594 if arg[0] == "flags" or is_optional_arg(arg[2]):
1595 if is_integral_type(arg[1]):
1596 classes.write("=0")
1597 else:
1598 classes.write("=None")
1599 n = n + 1
1600 classes.write("):\n")
1601 writeDoc(module, name, args, ' ', classes)
1602 n = 0
1603 for arg in args:
1604 if arg[1] in classes_type:
1605 if n != index:
1606 classes.write(" if %s is None: %s__o = None\n" %
1607 (arg[0], arg[0]))
1608 classes.write(" else: %s__o = %s%s\n" %
1609 (arg[0], arg[0], classes_type[arg[1]][0]))
1610 n = n + 1
1611 if ret[0] != "void":
1612 classes.write(" ret = ")
1613 else:
1614 classes.write(" ")
1615 n = 0
1616 classes.write("libvirtmod.%s(" % name)
1617 for arg in args:
1618 if n != 0:
1619 classes.write(", ")
1620 if n != index:
1621 classes.write("%s" % arg[0])
1622 if arg[1] in classes_type:
1623 classes.write("__o")
1624 else:
1625 classes.write("self")
1626 if arg[1] in classes_type:
1627 classes.write(classes_type[arg[1]][0])
1628 n = n + 1
1629 classes.write(")\n")
1631 if name == "virConnectClose":
1632 classes.write(" self._o = None\n")
1634 # For functions returning object types:
1635 if ret[0] != "void":
1636 if ret[0] in classes_type:
1638 # Raise an exception
1640 if name in functions_noexcept:
1641 classes.write(
1642 " if ret is None:return None\n")
1643 else:
1644 if classname == "virConnect":
1645 classes.write(
1646 " if ret is None:raise libvirtError('%s() failed', conn=self)\n" %
1647 (name))
1648 elif classname == "virDomain":
1649 classes.write(
1650 " if ret is None:raise libvirtError('%s() failed', dom=self)\n" %
1651 (name))
1652 elif classname == "virNetwork":
1653 classes.write(
1654 " if ret is None:raise libvirtError('%s() failed', net=self)\n" %
1655 (name))
1656 elif classname == "virInterface":
1657 classes.write(
1658 " if ret is None:raise libvirtError('%s() failed', net=self)\n" %
1659 (name))
1660 elif classname == "virStoragePool":
1661 classes.write(
1662 " if ret is None:raise libvirtError('%s() failed', pool=self)\n" %
1663 (name))
1664 elif classname == "virStorageVol":
1665 classes.write(
1666 " if ret is None:raise libvirtError('%s() failed', vol=self)\n" %
1667 (name))
1668 elif classname == "virDomainSnapshot":
1669 classes.write(
1670 " if ret is None:raise libvirtError('%s() failed', dom=self._dom)\n" %
1671 (name))
1672 else:
1673 classes.write(
1674 " if ret is None:raise libvirtError('%s() failed')\n" %
1675 (name))
1678 # generate the returned class wrapper for the object
1680 classes.write(" __tmp = ")
1681 classes.write(classes_type[ret[0]][1] % ("ret"))
1682 classes.write("\n")
1685 # return the class
1687 classes.write(" return __tmp\n")
1689 # For functions returning an integral type there
1690 # are several things that we can do, depending on
1691 # the contents of functions_int_*:
1692 elif is_integral_type (ret[0]):
1693 if name not in functions_noexcept:
1694 if name in functions_int_exception_test:
1695 test = functions_int_exception_test[name]
1696 else:
1697 test = functions_int_default_test
1698 if classname == "virConnect":
1699 classes.write ((" if " + test +
1700 ": raise libvirtError ('%s() failed', conn=self)\n") %
1701 ("ret", name))
1702 elif classname == "virDomain":
1703 classes.write ((" if " + test +
1704 ": raise libvirtError ('%s() failed', dom=self)\n") %
1705 ("ret", name))
1706 elif classname == "virNetwork":
1707 classes.write ((" if " + test +
1708 ": raise libvirtError ('%s() failed', net=self)\n") %
1709 ("ret", name))
1710 elif classname == "virInterface":
1711 classes.write ((" if " + test +
1712 ": raise libvirtError ('%s() failed', net=self)\n") %
1713 ("ret", name))
1714 elif classname == "virStoragePool":
1715 classes.write ((" if " + test +
1716 ": raise libvirtError ('%s() failed', pool=self)\n") %
1717 ("ret", name))
1718 elif classname == "virStorageVol":
1719 classes.write ((" if " + test +
1720 ": raise libvirtError ('%s() failed', vol=self)\n") %
1721 ("ret", name))
1722 else:
1723 classes.write ((" if " + test +
1724 ": raise libvirtError ('%s() failed')\n") %
1725 ("ret", name))
1727 classes.write (" return ret\n")
1729 elif is_python_noninteger_type (ret[0]):
1730 if name not in functions_noexcept:
1731 if classname == "virConnect":
1732 classes.write ((" if %s is None" +
1733 ": raise libvirtError ('%s() failed', conn=self)\n") %
1734 ("ret", name))
1735 elif classname == "virDomain":
1736 classes.write ((" if %s is None" +
1737 ": raise libvirtError ('%s() failed', dom=self)\n") %
1738 ("ret", name))
1739 elif classname == "virNetwork":
1740 classes.write ((" if %s is None" +
1741 ": raise libvirtError ('%s() failed', net=self)\n") %
1742 ("ret", name))
1743 elif classname == "virInterface":
1744 classes.write ((" if %s is None" +
1745 ": raise libvirtError ('%s() failed', net=self)\n") %
1746 ("ret", name))
1747 elif classname == "virStoragePool":
1748 classes.write ((" if %s is None" +
1749 ": raise libvirtError ('%s() failed', pool=self)\n") %
1750 ("ret", name))
1751 elif classname == "virStorageVol":
1752 classes.write ((" if %s is None" +
1753 ": raise libvirtError ('%s() failed', vol=self)\n") %
1754 ("ret", name))
1755 else:
1756 classes.write ((" if %s is None" +
1757 ": raise libvirtError ('%s() failed')\n") %
1758 ("ret", name))
1760 classes.write (" return ret\n")
1761 else:
1762 classes.write(" return ret\n")
1764 classes.write("\n")
1765 # Append "<classname>.py" to class def, iff it exists
1766 try:
1767 wantfuncs = []
1768 extra = open("libvirt-override-" + classname + ".py", "r")
1769 classes.write (" #\n")
1770 classes.write (" # %s methods from %s.py (hand coded)\n" % (classname,classname))
1771 classes.write (" #\n")
1772 cached = None
1775 # Since we compile with older libvirt, we don't want to pull
1776 # in manually written python methods which call C methods
1777 # that don't exist. This code attempts to detect which
1778 # methods to skip by looking at the libvirtmod.XXXX calls
1780 def shouldSkip(lines):
1781 for line in lines:
1782 offset = line.find("libvirtmod.")
1783 if offset != -1:
1784 func = line[offset + 11:]
1785 offset = func.find("(")
1786 func = func[0:offset]
1787 if func not in functions_skipped:
1788 return True
1789 return False
1791 for line in extra.readlines():
1792 offset = line.find(" def ")
1793 if offset != -1:
1794 name = line[offset+5:]
1795 offset = name.find("(")
1796 name = name[0:offset]
1797 if cached is not None:
1798 if not shouldSkip(cached):
1799 classes.writelines(cached)
1800 if name == "__del__":
1801 cached = None
1802 classes.write(line)
1803 else:
1804 cached = [line]
1805 else:
1806 if cached is not None:
1807 cached.append(line)
1808 else:
1809 classes.write(line)
1810 if not shouldSkip(cached):
1811 classes.writelines(cached)
1812 classes.write("\n")
1813 extra.close()
1814 except:
1815 pass
1818 # Generate enum constants
1820 def enumsSortKey(data):
1821 value = data[1]
1822 try:
1823 value = int(value)
1824 except ValueError:
1825 value = float('inf')
1826 return value, data[0]
1828 # Resolve only one level of reference
1829 def resolveEnum(enum, data):
1830 for name,val in enum.items():
1831 try:
1832 int(val)
1833 except ValueError:
1834 enum[name] = data[val]
1835 return enum
1837 enumvals = list(enums.items())
1838 # convert list of dicts to one dict
1839 enumData = {}
1840 for type,enum in enumvals:
1841 enumData.update(enum)
1843 if enumvals is not None:
1844 enumvals.sort(key=lambda x: x[0])
1845 for type,enum in enumvals:
1846 classes.write("# %s\n" % type)
1847 items = list(resolveEnum(enum, enumData).items())
1848 items.sort(key=enumsSortKey)
1849 if items[-1][0].endswith('_LAST'):
1850 del items[-1]
1851 for name,value in items:
1852 classes.write("%s = %s\n" % (name,value))
1853 classes.write("\n")
1855 classes.write("# typed parameter names\n")
1856 for name, value in params:
1857 classes.write("%s = \"%s\"\n" % (name, value))
1859 classes.close()
1861 def qemuBuildWrappers(module):
1862 global qemu_functions
1864 if not module == "libvirt-qemu":
1865 print("ERROR: only libvirt-qemu is supported")
1866 return None
1868 extra_file = "%s-override.py" % module
1869 extra = None
1871 fd = open("build/libvirt_qemu.py", "w")
1873 if os.path.exists(extra_file):
1874 extra = open(extra_file, "r")
1875 fd.write("#\n")
1876 fd.write("# WARNING WARNING WARNING WARNING\n")
1877 fd.write("#\n")
1878 fd.write("# This file is automatically written by generator.py. Any changes\n")
1879 fd.write("# made here will be lost.\n")
1880 fd.write("#\n")
1881 fd.write("# To change the manually written methods edit " + module + "-override.py\n")
1882 fd.write("# To change the automatically written methods edit generator.py\n")
1883 fd.write("#\n")
1884 fd.write("# WARNING WARNING WARNING WARNING\n")
1885 fd.write("#\n")
1886 fd.write("# Automatically written part of python bindings for libvirt\n")
1887 fd.write("#\n")
1889 fd.write("import sys\n")
1891 fd.write("try:\n")
1892 fd.write(" import libvirtmod_qemu\n")
1893 fd.write("except ImportError:\n")
1894 fd.write(" lib_e = sys.exc_info()[1]\n")
1895 fd.write(" try:\n")
1896 fd.write(" import cygvirtmod_qemu as libvirtmod_qemu\n")
1897 fd.write(" except ImportError:\n")
1898 fd.write(" cyg_e = sys.exc_info()[1]\n")
1899 fd.write(" if str(cyg_e).count(\"No module named\"):\n")
1900 fd.write(" raise lib_e\n\n")
1902 fd.write("import libvirt\n\n")
1903 fd.write("# WARNING WARNING WARNING WARNING\n")
1904 fd.write("#\n")
1905 if extra is not None:
1906 fd.writelines(extra.readlines())
1907 fd.write("#\n")
1908 if extra is not None:
1909 extra.close()
1911 fd.write("# WARNING WARNING WARNING WARNING\n")
1912 fd.write("#\n")
1913 fd.write("#\n# Functions from module %s\n#\n\n" % module)
1915 # Generate functions directly, no classes
1917 for name in sorted(qemu_functions.keys()):
1918 func = nameFixup(name, 'None', None, None)
1919 (desc, ret, args, file, mod, cond) = qemu_functions[name]
1920 fd.write("def %s(" % func)
1921 n = 0
1922 for arg in args:
1923 if n != 0:
1924 fd.write(", ")
1925 fd.write("%s" % arg[0])
1926 n = n + 1
1927 fd.write("):\n")
1928 writeDoc(module, name, args, ' ', fd)
1930 if ret[0] != "void":
1931 fd.write(" ret = ")
1932 else:
1933 fd.write(" ")
1934 fd.write("libvirtmod_qemu.%s(" % name)
1935 n = 0
1937 conn = None
1939 for arg in args:
1940 if arg[1] == "virConnectPtr":
1941 conn = arg[0]
1943 if n != 0:
1944 fd.write(", ")
1945 if arg[1] in ["virDomainPtr", "virConnectPtr"]:
1946 # FIXME: This might have problem if the function
1947 # has multiple args which are objects.
1948 fd.write("%s.%s" % (arg[0], "_o"))
1949 else:
1950 fd.write("%s" % arg[0])
1951 n = n + 1
1952 fd.write(")\n")
1954 if ret[0] != "void":
1955 fd.write(" if ret is None: raise libvirt.libvirtError('" + name + "() failed')\n")
1956 if ret[0] == "virDomainPtr":
1957 fd.write(" __tmp = libvirt.virDomain(" + conn + ", _obj=ret)\n")
1958 fd.write(" return __tmp\n")
1959 else:
1960 fd.write(" return ret\n")
1962 fd.write("\n")
1965 # Generate enum constants
1967 for type,enum in sorted(qemu_enums.items()):
1968 fd.write("# %s\n" % type)
1969 items = list(enum.items())
1970 items.sort(key=lambda i: (int(i[1]), i[0]))
1971 for name,value in items:
1972 fd.write("%s = %s\n" % (name,value))
1973 fd.write("\n")
1975 fd.close()
1978 def lxcBuildWrappers(module):
1979 global lxc_functions
1981 if not module == "libvirt-lxc":
1982 print("ERROR: only libvirt-lxc is supported")
1983 return None
1985 extra_file = "%s-override.py" % module
1986 extra = None
1988 fd = open("build/libvirt_lxc.py", "w")
1990 if os.path.exists(extra_file):
1991 extra = open(extra_file, "r")
1992 fd.write("#\n")
1993 fd.write("# WARNING WARNING WARNING WARNING\n")
1994 fd.write("#\n")
1995 fd.write("# This file is automatically written by generator.py. Any changes\n")
1996 fd.write("# made here will be lost.\n")
1997 fd.write("#\n")
1998 fd.write("# To change the manually written methods edit " + module + "-override.py\n")
1999 fd.write("# To change the automatically written methods edit generator.py\n")
2000 fd.write("#\n")
2001 fd.write("# WARNING WARNING WARNING WARNING\n")
2002 fd.write("#\n")
2003 if extra is not None:
2004 fd.writelines(extra.readlines())
2005 fd.write("#\n")
2006 fd.write("# WARNING WARNING WARNING WARNING\n")
2007 fd.write("#\n")
2008 fd.write("# Automatically written part of python bindings for libvirt\n")
2009 fd.write("#\n")
2010 fd.write("# WARNING WARNING WARNING WARNING\n")
2011 if extra is not None:
2012 extra.close()
2014 fd.write("import sys\n")
2016 fd.write("try:\n")
2017 fd.write(" import libvirtmod_lxc\n")
2018 fd.write("except ImportError:\n")
2019 fd.write(" lib_e = sys.exc_info()[1]\n")
2020 fd.write(" try:\n")
2021 fd.write(" import cygvirtmod_lxc as libvirtmod_lxc\n")
2022 fd.write(" except ImportError:\n")
2023 fd.write(" cyg_e = sys.exc_info()[1]\n")
2024 fd.write(" if str(cyg_e).count(\"No module named\"):\n")
2025 fd.write(" raise lib_e\n\n")
2027 fd.write("import libvirt\n\n")
2028 fd.write("#\n# Functions from module %s\n#\n\n" % module)
2030 # Generate functions directly, no classes
2032 for name in sorted(lxc_functions.keys()):
2033 func = nameFixup(name, 'None', None, None)
2034 (desc, ret, args, file, mod, cond) = lxc_functions[name]
2035 fd.write("def %s(" % func)
2036 n = 0
2037 for arg in args:
2038 if n != 0:
2039 fd.write(", ")
2040 fd.write("%s" % arg[0])
2041 n = n + 1
2042 fd.write("):\n")
2043 writeDoc(module, name, args, ' ', fd)
2045 if ret[0] != "void":
2046 fd.write(" ret = ")
2047 else:
2048 fd.write(" ")
2049 fd.write("libvirtmod_lxc.%s(" % name)
2050 n = 0
2052 conn = None
2054 for arg in args:
2055 if arg[1] == "virConnectPtr":
2056 conn = arg[0]
2058 if n != 0:
2059 fd.write(", ")
2060 if arg[1] in ["virDomainPtr", "virConnectPtr"]:
2061 # FIXME: This might have problem if the function
2062 # has multiple args which are objects.
2063 fd.write("%s.%s" % (arg[0], "_o"))
2064 else:
2065 fd.write("%s" % arg[0])
2066 n = n + 1
2067 fd.write(")\n")
2069 if ret[0] != "void":
2070 fd.write(" if ret is None: raise libvirt.libvirtError('" + name + "() failed')\n")
2071 if ret[0] == "virDomainPtr":
2072 fd.write(" __tmp = libvirt.virDomain(" + conn + ", _obj=ret)\n")
2073 fd.write(" return __tmp\n")
2074 else:
2075 fd.write(" return ret\n")
2077 fd.write("\n")
2080 # Generate enum constants
2082 for type,enum in sorted(lxc_enums.items()):
2083 fd.write("# %s\n" % type)
2084 items = list(enum.items())
2085 items.sort(key=lambda i: (int(i[1]), i[0]))
2086 for name,value in items:
2087 fd.write("%s = %s\n" % (name,value))
2088 fd.write("\n")
2090 fd.close()
2093 quiet = 0
2094 if not os.path.exists("build"):
2095 os.mkdir("build")
2097 if buildStubs(sys.argv[1], sys.argv[2]) < 0:
2098 sys.exit(1)
2100 if sys.argv[1] == "libvirt":
2101 buildWrappers(sys.argv[1])
2102 elif sys.argv[1] == "libvirt-lxc":
2103 lxcBuildWrappers(sys.argv[1])
2104 elif sys.argv[1] == "libvirt-qemu":
2105 qemuBuildWrappers(sys.argv[1])
2106 else:
2107 print("ERROR: unknown module %s" % sys.argv[1])
2108 sys.exit(1)
2110 sys.exit(0)