3 # generate python wrappers from the XML API description
7 enums
= {} # { enumType: { enumConstant: enumValue } }
14 if __name__
== "__main__":
15 # launched as a script
16 srcPref
= os
.path
.dirname(sys
.argv
[0])
19 srcPref
= os
.path
.dirname(__file__
)
21 #######################################################################
23 # That part if purely the API acquisition phase from the
24 # libvirt API description
26 #######################################################################
33 # Attach parser to an unmarshalling object. return both objects.
35 parser
= xml
.sax
.make_parser()
36 parser
.setContentHandler(target
)
39 class docParser(xml
.sax
.handler
.ContentHandler
):
41 self
._methodname
= None
45 self
.startElement
= self
.start
46 self
.endElement
= self
.end
47 self
.characters
= self
.data
53 def getmethodname(self
):
54 return self
._methodname
58 print "data %s" % text
59 self
._data
.append(text
)
61 def cdata(self
, text
):
63 print "data %s" % text
64 self
._data
.append(text
)
66 def start(self
, tag
, attrs
):
68 print "start %s, %s" % (tag
, attrs
)
73 self
.function_cond
= None
74 self
.function_args
= []
75 self
.function_descr
= None
76 self
.function_return
= None
77 self
.function_file
= None
78 if attrs
.has_key('name'):
79 self
.function
= attrs
['name']
80 if attrs
.has_key('file'):
81 self
.function_file
= attrs
['file']
87 if self
.in_function
== 1:
88 self
.function_arg_name
= None
89 self
.function_arg_type
= None
90 self
.function_arg_info
= None
91 if attrs
.has_key('name'):
92 self
.function_arg_name
= attrs
['name']
93 if self
.function_arg_name
== 'from':
94 self
.function_arg_name
= 'frm'
95 if attrs
.has_key('type'):
96 self
.function_arg_type
= attrs
['type']
97 if attrs
.has_key('info'):
98 self
.function_arg_info
= attrs
['info']
100 if self
.in_function
== 1:
101 self
.function_return_type
= None
102 self
.function_return_info
= None
103 self
.function_return_field
= None
104 if attrs
.has_key('type'):
105 self
.function_return_type
= attrs
['type']
106 if attrs
.has_key('info'):
107 self
.function_return_info
= attrs
['info']
108 if attrs
.has_key('field'):
109 self
.function_return_field
= attrs
['field']
111 enum(attrs
['type'],attrs
['name'],attrs
['value'])
116 if tag
== 'function':
117 if self
.function
!= None:
118 function(self
.function
, self
.function_descr
,
119 self
.function_return
, self
.function_args
,
120 self
.function_file
, self
.function_cond
)
123 if self
.in_function
== 1:
124 self
.function_args
.append([self
.function_arg_name
,
125 self
.function_arg_type
,
126 self
.function_arg_info
])
127 elif tag
== 'return':
128 if self
.in_function
== 1:
129 self
.function_return
= [self
.function_return_type
,
130 self
.function_return_info
,
131 self
.function_return_field
]
136 if self
.in_function
== 1:
137 self
.function_descr
= str
142 if self
.in_function
== 1:
143 self
.function_cond
= str
146 def function(name
, desc
, ret
, args
, file, cond
):
147 functions
[name
] = (desc
, ret
, args
, file, cond
)
149 def enum(type, name
, value
):
150 if not enums
.has_key(type):
152 enums
[type][name
] = value
154 #######################################################################
156 # Some filtering rukes to drop functions/types which should not
157 # be exposed as-is on the Python interface
159 #######################################################################
161 functions_failed
= []
162 functions_skipped
= [
163 "virConnectListDomains"
170 # 'int *': "usually a return type",
171 'virConnectDomainEventCallback': "No function types in python",
172 'virEventAddHandleFunc': "No function types in python",
175 #######################################################################
177 # Table of remapping to/from the python type or class to the C
180 #######################################################################
183 'void': (None, None, None, None),
184 'int': ('i', None, "int", "int"),
185 'long': ('l', None, "long", "long"),
186 'double': ('d', None, "double", "double"),
187 'unsigned int': ('i', None, "int", "int"),
188 'unsigned long': ('l', None, "long", "long"),
189 'unsigned long long': ('l', None, "longlong", "long long"),
190 'unsigned char *': ('z', None, "charPtr", "char *"),
191 'char *': ('z', None, "charPtr", "char *"),
192 'const char *': ('z', None, "charPtrConst", "const char *"),
194 'virDomainPtr': ('O', "virDomain", "virDomainPtr", "virDomainPtr"),
195 'const virDomainPtr': ('O', "virDomain", "virDomainPtr", "virDomainPtr"),
196 'virDomain *': ('O', "virDomain", "virDomainPtr", "virDomainPtr"),
197 'const virDomain *': ('O', "virDomain", "virDomainPtr", "virDomainPtr"),
199 'virNetworkPtr': ('O', "virNetwork", "virNetworkPtr", "virNetworkPtr"),
200 'const virNetworkPtr': ('O', "virNetwork", "virNetworkPtr", "virNetworkPtr"),
201 'virNetwork *': ('O', "virNetwork", "virNetworkPtr", "virNetworkPtr"),
202 'const virNetwork *': ('O', "virNetwork", "virNetworkPtr", "virNetworkPtr"),
204 'virInterfacePtr': ('O', "virInterface", "virInterfacePtr", "virInterfacePtr"),
205 'const virInterfacePtr': ('O', "virInterface", "virInterfacePtr", "virInterfacePtr"),
206 'virInterface *': ('O', "virInterface", "virInterfacePtr", "virInterfacePtr"),
207 'const virInterface *': ('O', "virInterface", "virInterfacePtr", "virInterfacePtr"),
209 'virStoragePoolPtr': ('O', "virStoragePool", "virStoragePoolPtr", "virStoragePoolPtr"),
210 'const virStoragePoolPtr': ('O', "virStoragePool", "virStoragePoolPtr", "virStoragePoolPtr"),
211 'virStoragePool *': ('O', "virStoragePool", "virStoragePoolPtr", "virStoragePoolPtr"),
212 'const virStoragePool *': ('O', "virStoragePool", "virStoragePoolPtr", "virStoragePoolPtr"),
214 'virStorageVolPtr': ('O', "virStorageVol", "virStorageVolPtr", "virStorageVolPtr"),
215 'const virStorageVolPtr': ('O', "virStorageVol", "virStorageVolPtr", "virStorageVolPtr"),
216 'virStorageVol *': ('O', "virStorageVol", "virStorageVolPtr", "virStorageVolPtr"),
217 'const virStorageVol *': ('O', "virStorageVol", "virStorageVolPtr", "virStorageVolPtr"),
219 'virConnectPtr': ('O', "virConnect", "virConnectPtr", "virConnectPtr"),
220 'const virConnectPtr': ('O', "virConnect", "virConnectPtr", "virConnectPtr"),
221 'virConnect *': ('O', "virConnect", "virConnectPtr", "virConnectPtr"),
222 'const virConnect *': ('O', "virConnect", "virConnectPtr", "virConnectPtr"),
224 'virNodeDevicePtr': ('O', "virNodeDevice", "virNodeDevicePtr", "virNodeDevicePtr"),
225 'const virNodeDevicePtr': ('O', "virNodeDevice", "virNodeDevicePtr", "virNodeDevicePtr"),
226 'virNodeDevice *': ('O', "virNodeDevice", "virNodeDevicePtr", "virNodeDevicePtr"),
227 'const virNodeDevice *': ('O', "virNodeDevice", "virNodeDevicePtr", "virNodeDevicePtr"),
229 'virSecretPtr': ('O', "virSecret", "virSecretPtr", "virSecretPtr"),
230 'const virSecretPtr': ('O', "virSecret", "virSecretPtr", "virSecretPtr"),
231 'virSecret *': ('O', "virSecret", "virSecretPtr", "virSecretPtr"),
232 'const virSecret *': ('O', "virSecret", "virSecretPtr", "virSecretPtr"),
234 'virStreamPtr': ('O', "virStream", "virStreamPtr", "virStreamPtr"),
235 'const virStreamPtr': ('O', "virStream", "virStreamPtr", "virStreamPtr"),
236 'virStream *': ('O', "virStream", "virStreamPtr", "virStreamPtr"),
237 'const virStream *': ('O', "virStream", "virStreamPtr", "virStreamPtr"),
245 foreign_encoding_args
= (
248 #######################################################################
250 # This part writes the C <-> Python stubs libvirt.[ch] and
251 # the table libvirt-export.c to add when registrering the Python module
253 #######################################################################
255 # Class methods which are written by hand in libvir.c but the Python-level
256 # code is still automatically generated (so they are not in skip_function()).
258 'virConnectListDomainsID',
259 'virConnectListDefinedDomains',
260 'virConnectListNetworks',
261 'virConnectListDefinedNetworks',
262 'virConnectListInterfaces',
263 'virConnectListDefinedInterfaces',
264 'virConnectListSecrets',
265 'virConnectListStoragePools',
266 'virConnectListDefinedStoragePools',
267 'virConnectListStorageVols',
268 'virConnectListDefinedStorageVols',
269 'virConnGetLastError',
274 'virDomainGetUUIDString',
275 'virDomainLookupByUUID',
277 'virNetworkGetUUIDString',
278 'virNetworkLookupByUUID',
279 'virDomainGetAutostart',
280 'virNetworkGetAutostart',
281 'virDomainBlockStats',
282 'virDomainInterfaceStats',
283 'virNodeGetCellsFreeMemory',
284 'virDomainGetSchedulerType',
285 'virDomainGetSchedulerParameters',
286 'virDomainSetSchedulerParameters',
292 'virSecretGetUUIDString',
293 'virSecretLookupByUUID',
296 'virStoragePoolGetUUID',
297 'virStoragePoolGetUUIDString',
298 'virStoragePoolLookupByUUID',
299 'virStoragePoolGetInfo',
300 'virStorageVolGetInfo',
301 'virStoragePoolGetAutostart',
302 'virStoragePoolListVolumes',
303 'virDomainBlockPeek',
304 'virDomainMemoryPeek',
305 'virEventRegisterImpl',
306 'virNodeListDevices',
307 'virNodeDeviceListCaps',
311 # These are functions which the generator skips completly - no python
312 # or C code is generated. Generally should not be used for any more
313 # functions than those already listed
315 'virConnectListDomains', # Python API is called virConectListDomainsID for unknown reasons
316 'virConnSetErrorFunc', # Not used in Python API XXX is this a bug ?
317 'virResetError', # Not used in Python API XXX is this a bug ?
318 'virConnectGetVersion', # Not used in Python API XXX is this a bug ?
319 'virGetVersion', # Python C code is manually written
320 'virSetErrorFunc', # Python API is called virRegisterErrorHandler for unknown reasons
321 'virConnCopyLastError', # Python API is called virConnGetLastError instead
322 'virCopyLastError', # Python API is called virGetLastError instead
323 'virConnectOpenAuth', # Python C code is manually written
324 'virDefaultErrorFunc', # Python virErrorFuncHandler impl calls this from C
325 'virDomainGetSecurityLabel', # Needs investigation...
326 'virNodeGetSecurityModel', # Needs investigation...
327 'virConnectDomainEventRegister', # overridden in virConnect.py
328 'virConnectDomainEventDeregister', # overridden in virConnect.py
329 'virSaveLastError', # We have our own python error wrapper
330 'virFreeError', # Only needed if we use virSaveLastError
331 'virStreamEventAddCallback',
337 # These have no use for bindings users.
347 # This functions shouldn't be called via the bindings (and even the docs
348 # contain an explicit warning to that effect). The equivalent should be
349 # implemented in pure python for each class
350 "virDomainGetConnect",
351 "virInterfaceGetConnect",
352 "virNetworkGetConnect",
353 "virSecretGetConnect",
354 "virStoragePoolGetConnect",
355 "virStorageVolGetConnect",
359 def print_function_wrapper(name
, output
, export
, include
):
363 global skipped_modules
366 (desc
, ret
, args
, file, cond
) = functions
[name
]
368 print "failed to get function %s infos"
371 if skipped_modules
.has_key(file):
373 if name
in skip_function
:
375 if name
in skip_impl
:
376 # Don't delete the function entry in the caller.
387 # This should be correct
388 if arg
[1][0:6] == "const ":
390 c_args
= c_args
+ " %s %s;\n" % (arg
[1], arg
[0])
391 if py_types
.has_key(arg
[1]):
392 (f
, t
, n
, c
) = py_types
[arg
[1]]
393 if (f
== 'z') and (name
in foreign_encoding_args
) and (num_bufs
== 0):
398 format_args
= format_args
+ ", &pyobj_%s" % (arg
[0])
399 c_args
= c_args
+ " PyObject *pyobj_%s;\n" % (arg
[0])
400 c_convert
= c_convert
+ \
401 " %s = (%s) Py%s_Get(pyobj_%s);\n" % (arg
[0],
404 format_args
= format_args
+ ", &%s" % (arg
[0])
406 format_args
= format_args
+ ", &py_buffsize%d" % num_bufs
407 c_args
= c_args
+ " int py_buffsize%d;\n" % num_bufs
408 num_bufs
= num_bufs
+ 1
410 c_call
= c_call
+ ", ";
411 c_call
= c_call
+ "%s" % (arg
[0])
413 if skipped_types
.has_key(arg
[1]):
415 if unknown_types
.has_key(arg
[1]):
416 lst
= unknown_types
[arg
[1]]
419 unknown_types
[arg
[1]] = [name
]
422 format
= format
+ ":%s" % (name
)
425 if file == "python_accessor":
426 if args
[1][1] == "char *":
427 c_call
= "\n free(%s->%s);\n" % (
428 args
[0][0], args
[1][0], args
[0][0], args
[1][0])
429 c_call
= c_call
+ " %s->%s = (%s)strdup((const xmlChar *)%s);\n" % (args
[0][0],
430 args
[1][0], args
[1][1], args
[1][0])
432 c_call
= "\n %s->%s = %s;\n" % (args
[0][0], args
[1][0],
435 c_call
= "\n %s(%s);\n" % (name
, c_call
);
436 ret_convert
= " Py_INCREF(Py_None);\n return(Py_None);\n"
437 elif py_types
.has_key(ret
[0]):
438 (f
, t
, n
, c
) = py_types
[ret
[0]]
439 c_return
= " %s c_retval;\n" % (ret
[0])
440 if file == "python_accessor" and ret
[2] != None:
441 c_call
= "\n c_retval = %s->%s;\n" % (args
[0][0], ret
[2])
443 c_call
= "\n c_retval = %s(%s);\n" % (name
, c_call
);
444 ret_convert
= " py_retval = libvirt_%sWrap((%s) c_retval);\n" % (n
,c
)
445 ret_convert
= ret_convert
+ " return(py_retval);\n"
446 elif py_return_types
.has_key(ret
[0]):
447 (f
, t
, n
, c
) = py_return_types
[ret
[0]]
448 c_return
= " %s c_retval;\n" % (ret
[0])
449 c_call
= "\n c_retval = %s(%s);\n" % (name
, c_call
);
450 ret_convert
= " py_retval = libvirt_%sWrap((%s) c_retval);\n" % (n
,c
)
451 ret_convert
= ret_convert
+ " return(py_retval);\n"
453 if skipped_types
.has_key(ret
[0]):
455 if unknown_types
.has_key(ret
[0]):
456 lst
= unknown_types
[ret
[0]]
459 unknown_types
[ret
[0]] = [name
]
462 if cond
!= None and cond
!= "":
463 include
.write("#if %s\n" % cond
)
464 export
.write("#if %s\n" % cond
)
465 output
.write("#if %s\n" % cond
)
467 include
.write("PyObject * ")
468 include
.write("libvirt_%s(PyObject *self, PyObject *args);\n" % (name
));
470 export
.write(" { (char *)\"%s\", libvirt_%s, METH_VARARGS, NULL },\n" %
474 # Those have been manually generated
475 if cond
!= None and cond
!= "":
476 include
.write("#endif\n");
477 export
.write("#endif\n");
478 output
.write("#endif\n");
480 if file == "python_accessor" and ret
[0] != "void" and ret
[2] is None:
481 # Those have been manually generated
482 if cond
!= None and cond
!= "":
483 include
.write("#endif\n");
484 export
.write("#endif\n");
485 output
.write("#endif\n");
488 output
.write("PyObject *\n")
489 output
.write("libvirt_%s(PyObject *self ATTRIBUTE_UNUSED," % (name
))
490 output
.write(" PyObject *args")
492 output
.write(" ATTRIBUTE_UNUSED")
493 output
.write(") {\n")
495 output
.write(" PyObject *py_retval;\n")
497 output
.write(c_return
)
501 output
.write("\n if (!PyArg_ParseTuple(args, (char *)\"%s\"%s))\n" %
502 (format
, format_args
))
503 output
.write(" return(NULL);\n")
505 output
.write(c_convert
)
507 output
.write("LIBVIRT_BEGIN_ALLOW_THREADS;\n");
508 output
.write(c_call
);
509 output
.write("LIBVIRT_END_ALLOW_THREADS;\n");
510 output
.write(ret_convert
)
511 output
.write("}\n\n")
512 if cond
!= None and cond
!= "":
513 include
.write("#endif /* %s */\n" % cond
)
514 export
.write("#endif /* %s */\n" % cond
)
515 output
.write("#endif /* %s */\n" % cond
)
520 global py_return_types
524 f
= open(os
.path
.join(srcPref
,"libvirt-api.xml"))
526 (parser
, target
) = getparser()
531 f
= open(os
.path
.join(srcPref
,"..","docs","libvirt-api.xml"))
533 (parser
, target
) = getparser()
540 n
= len(functions
.keys())
541 print "Found %d functions in libvirt-api.xml" % (n
)
543 py_types
['pythonObject'] = ('O', "pythonObject", "pythonObject", "pythonObject")
545 f
= open(os
.path
.join(srcPref
,"libvirt-override-api.xml"))
547 (parser
, target
) = getparser()
554 print "Found %d functions in libvirt-override-api.xml" % (
555 len(functions
.keys()) - n
)
560 include
= open("libvirt.h", "w")
561 include
.write("/* Generated */\n\n")
562 export
= open("libvirt-export.c", "w")
563 export
.write("/* Generated */\n\n")
564 wrapper
= open("libvirt.c", "w")
565 wrapper
.write("/* Generated */\n\n")
566 wrapper
.write("#include <Python.h>\n")
567 wrapper
.write("#include <libvirt/libvirt.h>\n")
568 wrapper
.write("#include \"typewrappers.h\"\n")
569 wrapper
.write("#include \"libvirt.h\"\n\n")
570 for function
in functions
.keys():
571 ret
= print_function_wrapper(function
, wrapper
, export
, include
)
574 functions_failed
.append(function
)
575 del functions
[function
]
577 skipped
= skipped
+ 1
578 functions_skipped
.append(function
)
579 del functions
[function
]
581 nb_wrap
= nb_wrap
+ 1
586 print "Generated %d wrapper functions" % nb_wrap
588 print "Missing type converters: "
589 for type in unknown_types
.keys():
590 print "%s:%d " % (type, len(unknown_types
[type])),
593 for f
in functions_failed
:
594 print "ERROR: failed %s" % f
600 #######################################################################
602 # This part writes part of the Python front-end classes based on
603 # mapping rules between types and classes and also based on function
604 # renaming to get consistent function names at the Python level
606 #######################################################################
609 # The type automatically remapped to generated classes
612 "virDomainPtr": ("._o", "virDomain(self,_obj=%s)", "virDomain"),
613 "virDomain *": ("._o", "virDomain(self, _obj=%s)", "virDomain"),
614 "virNetworkPtr": ("._o", "virNetwork(self, _obj=%s)", "virNetwork"),
615 "virNetwork *": ("._o", "virNetwork(self, _obj=%s)", "virNetwork"),
616 "virInterfacePtr": ("._o", "virInterface(self, _obj=%s)", "virInterface"),
617 "virInterface *": ("._o", "virInterface(self, _obj=%s)", "virInterface"),
618 "virStoragePoolPtr": ("._o", "virStoragePool(self, _obj=%s)", "virStoragePool"),
619 "virStoragePool *": ("._o", "virStoragePool(self, _obj=%s)", "virStoragePool"),
620 "virStorageVolPtr": ("._o", "virStorageVol(self, _obj=%s)", "virStorageVol"),
621 "virStorageVol *": ("._o", "virStorageVol(self, _obj=%s)", "virStorageVol"),
622 "virNodeDevicePtr": ("._o", "virNodeDevice(self, _obj=%s)", "virNodeDevice"),
623 "virNodeDevice *": ("._o", "virNodeDevice(self, _obj=%s)", "virNodeDevice"),
624 "virSecretPtr": ("._o", "virSecret(self, _obj=%s)", "virSecret"),
625 "virSecret *": ("._o", "virSecret(self, _obj=%s)", "virSecret"),
626 "virStreamPtr": ("._o", "virStream(self, _obj=%s)", "virStream"),
627 "virStream *": ("._o", "virStream(self, _obj=%s)", "virStream"),
628 "virConnectPtr": ("._o", "virConnect(_obj=%s)", "virConnect"),
629 "virConnect *": ("._o", "virConnect(_obj=%s)", "virConnect"),
635 primary_classes
= ["virDomain", "virNetwork", "virInterface",
636 "virStoragePool", "virStorageVol",
637 "virConnect", "virNodeDevice", "virSecret",
642 classes_destructors
= {
643 "virDomain": "virDomainFree",
644 "virNetwork": "virNetworkFree",
645 "virInterface": "virInterfaceFree",
646 "virStoragePool": "virStoragePoolFree",
647 "virStorageVol": "virStorageVolFree",
648 "virNodeDevice" : "virNodeDeviceFree",
649 "virSecret": "virSecretFree",
650 # We hand-craft __del__ for this one
651 #"virStream": "virStreamFree",
654 class_skip_connect_impl
= {
659 functions_noexcept
= {
660 'virDomainGetID': True,
661 'virDomainGetName': True,
662 'virNetworkGetName': True,
663 'virInterfaceGetName': True,
664 'virStoragePoolGetName': True,
665 'virStorageVolGetName': True,
666 'virStorageVolGetkey': True,
667 'virNodeDeviceGetName': True,
668 'virNodeDeviceGetParent': True,
669 'virSecretGetUsageType': True,
670 'virSecretGetUsageID': True,
673 reference_keepers
= {
676 function_classes
= {}
678 function_classes
["None"] = []
682 # Functions returning an integral type which need special rules to
683 # check for errors and raise exceptions.
684 functions_int_exception_test
= {
685 'virDomainGetMaxMemory': "%s == 0",
687 functions_int_default_test
= "%s == -1"
689 def is_integral_type (name
):
690 return not re
.search ("^(unsigned)? ?(int|long)$", name
) is None
692 # Functions returning lists which need special rules to check for errors
693 # and raise exceptions.
694 functions_list_exception_test
= {
696 functions_list_default_test
= "%s is None"
698 def is_list_type (name
):
699 whitelist
= [ "virDomainBlockStats",
700 "virDomainInterfaceStats" ]
702 return name
[-1:] == "*" or name
in whitelist
704 def nameFixup(name
, classe
, type, file):
705 # avoid a desastrous clash
706 listname
= classe
+ "List"
709 if name
[0:l
] == listname
:
711 func
= string
.lower(func
[0:1]) + func
[1:]
712 elif name
[0:16] == "virNetworkDefine":
714 func
= string
.lower(func
[0:1]) + func
[1:]
715 elif name
[0:19] == "virNetworkCreateXML":
717 func
= string
.lower(func
[0:1]) + func
[1:]
718 elif name
[0:16] == "virNetworkLookup":
720 func
= string
.lower(func
[0:1]) + func
[1:]
721 elif name
[0:18] == "virInterfaceDefine":
723 func
= string
.lower(func
[0:1]) + func
[1:]
724 elif name
[0:21] == "virInterfaceCreateXML":
726 func
= string
.lower(func
[0:1]) + func
[1:]
727 elif name
[0:18] == "virInterfaceLookup":
729 func
= string
.lower(func
[0:1]) + func
[1:]
730 elif name
[0:15] == "virSecretDefine":
732 func
= string
.lower(func
[0:1]) + func
[1:]
733 elif name
[0:15] == "virSecretLookup":
735 func
= string
.lower(func
[0:1]) + func
[1:]
736 elif name
[0:20] == "virStoragePoolDefine":
738 func
= string
.lower(func
[0:1]) + func
[1:]
739 elif name
[0:23] == "virStoragePoolCreateXML":
741 func
= string
.lower(func
[0:1]) + func
[1:]
742 elif name
[0:20] == "virStoragePoolLookup":
744 func
= string
.lower(func
[0:1]) + func
[1:]
745 elif name
[0:19] == "virStorageVolDefine":
747 func
= string
.lower(func
[0:1]) + func
[1:]
748 elif name
[0:19] == "virStorageVolLookup":
750 func
= string
.lower(func
[0:1]) + func
[1:]
751 elif name
[0:12] == "virDomainGet":
753 func
= string
.lower(func
[0:1]) + func
[1:]
754 elif name
[0:9] == "virDomain":
756 func
= string
.lower(func
[0:1]) + func
[1:]
757 elif name
[0:13] == "virNetworkGet":
759 func
= string
.lower(func
[0:1]) + func
[1:]
760 elif name
[0:10] == "virNetwork":
762 func
= string
.lower(func
[0:1]) + func
[1:]
763 elif name
[0:15] == "virInterfaceGet":
765 func
= string
.lower(func
[0:1]) + func
[1:]
766 elif name
[0:12] == "virInterface":
768 func
= string
.lower(func
[0:1]) + func
[1:]
769 elif name
[0:12] == 'virSecretGet':
771 func
= string
.lower(func
[0:1]) + func
[1:]
772 elif name
[0:9] == 'virSecret':
774 func
= string
.lower(func
[0:1]) + func
[1:]
775 elif name
[0:12] == 'virStreamNew':
777 elif name
[0:9] == 'virStream':
779 func
= string
.lower(func
[0:1]) + func
[1:]
780 elif name
[0:17] == "virStoragePoolGet":
782 func
= string
.lower(func
[0:1]) + func
[1:]
783 elif name
[0:14] == "virStoragePool":
785 func
= string
.lower(func
[0:1]) + func
[1:]
786 elif name
[0:16] == "virStorageVolGet":
788 func
= string
.lower(func
[0:1]) + func
[1:]
789 elif name
[0:13] == "virStorageVol":
791 func
= string
.lower(func
[0:1]) + func
[1:]
792 elif name
[0:13] == "virNodeDevice":
793 if name
[13:16] == "Get":
794 func
= string
.lower(name
[16]) + name
[17:]
795 elif name
[13:19] == "Lookup" or name
[13:19] == "Create":
796 func
= string
.lower(name
[3]) + name
[4:]
798 func
= string
.lower(name
[13]) + name
[14:]
799 elif name
[0:7] == "virNode":
801 func
= string
.lower(func
[0:1]) + func
[1:]
802 elif name
[0:10] == "virConnect":
804 func
= string
.lower(func
[0:1]) + func
[1:]
805 elif name
[0:3] == "xml":
807 func
= string
.lower(func
[0:1]) + func
[1:]
814 if func
== "uUIDString":
818 if func
== "xMLDesc":
820 if func
== "mACString":
826 def functionCompare(info1
, info2
):
827 (index1
, func1
, name1
, ret1
, args1
, file1
) = info1
828 (index2
, func2
, name2
, ret2
, args2
, file2
) = info2
834 if file1
== "python_accessor":
836 if file2
== "python_accessor":
844 def writeDoc(name
, args
, indent
, output
):
845 if functions
[name
][0] is None or functions
[name
][0] == "":
847 val
= functions
[name
][0]
848 val
= string
.replace(val
, "NULL", "None");
851 i
= string
.find(val
, "\n")
856 i
= string
.find(val
, "\n")
859 output
.write(' """\n')
864 global py_return_types
867 global function_classes
870 global converter_type
871 global primary_classes
872 global converter_type
873 global classes_ancestor
874 global converter_type
875 global primary_classes
876 global classes_ancestor
877 global classes_destructors
878 global functions_noexcept
880 for type in classes_type
.keys():
881 function_classes
[classes_type
[type][2]] = []
884 # Build the list of C types to look for ordered to start
885 # with primary classes
889 ctypes_processed
= {}
890 classes_processed
= {}
891 for classe
in primary_classes
:
892 classes_list
.append(classe
)
893 classes_processed
[classe
] = ()
894 for type in classes_type
.keys():
895 tinfo
= classes_type
[type]
896 if tinfo
[2] == classe
:
898 ctypes_processed
[type] = ()
899 for type in classes_type
.keys():
900 if ctypes_processed
.has_key(type):
902 tinfo
= classes_type
[type]
903 if not classes_processed
.has_key(tinfo
[2]):
904 classes_list
.append(tinfo
[2])
905 classes_processed
[tinfo
[2]] = ()
908 ctypes_processed
[type] = ()
910 for name
in functions
.keys():
912 (desc
, ret
, args
, file, cond
) = functions
[name
]
914 classe
= classes_type
[type][2]
916 if name
[0:3] == "vir" and len(args
) >= 1 and args
[0][1] == type:
918 func
= nameFixup(name
, classe
, type, file)
919 info
= (0, func
, name
, ret
, args
, file)
920 function_classes
[classe
].append(info
)
921 elif name
[0:3] == "vir" and len(args
) >= 2 and args
[1][1] == type \
922 and file != "python_accessor":
924 func
= nameFixup(name
, classe
, type, file)
925 info
= (1, func
, name
, ret
, args
, file)
926 function_classes
[classe
].append(info
)
929 func
= nameFixup(name
, "None", file, file)
930 info
= (0, func
, name
, ret
, args
, file)
931 function_classes
['None'].append(info
)
933 classes
= open("libvirt.py", "w")
935 extra
= open(os
.path
.join(srcPref
,"libvirt-override.py"), "r")
936 classes
.write("#!/usr/bin/python -i\n")
938 classes
.write("# WARNING WARNING WARNING WARNING\n")
940 classes
.write("# This file is automatically written by generator.py. Any changes\n")
941 classes
.write("# made here will be lost.\n")
943 classes
.write("# To change the manually written methods edit libvirt-override.py\n")
944 classes
.write("# To change the automatically written methods edit generator.py\n")
946 classes
.write("# WARNING WARNING WARNING WARNING\n")
948 classes
.writelines(extra
.readlines())
950 classes
.write("# WARNING WARNING WARNING WARNING\n")
952 classes
.write("# Automatically written part of python bindings for libvirt\n")
954 classes
.write("# WARNING WARNING WARNING WARNING\n")
957 if function_classes
.has_key("None"):
958 flist
= function_classes
["None"]
959 flist
.sort(functionCompare
)
962 (index
, func
, name
, ret
, args
, file) = info
964 classes
.write("#\n# Functions from module %s\n#\n\n" % file)
966 classes
.write("def %s(" % func
)
971 classes
.write("%s" % arg
[0])
973 classes
.write("):\n")
974 writeDoc(name
, args
, ' ', classes
);
977 if classes_type
.has_key(arg
[1]):
978 classes
.write(" if %s is None: %s__o = None\n" %
980 classes
.write(" else: %s__o = %s%s\n" %
981 (arg
[0], arg
[0], classes_type
[arg
[1]][0]))
983 classes
.write(" ret = ");
986 classes
.write("libvirtmod.%s(" % name
)
991 classes
.write("%s" % arg
[0])
992 if classes_type
.has_key(arg
[1]):
993 classes
.write("__o");
995 classes
.write(")\n");
998 if classes_type
.has_key(ret
[0]):
1000 # Raise an exception
1002 if functions_noexcept
.has_key(name
):
1003 classes
.write(" if ret is None:return None\n");
1006 " if ret is None:raise libvirtError('%s() failed')\n" %
1009 classes
.write(" return ");
1010 classes
.write(classes_type
[ret
[0]][1] % ("ret"));
1011 classes
.write("\n");
1013 # For functions returning an integral type there are
1014 # several things that we can do, depending on the
1015 # contents of functions_int_*:
1016 elif is_integral_type (ret
[0]):
1017 if not functions_noexcept
.has_key (name
):
1018 if functions_int_exception_test
.has_key (name
):
1019 test
= functions_int_exception_test
[name
]
1021 test
= functions_int_default_test
1022 classes
.write ((" if " + test
+
1023 ": raise libvirtError ('%s() failed')\n") %
1025 classes
.write(" return ret\n")
1027 elif is_list_type (ret
[0]):
1028 if not functions_noexcept
.has_key (name
):
1029 if functions_list_exception_test
.has_key (name
):
1030 test
= functions_list_exception_test
[name
]
1032 test
= functions_list_default_test
1033 classes
.write ((" if " + test
+
1034 ": raise libvirtError ('%s() failed')\n") %
1036 classes
.write(" return ret\n")
1039 classes
.write(" return ret\n")
1041 classes
.write("\n");
1043 for classname
in classes_list
:
1044 if classname
== "None":
1047 if classes_ancestor
.has_key(classname
):
1048 classes
.write("class %s(%s):\n" % (classname
,
1049 classes_ancestor
[classname
]))
1050 classes
.write(" def __init__(self, _obj=None):\n")
1051 if reference_keepers
.has_key(classname
):
1052 rlist
= reference_keepers
[classname
]
1054 classes
.write(" self.%s = None\n" % ref
[1])
1055 classes
.write(" self._o = _obj\n")
1056 classes
.write(" %s.__init__(self, _obj=_obj)\n\n" % (
1057 classes_ancestor
[classname
]))
1059 classes
.write("class %s:\n" % (classname
))
1060 if classname
in [ "virDomain", "virNetwork", "virInterface", "virStoragePool",
1061 "virStorageVol", "virNodeDevice", "virSecret","virStream" ]:
1062 classes
.write(" def __init__(self, conn, _obj=None):\n")
1064 classes
.write(" def __init__(self, _obj=None):\n")
1065 if reference_keepers
.has_key(classname
):
1066 list = reference_keepers
[classname
]
1068 classes
.write(" self.%s = None\n" % ref
[1])
1069 if classname
in [ "virDomain", "virNetwork", "virInterface",
1070 "virNodeDevice", "virSecret", "virStream" ]:
1071 classes
.write(" self._conn = conn\n")
1072 elif classname
in [ "virStorageVol", "virStoragePool" ]:
1073 classes
.write(" self._conn = conn\n" + \
1074 " if not isinstance(conn, virConnect):\n" + \
1075 " self._conn = conn._conn\n")
1076 classes
.write(" if _obj != None:self._o = _obj;return\n")
1077 classes
.write(" self._o = None\n\n");
1079 if classes_destructors
.has_key(classname
):
1080 classes
.write(" def __del__(self):\n")
1081 classes
.write(" if self._o != None:\n")
1082 classes
.write(" libvirtmod.%s(self._o)\n" %
1083 classes_destructors
[classname
]);
1084 classes
.write(" self._o = None\n\n");
1085 destruct
=classes_destructors
[classname
]
1087 if not class_skip_connect_impl
.has_key(classname
):
1088 # Build python safe 'connect' method
1089 classes
.write(" def connect(self):\n")
1090 classes
.write(" return self._conn\n\n")
1092 flist
= function_classes
[classname
]
1093 flist
.sort(functionCompare
)
1096 (index
, func
, name
, ret
, args
, file) = info
1098 # Do not provide as method the destructors for the class
1099 # to avoid double free
1101 if name
== destruct
:
1104 if file == "python_accessor":
1105 classes
.write(" # accessors for %s\n" % (classname
))
1107 classes
.write(" #\n")
1108 classes
.write(" # %s functions from module %s\n" % (
1110 classes
.write(" #\n\n")
1112 classes
.write(" def %s(self" % func
)
1116 classes
.write(", %s" % arg
[0])
1118 classes
.write("):\n")
1119 writeDoc(name
, args
, ' ', classes
);
1122 if classes_type
.has_key(arg
[1]):
1124 classes
.write(" if %s is None: %s__o = None\n" %
1126 classes
.write(" else: %s__o = %s%s\n" %
1127 (arg
[0], arg
[0], classes_type
[arg
[1]][0]))
1129 if ret
[0] != "void":
1130 classes
.write(" ret = ");
1133 classes
.write("libvirtmod.%s(" % name
)
1137 classes
.write(", ");
1139 classes
.write("%s" % arg
[0])
1140 if classes_type
.has_key(arg
[1]):
1141 classes
.write("__o");
1143 classes
.write("self");
1144 if classes_type
.has_key(arg
[1]):
1145 classes
.write(classes_type
[arg
[1]][0])
1147 classes
.write(")\n");
1149 if name
== "virConnectClose":
1150 classes
.write(" self._o = None\n")
1152 # For functions returning object types:
1153 if ret
[0] != "void":
1154 if classes_type
.has_key(ret
[0]):
1156 # Raise an exception
1158 if functions_noexcept
.has_key(name
):
1160 " if ret is None:return None\n");
1162 if classname
== "virConnect":
1164 " if ret is None:raise libvirtError('%s() failed', conn=self)\n" %
1166 elif classname
== "virDomain":
1168 " if ret is None:raise libvirtError('%s() failed', dom=self)\n" %
1170 elif classname
== "virNetwork":
1172 " if ret is None:raise libvirtError('%s() failed', net=self)\n" %
1174 elif classname
== "virInterface":
1176 " if ret is None:raise libvirtError('%s() failed', net=self)\n" %
1178 elif classname
== "virStoragePool":
1180 " if ret is None:raise libvirtError('%s() failed', pool=self)\n" %
1182 elif classname
== "virStorageVol":
1184 " if ret is None:raise libvirtError('%s() failed', vol=self)\n" %
1188 " if ret is None:raise libvirtError('%s() failed')\n" %
1192 # generate the returned class wrapper for the object
1194 classes
.write(" __tmp = ");
1195 classes
.write(classes_type
[ret
[0]][1] % ("ret"));
1196 classes
.write("\n");
1199 # Sometime one need to keep references of the source
1200 # class in the returned class object.
1201 # See reference_keepers for the list
1203 tclass
= classes_type
[ret
[0]][2]
1204 if reference_keepers
.has_key(tclass
):
1205 list = reference_keepers
[tclass
]
1207 if pref
[0] == classname
:
1208 classes
.write(" __tmp.%s = self\n" %
1211 # Post-processing - just before we return.
1212 if function_post
.has_key(name
):
1213 classes
.write(" %s\n" %
1214 (function_post
[name
]));
1219 classes
.write(" return __tmp\n");
1220 elif converter_type
.has_key(ret
[0]):
1222 # Raise an exception
1224 if functions_noexcept
.has_key(name
):
1226 " if ret is None:return None");
1228 # Post-processing - just before we return.
1229 if function_post
.has_key(name
):
1230 classes
.write(" %s\n" %
1231 (function_post
[name
]));
1233 classes
.write(" return ");
1234 classes
.write(converter_type
[ret
[0]] % ("ret"));
1235 classes
.write("\n");
1237 # For functions returning an integral type there
1238 # are several things that we can do, depending on
1239 # the contents of functions_int_*:
1240 elif is_integral_type (ret
[0]):
1241 if not functions_noexcept
.has_key (name
):
1242 if functions_int_exception_test
.has_key (name
):
1243 test
= functions_int_exception_test
[name
]
1245 test
= functions_int_default_test
1246 if classname
== "virConnect":
1247 classes
.write ((" if " + test
+
1248 ": raise libvirtError ('%s() failed', conn=self)\n") %
1250 elif classname
== "virDomain":
1251 classes
.write ((" if " + test
+
1252 ": raise libvirtError ('%s() failed', dom=self)\n") %
1254 elif classname
== "virNetwork":
1255 classes
.write ((" if " + test
+
1256 ": raise libvirtError ('%s() failed', net=self)\n") %
1258 elif classname
== "virInterface":
1259 classes
.write ((" if " + test
+
1260 ": raise libvirtError ('%s() failed', net=self)\n") %
1262 elif classname
== "virStoragePool":
1263 classes
.write ((" if " + test
+
1264 ": raise libvirtError ('%s() failed', pool=self)\n") %
1266 elif classname
== "virStorageVol":
1267 classes
.write ((" if " + test
+
1268 ": raise libvirtError ('%s() failed', vol=self)\n") %
1271 classes
.write ((" if " + test
+
1272 ": raise libvirtError ('%s() failed')\n") %
1275 # Post-processing - just before we return.
1276 if function_post
.has_key(name
):
1277 classes
.write(" %s\n" %
1278 (function_post
[name
]));
1280 classes
.write (" return ret\n")
1282 elif is_list_type (ret
[0]):
1283 if not functions_noexcept
.has_key (name
):
1284 if functions_list_exception_test
.has_key (name
):
1285 test
= functions_list_exception_test
[name
]
1287 test
= functions_list_default_test
1288 if classname
== "virConnect":
1289 classes
.write ((" if " + test
+
1290 ": raise libvirtError ('%s() failed', conn=self)\n") %
1292 elif classname
== "virDomain":
1293 classes
.write ((" if " + test
+
1294 ": raise libvirtError ('%s() failed', dom=self)\n") %
1296 elif classname
== "virNetwork":
1297 classes
.write ((" if " + test
+
1298 ": raise libvirtError ('%s() failed', net=self)\n") %
1300 elif classname
== "virInterface":
1301 classes
.write ((" if " + test
+
1302 ": raise libvirtError ('%s() failed', net=self)\n") %
1304 elif classname
== "virStoragePool":
1305 classes
.write ((" if " + test
+
1306 ": raise libvirtError ('%s() failed', pool=self)\n") %
1308 elif classname
== "virStorageVol":
1309 classes
.write ((" if " + test
+
1310 ": raise libvirtError ('%s() failed', vol=self)\n") %
1313 classes
.write ((" if " + test
+
1314 ": raise libvirtError ('%s() failed')\n") %
1317 # Post-processing - just before we return.
1318 if function_post
.has_key(name
):
1319 classes
.write(" %s\n" %
1320 (function_post
[name
]));
1322 classes
.write (" return ret\n")
1325 # Post-processing - just before we return.
1326 if function_post
.has_key(name
):
1327 classes
.write(" %s\n" %
1328 (function_post
[name
]));
1330 classes
.write(" return ret\n");
1332 classes
.write("\n");
1333 # Append "<classname>.py" to class def, iff it exists
1335 extra
= open(os
.path
.join(srcPref
,"libvirt-override-" + classname
+ ".py"), "r")
1336 classes
.write (" #\n")
1337 classes
.write (" # %s methods from %s.py (hand coded)\n" % (classname
,classname
))
1338 classes
.write (" #\n")
1339 classes
.writelines(extra
.readlines())
1346 # Generate enum constants
1348 for type,enum
in enums
.items():
1349 classes
.write("# %s\n" % type)
1350 items
= enum
.items()
1351 items
.sort(lambda i1
,i2
: cmp(long(i1
[1]),long(i2
[1])))
1352 for name
,value
in items
:
1353 classes
.write("%s = %s\n" % (name
,value
))
1354 classes
.write("\n");
1358 if buildStubs() < 0: