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 #######################################################################
32 sgmlop
= None # accelerator not available
38 """sgmlop based XML parser. this is typically 15x faster
41 def __init__(self
, target
):
44 self
.finish_starttag
= target
.start
45 self
.finish_endtag
= target
.end
46 self
.handle_data
= target
.data
49 self
.parser
= sgmlop
.XMLParser()
50 self
.parser
.register(self
)
51 self
.feed
= self
.parser
.feed
53 "amp": "&", "gt": ">", "lt": "<",
54 "apos": "'", "quot": '"'
61 self
.parser
= self
.feed
= None # nuke circular reference
63 def handle_entityref(self
, entity
):
66 self
.handle_data(self
.entity
[entity
])
68 self
.handle_data("&%s;" % entity
)
74 class SlowParser(xmllib
.XMLParser
):
75 """slow but safe standard parser, based on the XML parser in
76 Python's standard library."""
78 def __init__(self
, target
):
79 self
.unknown_starttag
= target
.start
80 self
.handle_data
= target
.data
81 self
.unknown_endtag
= target
.end
82 xmllib
.XMLParser
.__init
__(self
)
84 def getparser(target
= None):
85 # get the fastest available parser, and attach it to an
86 # unmarshalling object. return both objects.
90 return FastParser(target
), target
91 return SlowParser(target
), target
95 self
._methodname
= None
103 def getmethodname(self
):
104 return self
._methodname
106 def data(self
, text
):
108 print "data %s" % text
109 self
._data
.append(text
)
111 def start(self
, tag
, attrs
):
113 print "start %s, %s" % (tag
, attrs
)
114 if tag
== 'function':
118 self
.function_cond
= None
119 self
.function_args
= []
120 self
.function_descr
= None
121 self
.function_return
= None
122 self
.function_file
= None
123 if attrs
.has_key('name'):
124 self
.function
= attrs
['name']
125 if attrs
.has_key('file'):
126 self
.function_file
= attrs
['file']
132 if self
.in_function
== 1:
133 self
.function_arg_name
= None
134 self
.function_arg_type
= None
135 self
.function_arg_info
= None
136 if attrs
.has_key('name'):
137 self
.function_arg_name
= attrs
['name']
138 if self
.function_arg_name
== 'from':
139 self
.function_arg_name
= 'frm'
140 if attrs
.has_key('type'):
141 self
.function_arg_type
= attrs
['type']
142 if attrs
.has_key('info'):
143 self
.function_arg_info
= attrs
['info']
144 elif tag
== 'return':
145 if self
.in_function
== 1:
146 self
.function_return_type
= None
147 self
.function_return_info
= None
148 self
.function_return_field
= None
149 if attrs
.has_key('type'):
150 self
.function_return_type
= attrs
['type']
151 if attrs
.has_key('info'):
152 self
.function_return_info
= attrs
['info']
153 if attrs
.has_key('field'):
154 self
.function_return_field
= attrs
['field']
156 enum(attrs
['type'],attrs
['name'],attrs
['value'])
161 if tag
== 'function':
162 if self
.function
!= None:
163 function(self
.function
, self
.function_descr
,
164 self
.function_return
, self
.function_args
,
165 self
.function_file
, self
.function_cond
)
168 if self
.in_function
== 1:
169 self
.function_args
.append([self
.function_arg_name
,
170 self
.function_arg_type
,
171 self
.function_arg_info
])
172 elif tag
== 'return':
173 if self
.in_function
== 1:
174 self
.function_return
= [self
.function_return_type
,
175 self
.function_return_info
,
176 self
.function_return_field
]
181 if self
.in_function
== 1:
182 self
.function_descr
= str
187 if self
.in_function
== 1:
188 self
.function_cond
= str
191 def function(name
, desc
, ret
, args
, file, cond
):
192 functions
[name
] = (desc
, ret
, args
, file, cond
)
194 def enum(type, name
, value
):
195 if not enums
.has_key(type):
197 enums
[type][name
] = value
199 #######################################################################
201 # Some filtering rukes to drop functions/types which should not
202 # be exposed as-is on the Python interface
204 #######################################################################
206 functions_failed
= []
207 functions_skipped
= [
208 "virConnectListDomains"
215 # 'int *': "usually a return type",
216 'virConnectDomainEventCallback': "No function types in python",
217 'virEventAddHandleFunc': "No function types in python",
220 #######################################################################
222 # Table of remapping to/from the python type or class to the C
225 #######################################################################
228 'void': (None, None, None, None),
229 'int': ('i', None, "int", "int"),
230 'long': ('l', None, "long", "long"),
231 'double': ('d', None, "double", "double"),
232 'unsigned int': ('i', None, "int", "int"),
233 'unsigned long': ('l', None, "long", "long"),
234 'unsigned long long': ('l', None, "longlong", "long long"),
235 'unsigned char *': ('z', None, "charPtr", "char *"),
236 'char *': ('z', None, "charPtr", "char *"),
237 'const char *': ('z', None, "charPtrConst", "const char *"),
239 'virDomainPtr': ('O', "virDomain", "virDomainPtr", "virDomainPtr"),
240 'const virDomainPtr': ('O', "virDomain", "virDomainPtr", "virDomainPtr"),
241 'virDomain *': ('O', "virDomain", "virDomainPtr", "virDomainPtr"),
242 'const virDomain *': ('O', "virDomain", "virDomainPtr", "virDomainPtr"),
244 'virNetworkPtr': ('O', "virNetwork", "virNetworkPtr", "virNetworkPtr"),
245 'const virNetworkPtr': ('O', "virNetwork", "virNetworkPtr", "virNetworkPtr"),
246 'virNetwork *': ('O', "virNetwork", "virNetworkPtr", "virNetworkPtr"),
247 'const virNetwork *': ('O', "virNetwork", "virNetworkPtr", "virNetworkPtr"),
249 'virInterfacePtr': ('O', "virInterface", "virInterfacePtr", "virInterfacePtr"),
250 'const virInterfacePtr': ('O', "virInterface", "virInterfacePtr", "virInterfacePtr"),
251 'virInterface *': ('O', "virInterface", "virInterfacePtr", "virInterfacePtr"),
252 'const virInterface *': ('O', "virInterface", "virInterfacePtr", "virInterfacePtr"),
254 'virStoragePoolPtr': ('O', "virStoragePool", "virStoragePoolPtr", "virStoragePoolPtr"),
255 'const virStoragePoolPtr': ('O', "virStoragePool", "virStoragePoolPtr", "virStoragePoolPtr"),
256 'virStoragePool *': ('O', "virStoragePool", "virStoragePoolPtr", "virStoragePoolPtr"),
257 'const virStoragePool *': ('O', "virStoragePool", "virStoragePoolPtr", "virStoragePoolPtr"),
259 'virStorageVolPtr': ('O', "virStorageVol", "virStorageVolPtr", "virStorageVolPtr"),
260 'const virStorageVolPtr': ('O', "virStorageVol", "virStorageVolPtr", "virStorageVolPtr"),
261 'virStorageVol *': ('O', "virStorageVol", "virStorageVolPtr", "virStorageVolPtr"),
262 'const virStorageVol *': ('O', "virStorageVol", "virStorageVolPtr", "virStorageVolPtr"),
264 'virConnectPtr': ('O', "virConnect", "virConnectPtr", "virConnectPtr"),
265 'const virConnectPtr': ('O', "virConnect", "virConnectPtr", "virConnectPtr"),
266 'virConnect *': ('O', "virConnect", "virConnectPtr", "virConnectPtr"),
267 'const virConnect *': ('O', "virConnect", "virConnectPtr", "virConnectPtr"),
269 'virNodeDevicePtr': ('O', "virNodeDevice", "virNodeDevicePtr", "virNodeDevicePtr"),
270 'const virNodeDevicePtr': ('O', "virNodeDevice", "virNodeDevicePtr", "virNodeDevicePtr"),
271 'virNodeDevice *': ('O', "virNodeDevice", "virNodeDevicePtr", "virNodeDevicePtr"),
272 'const virNodeDevice *': ('O', "virNodeDevice", "virNodeDevicePtr", "virNodeDevicePtr"),
274 'virSecretPtr': ('O', "virSecret", "virSecretPtr", "virSecretPtr"),
275 'const virSecretPtr': ('O', "virSecret", "virSecretPtr", "virSecretPtr"),
276 'virSecret *': ('O', "virSecret", "virSecretPtr", "virSecretPtr"),
277 'const virSecret *': ('O', "virSecret", "virSecretPtr", "virSecretPtr"),
285 foreign_encoding_args
= (
288 #######################################################################
290 # This part writes the C <-> Python stubs libvirt2-py.[ch] and
291 # the table libxml2-export.c to add when registrering the Python module
293 #######################################################################
295 # Class methods which are written by hand in libvir.c but the Python-level
296 # code is still automatically generated (so they are not in skip_function()).
298 'virConnectListDomainsID',
299 'virConnectListDefinedDomains',
300 'virConnectListNetworks',
301 'virConnectListDefinedNetworks',
302 'virConnectListInterfaces',
303 'virConnectListDefinedInterfaces',
304 'virConnectListSecrets',
305 'virConnectListStoragePools',
306 'virConnectListDefinedStoragePools',
307 'virConnectListStorageVols',
308 'virConnectListDefinedStorageVols',
309 'virConnGetLastError',
314 'virDomainGetUUIDString',
315 'virDomainLookupByUUID',
317 'virNetworkGetUUIDString',
318 'virNetworkLookupByUUID',
319 'virDomainGetAutostart',
320 'virNetworkGetAutostart',
321 'virDomainBlockStats',
322 'virDomainInterfaceStats',
323 'virNodeGetCellsFreeMemory',
324 'virDomainGetSchedulerType',
325 'virDomainGetSchedulerParameters',
326 'virDomainSetSchedulerParameters',
332 'virSecretGetUUIDString',
333 'virSecretLookupByUUID',
334 'virStoragePoolGetUUID',
335 'virStoragePoolGetUUIDString',
336 'virStoragePoolLookupByUUID',
337 'virStoragePoolGetInfo',
338 'virStorageVolGetInfo',
339 'virStoragePoolGetAutostart',
340 'virStoragePoolListVolumes',
341 'virDomainBlockPeek',
342 'virDomainMemoryPeek',
343 'virEventRegisterImpl',
344 'virNodeListDevices',
345 'virNodeDeviceListCaps',
349 # These are functions which the generator skips completly - no python
350 # or C code is generated. Generally should not be used for any more
351 # functions than those already listed
353 'virConnectListDomains', # Python API is called virConectListDomainsID for unknown reasons
354 'virConnSetErrorFunc', # Not used in Python API XXX is this a bug ?
355 'virResetError', # Not used in Python API XXX is this a bug ?
356 'virConnectGetVersion', # Not used in Python API XXX is this a bug ?
357 'virGetVersion', # Python C code is manually written
358 'virSetErrorFunc', # Python API is called virRegisterErrorHandler for unknown reasons
359 'virConnCopyLastError', # Python API is called virConnGetLastError instead
360 'virCopyLastError', # Python API is called virGetLastError instead
361 'virConnectOpenAuth', # Python C code is manually written
362 'virDefaultErrorFunc', # Python virErrorFuncHandler impl calls this from C
363 'virDomainGetSecurityLabel', # Needs investigation...
364 'virNodeGetSecurityModel', # Needs investigation...
365 'virConnectDomainEventRegister', # overridden in virConnect.py
366 'virConnectDomainEventDeregister', # overridden in virConnect.py
367 'virSaveLastError', # We have our own python error wrapper
368 'virFreeError', # Only needed if we use virSaveLastError
372 def print_function_wrapper(name
, output
, export
, include
):
376 global skipped_modules
379 (desc
, ret
, args
, file, cond
) = functions
[name
]
381 print "failed to get function %s infos"
384 if skipped_modules
.has_key(file):
386 if name
in skip_function
:
388 if name
in skip_impl
:
389 # Don't delete the function entry in the caller.
400 # This should be correct
401 if arg
[1][0:6] == "const ":
403 c_args
= c_args
+ " %s %s;\n" % (arg
[1], arg
[0])
404 if py_types
.has_key(arg
[1]):
405 (f
, t
, n
, c
) = py_types
[arg
[1]]
406 if (f
== 'z') and (name
in foreign_encoding_args
) and (num_bufs
== 0):
411 format_args
= format_args
+ ", &pyobj_%s" % (arg
[0])
412 c_args
= c_args
+ " PyObject *pyobj_%s;\n" % (arg
[0])
413 c_convert
= c_convert
+ \
414 " %s = (%s) Py%s_Get(pyobj_%s);\n" % (arg
[0],
417 format_args
= format_args
+ ", &%s" % (arg
[0])
419 format_args
= format_args
+ ", &py_buffsize%d" % num_bufs
420 c_args
= c_args
+ " int py_buffsize%d;\n" % num_bufs
421 num_bufs
= num_bufs
+ 1
423 c_call
= c_call
+ ", ";
424 c_call
= c_call
+ "%s" % (arg
[0])
426 if skipped_types
.has_key(arg
[1]):
428 if unknown_types
.has_key(arg
[1]):
429 lst
= unknown_types
[arg
[1]]
432 unknown_types
[arg
[1]] = [name
]
435 format
= format
+ ":%s" % (name
)
438 if file == "python_accessor":
439 if args
[1][1] == "char *":
440 c_call
= "\n free(%s->%s);\n" % (
441 args
[0][0], args
[1][0], args
[0][0], args
[1][0])
442 c_call
= c_call
+ " %s->%s = (%s)strdup((const xmlChar *)%s);\n" % (args
[0][0],
443 args
[1][0], args
[1][1], args
[1][0])
445 c_call
= "\n %s->%s = %s;\n" % (args
[0][0], args
[1][0],
448 c_call
= "\n %s(%s);\n" % (name
, c_call
);
449 ret_convert
= " Py_INCREF(Py_None);\n return(Py_None);\n"
450 elif py_types
.has_key(ret
[0]):
451 (f
, t
, n
, c
) = py_types
[ret
[0]]
452 c_return
= " %s c_retval;\n" % (ret
[0])
453 if file == "python_accessor" and ret
[2] != None:
454 c_call
= "\n c_retval = %s->%s;\n" % (args
[0][0], ret
[2])
456 c_call
= "\n c_retval = %s(%s);\n" % (name
, c_call
);
457 ret_convert
= " py_retval = libvirt_%sWrap((%s) c_retval);\n" % (n
,c
)
458 ret_convert
= ret_convert
+ " return(py_retval);\n"
459 elif py_return_types
.has_key(ret
[0]):
460 (f
, t
, n
, c
) = py_return_types
[ret
[0]]
461 c_return
= " %s c_retval;\n" % (ret
[0])
462 c_call
= "\n c_retval = %s(%s);\n" % (name
, c_call
);
463 ret_convert
= " py_retval = libvirt_%sWrap((%s) c_retval);\n" % (n
,c
)
464 ret_convert
= ret_convert
+ " return(py_retval);\n"
466 if skipped_types
.has_key(ret
[0]):
468 if unknown_types
.has_key(ret
[0]):
469 lst
= unknown_types
[ret
[0]]
472 unknown_types
[ret
[0]] = [name
]
475 if cond
!= None and cond
!= "":
476 include
.write("#if %s\n" % cond
)
477 export
.write("#if %s\n" % cond
)
478 output
.write("#if %s\n" % cond
)
480 include
.write("PyObject * ")
481 include
.write("libvirt_%s(PyObject *self, PyObject *args);\n" % (name
));
483 export
.write(" { (char *)\"%s\", libvirt_%s, METH_VARARGS, NULL },\n" %
487 # Those have been manually generated
488 if cond
!= None and cond
!= "":
489 include
.write("#endif\n");
490 export
.write("#endif\n");
491 output
.write("#endif\n");
493 if file == "python_accessor" and ret
[0] != "void" and ret
[2] is None:
494 # Those have been manually generated
495 if cond
!= None and cond
!= "":
496 include
.write("#endif\n");
497 export
.write("#endif\n");
498 output
.write("#endif\n");
501 output
.write("PyObject *\n")
502 output
.write("libvirt_%s(PyObject *self ATTRIBUTE_UNUSED," % (name
))
503 output
.write(" PyObject *args")
505 output
.write(" ATTRIBUTE_UNUSED")
506 output
.write(") {\n")
508 output
.write(" PyObject *py_retval;\n")
510 output
.write(c_return
)
514 output
.write("\n if (!PyArg_ParseTuple(args, (char *)\"%s\"%s))\n" %
515 (format
, format_args
))
516 output
.write(" return(NULL);\n")
518 output
.write(c_convert
)
520 output
.write("LIBVIRT_BEGIN_ALLOW_THREADS;\n");
521 output
.write(c_call
);
522 output
.write("LIBVIRT_END_ALLOW_THREADS;\n");
523 output
.write(ret_convert
)
524 output
.write("}\n\n")
525 if cond
!= None and cond
!= "":
526 include
.write("#endif /* %s */\n" % cond
)
527 export
.write("#endif /* %s */\n" % cond
)
528 output
.write("#endif /* %s */\n" % cond
)
533 global py_return_types
537 f
= open(os
.path
.join(srcPref
,"libvirt-api.xml"))
539 (parser
, target
) = getparser()
544 f
= open(os
.path
.join(srcPref
,"..","docs","libvirt-api.xml"))
546 (parser
, target
) = getparser()
553 n
= len(functions
.keys())
554 print "Found %d functions in libvirt-api.xml" % (n
)
556 py_types
['pythonObject'] = ('O', "pythonObject", "pythonObject", "pythonObject")
558 f
= open(os
.path
.join(srcPref
,"libvirt-python-api.xml"))
560 (parser
, target
) = getparser()
567 print "Found %d functions in libvirt-python-api.xml" % (
568 len(functions
.keys()) - n
)
573 include
= open("libvirt-py.h", "w")
574 include
.write("/* Generated */\n\n")
575 export
= open("libvirt-export.c", "w")
576 export
.write("/* Generated */\n\n")
577 wrapper
= open("libvirt-py.c", "w")
578 wrapper
.write("/* Generated */\n\n")
579 wrapper
.write("#include <Python.h>\n")
580 wrapper
.write("#include <libvirt/libvirt.h>\n")
581 wrapper
.write("#include \"libvirt_wrap.h\"\n")
582 wrapper
.write("#include \"libvirt-py.h\"\n\n")
583 for function
in functions
.keys():
584 ret
= print_function_wrapper(function
, wrapper
, export
, include
)
587 functions_failed
.append(function
)
588 del functions
[function
]
590 skipped
= skipped
+ 1
591 functions_skipped
.append(function
)
592 del functions
[function
]
594 nb_wrap
= nb_wrap
+ 1
599 print "Generated %d wrapper functions" % nb_wrap
601 print "Missing type converters: "
602 for type in unknown_types
.keys():
603 print "%s:%d " % (type, len(unknown_types
[type])),
606 for f
in functions_failed
:
607 print "ERROR: failed %s" % f
613 #######################################################################
615 # This part writes part of the Python front-end classes based on
616 # mapping rules between types and classes and also based on function
617 # renaming to get consistent function names at the Python level
619 #######################################################################
622 # The type automatically remapped to generated classes
625 "virDomainPtr": ("._o", "virDomain(self,_obj=%s)", "virDomain"),
626 "virDomain *": ("._o", "virDomain(self, _obj=%s)", "virDomain"),
627 "virNetworkPtr": ("._o", "virNetwork(self, _obj=%s)", "virNetwork"),
628 "virNetwork *": ("._o", "virNetwork(self, _obj=%s)", "virNetwork"),
629 "virInterfacePtr": ("._o", "virInterface(self, _obj=%s)", "virInterface"),
630 "virInterface *": ("._o", "virInterface(self, _obj=%s)", "virInterface"),
631 "virStoragePoolPtr": ("._o", "virStoragePool(self, _obj=%s)", "virStoragePool"),
632 "virStoragePool *": ("._o", "virStoragePool(self, _obj=%s)", "virStoragePool"),
633 "virStorageVolPtr": ("._o", "virStorageVol(self, _obj=%s)", "virStorageVol"),
634 "virStorageVol *": ("._o", "virStorageVol(self, _obj=%s)", "virStorageVol"),
635 "virNodeDevicePtr": ("._o", "virNodeDevice(self, _obj=%s)", "virNodeDevice"),
636 "virNodeDevice *": ("._o", "virNodeDevice(self, _obj=%s)", "virNodeDevice"),
637 "virSecretPtr": ("._o", "virSecret(self, _obj=%s)", "virSecret"),
638 "virSecret *": ("._o", "virSecret(self, _obj=%s)", "virSecret"),
639 "virConnectPtr": ("._o", "virConnect(_obj=%s)", "virConnect"),
640 "virConnect *": ("._o", "virConnect(_obj=%s)", "virConnect"),
646 primary_classes
= ["virDomain", "virNetwork", "virInterface",
647 "virStoragePool", "virStorageVol",
648 "virConnect", "virNodeDevice", "virSecret" ]
652 classes_destructors
= {
653 "virDomain": "virDomainFree",
654 "virNetwork": "virNetworkFree",
655 "virInterface": "virInterfaceFree",
656 "virStoragePool": "virStoragePoolFree",
657 "virStorageVol": "virStorageVolFree",
658 "virNodeDevice" : "virNodeDeviceFree",
659 "virSecret": "virSecretFree"
662 functions_noexcept
= {
663 'virDomainGetID': True,
664 'virDomainGetName': True,
665 'virNetworkGetName': True,
666 'virInterfaceGetName': True,
667 'virStoragePoolGetName': True,
668 'virStorageVolGetName': True,
669 'virStorageVolGetkey': True,
670 'virNodeDeviceGetName': True,
671 'virNodeDeviceGetParent': True,
672 'virSecretGetUsageType': True,
673 'virSecretGetUsageID': True,
676 reference_keepers
= {
679 function_classes
= {}
681 function_classes
["None"] = []
685 # Functions returning an integral type which need special rules to
686 # check for errors and raise exceptions.
687 functions_int_exception_test
= {
688 'virDomainGetMaxMemory': "%s == 0",
690 functions_int_default_test
= "%s == -1"
692 def is_integral_type (name
):
693 return not re
.search ("^(unsigned)? ?(int|long)$", name
) is None
695 # Functions returning lists which need special rules to check for errors
696 # and raise exceptions.
697 functions_list_exception_test
= {
699 functions_list_default_test
= "%s is None"
701 def is_list_type (name
):
702 whitelist
= [ "virDomainBlockStats",
703 "virDomainInterfaceStats" ]
705 return name
[-1:] == "*" or name
in whitelist
707 def nameFixup(name
, classe
, type, file):
708 # avoid a desastrous clash
709 listname
= classe
+ "List"
712 if name
[0:l
] == listname
:
714 func
= string
.lower(func
[0:1]) + func
[1:]
715 elif name
[0:16] == "virNetworkDefine":
717 func
= string
.lower(func
[0:1]) + func
[1:]
718 elif name
[0:19] == "virNetworkCreateXML":
720 func
= string
.lower(func
[0:1]) + func
[1:]
721 elif name
[0:16] == "virNetworkLookup":
723 func
= string
.lower(func
[0:1]) + func
[1:]
724 elif name
[0:18] == "virInterfaceDefine":
726 func
= string
.lower(func
[0:1]) + func
[1:]
727 elif name
[0:21] == "virInterfaceCreateXML":
729 func
= string
.lower(func
[0:1]) + func
[1:]
730 elif name
[0:18] == "virInterfaceLookup":
732 func
= string
.lower(func
[0:1]) + func
[1:]
733 elif name
[0:15] == "virSecretDefine":
735 func
= string
.lower(func
[0:1]) + func
[1:]
736 elif name
[0:15] == "virSecretLookup":
738 func
= string
.lower(func
[0:1]) + func
[1:]
739 elif name
[0:20] == "virStoragePoolDefine":
741 func
= string
.lower(func
[0:1]) + func
[1:]
742 elif name
[0:23] == "virStoragePoolCreateXML":
744 func
= string
.lower(func
[0:1]) + func
[1:]
745 elif name
[0:20] == "virStoragePoolLookup":
747 func
= string
.lower(func
[0:1]) + func
[1:]
748 elif name
[0:19] == "virStorageVolDefine":
750 func
= string
.lower(func
[0:1]) + func
[1:]
751 elif name
[0:19] == "virStorageVolLookup":
753 func
= string
.lower(func
[0:1]) + func
[1:]
754 elif name
[0:12] == "virDomainGet":
756 func
= string
.lower(func
[0:1]) + func
[1:]
757 elif name
[0:9] == "virDomain":
759 func
= string
.lower(func
[0:1]) + func
[1:]
760 elif name
[0:13] == "virNetworkGet":
762 func
= string
.lower(func
[0:1]) + func
[1:]
763 elif name
[0:10] == "virNetwork":
765 func
= string
.lower(func
[0:1]) + func
[1:]
766 elif name
[0:15] == "virInterfaceGet":
768 func
= string
.lower(func
[0:1]) + func
[1:]
769 elif name
[0:12] == "virInterface":
771 func
= string
.lower(func
[0:1]) + func
[1:]
772 elif name
[0:12] == 'virSecretGet':
774 func
= string
.lower(func
[0:1]) + func
[1:]
775 elif name
[0:9] == 'virSecret':
777 func
= string
.lower(func
[0:1]) + func
[1:]
778 elif name
[0:17] == "virStoragePoolGet":
780 func
= string
.lower(func
[0:1]) + func
[1:]
781 elif name
[0:14] == "virStoragePool":
783 func
= string
.lower(func
[0:1]) + func
[1:]
784 elif name
[0:16] == "virStorageVolGet":
786 func
= string
.lower(func
[0:1]) + func
[1:]
787 elif name
[0:13] == "virStorageVol":
789 func
= string
.lower(func
[0:1]) + func
[1:]
790 elif name
[0:13] == "virNodeDevice":
791 if name
[13:16] == "Get":
792 func
= string
.lower(name
[16]) + name
[17:]
793 elif name
[13:19] == "Lookup" or name
[13:] == "Create":
794 func
= string
.lower(name
[3]) + name
[4:]
796 func
= string
.lower(name
[13]) + name
[14:]
797 elif name
[0:7] == "virNode":
799 func
= string
.lower(func
[0:1]) + func
[1:]
800 elif name
[0:10] == "virConnect":
802 func
= string
.lower(func
[0:1]) + func
[1:]
803 elif name
[0:3] == "xml":
805 func
= string
.lower(func
[0:1]) + func
[1:]
812 if func
== "uUIDString":
816 if func
== "xMLDesc":
821 def functionCompare(info1
, info2
):
822 (index1
, func1
, name1
, ret1
, args1
, file1
) = info1
823 (index2
, func2
, name2
, ret2
, args2
, file2
) = info2
829 if file1
== "python_accessor":
831 if file2
== "python_accessor":
839 def writeDoc(name
, args
, indent
, output
):
840 if functions
[name
][0] is None or functions
[name
][0] == "":
842 val
= functions
[name
][0]
843 val
= string
.replace(val
, "NULL", "None");
851 i
= string
.rfind(str, " ");
860 output
.write(' """\n')
865 global py_return_types
868 global function_classes
871 global converter_type
872 global primary_classes
873 global converter_type
874 global classes_ancestor
875 global converter_type
876 global primary_classes
877 global classes_ancestor
878 global classes_destructors
879 global functions_noexcept
881 for type in classes_type
.keys():
882 function_classes
[classes_type
[type][2]] = []
885 # Build the list of C types to look for ordered to start
886 # with primary classes
890 ctypes_processed
= {}
891 classes_processed
= {}
892 for classe
in primary_classes
:
893 classes_list
.append(classe
)
894 classes_processed
[classe
] = ()
895 for type in classes_type
.keys():
896 tinfo
= classes_type
[type]
897 if tinfo
[2] == classe
:
899 ctypes_processed
[type] = ()
900 for type in classes_type
.keys():
901 if ctypes_processed
.has_key(type):
903 tinfo
= classes_type
[type]
904 if not classes_processed
.has_key(tinfo
[2]):
905 classes_list
.append(tinfo
[2])
906 classes_processed
[tinfo
[2]] = ()
909 ctypes_processed
[type] = ()
911 for name
in functions
.keys():
913 (desc
, ret
, args
, file, cond
) = functions
[name
]
915 classe
= classes_type
[type][2]
917 if name
[0:3] == "vir" and len(args
) >= 1 and args
[0][1] == type:
919 func
= nameFixup(name
, classe
, type, file)
920 info
= (0, func
, name
, ret
, args
, file)
921 function_classes
[classe
].append(info
)
922 elif name
[0:3] == "vir" and len(args
) >= 2 and args
[1][1] == type \
923 and file != "python_accessor":
925 func
= nameFixup(name
, classe
, type, file)
926 info
= (1, func
, name
, ret
, args
, file)
927 function_classes
[classe
].append(info
)
930 func
= nameFixup(name
, "None", file, file)
931 info
= (0, func
, name
, ret
, args
, file)
932 function_classes
['None'].append(info
)
934 classes
= open("libvirtclass.py", "w")
936 txt
= open("libvirtclass.txt", "w")
937 txt
.write(" Generated Classes for libvir-python\n\n")
939 txt
.write("#\n# Global functions of the module\n#\n\n")
940 if function_classes
.has_key("None"):
941 flist
= function_classes
["None"]
942 flist
.sort(functionCompare
)
945 (index
, func
, name
, ret
, args
, file) = info
947 classes
.write("#\n# Functions from module %s\n#\n\n" % file)
948 txt
.write("\n# functions from module %s\n" % file)
950 classes
.write("def %s(" % func
)
951 txt
.write("%s()\n" % func
);
956 classes
.write("%s" % arg
[0])
958 classes
.write("):\n")
959 writeDoc(name
, args
, ' ', classes
);
962 if classes_type
.has_key(arg
[1]):
963 classes
.write(" if %s is None: %s__o = None\n" %
965 classes
.write(" else: %s__o = %s%s\n" %
966 (arg
[0], arg
[0], classes_type
[arg
[1]][0]))
968 classes
.write(" ret = ");
971 classes
.write("libvirtmod.%s(" % name
)
976 classes
.write("%s" % arg
[0])
977 if classes_type
.has_key(arg
[1]):
978 classes
.write("__o");
980 classes
.write(")\n");
983 if classes_type
.has_key(ret
[0]):
987 if functions_noexcept
.has_key(name
):
988 classes
.write(" if ret is None:return None\n");
991 " if ret is None:raise libvirtError('%s() failed')\n" %
994 classes
.write(" return ");
995 classes
.write(classes_type
[ret
[0]][1] % ("ret"));
998 # For functions returning an integral type there are
999 # several things that we can do, depending on the
1000 # contents of functions_int_*:
1001 elif is_integral_type (ret
[0]):
1002 if not functions_noexcept
.has_key (name
):
1003 if functions_int_exception_test
.has_key (name
):
1004 test
= functions_int_exception_test
[name
]
1006 test
= functions_int_default_test
1007 classes
.write ((" if " + test
+
1008 ": raise libvirtError ('%s() failed')\n") %
1010 classes
.write(" return ret\n")
1012 elif is_list_type (ret
[0]):
1013 if not functions_noexcept
.has_key (name
):
1014 if functions_list_exception_test
.has_key (name
):
1015 test
= functions_list_exception_test
[name
]
1017 test
= functions_list_default_test
1018 classes
.write ((" if " + test
+
1019 ": raise libvirtError ('%s() failed')\n") %
1021 classes
.write(" return ret\n")
1024 classes
.write(" return ret\n")
1026 classes
.write("\n");
1028 txt
.write("\n\n#\n# Set of classes of the module\n#\n\n")
1029 for classname
in classes_list
:
1030 if classname
== "None":
1033 if classes_ancestor
.has_key(classname
):
1034 txt
.write("\n\nClass %s(%s)\n" % (classname
,
1035 classes_ancestor
[classname
]))
1036 classes
.write("class %s(%s):\n" % (classname
,
1037 classes_ancestor
[classname
]))
1038 classes
.write(" def __init__(self, _obj=None):\n")
1039 if reference_keepers
.has_key(classname
):
1040 rlist
= reference_keepers
[classname
]
1042 classes
.write(" self.%s = None\n" % ref
[1])
1043 classes
.write(" self._o = _obj\n")
1044 classes
.write(" %s.__init__(self, _obj=_obj)\n\n" % (
1045 classes_ancestor
[classname
]))
1047 txt
.write("Class %s()\n" % (classname
))
1048 classes
.write("class %s:\n" % (classname
))
1049 if classname
in [ "virDomain", "virNetwork", "virInterface", "virStoragePool", "virStorageVol", "virNodeDevice", "virSecret" ]:
1050 classes
.write(" def __init__(self, conn, _obj=None):\n")
1052 classes
.write(" def __init__(self, _obj=None):\n")
1053 if reference_keepers
.has_key(classname
):
1054 list = reference_keepers
[classname
]
1056 classes
.write(" self.%s = None\n" % ref
[1])
1057 if classname
in [ "virDomain", "virNetwork", "virInterface", "virNodeDevice", "virSecret" ]:
1058 classes
.write(" self._conn = conn\n")
1059 elif classname
in [ "virStorageVol", "virStoragePool" ]:
1060 classes
.write(" self._conn = conn\n" + \
1061 " if not isinstance(conn, virConnect):\n" + \
1062 " self._conn = conn._conn\n")
1063 classes
.write(" if _obj != None:self._o = _obj;return\n")
1064 classes
.write(" self._o = None\n\n");
1066 if classes_destructors
.has_key(classname
):
1067 classes
.write(" def __del__(self):\n")
1068 classes
.write(" if self._o != None:\n")
1069 classes
.write(" libvirtmod.%s(self._o)\n" %
1070 classes_destructors
[classname
]);
1071 classes
.write(" self._o = None\n\n");
1072 destruct
=classes_destructors
[classname
]
1073 flist
= function_classes
[classname
]
1074 flist
.sort(functionCompare
)
1077 (index
, func
, name
, ret
, args
, file) = info
1079 # Do not provide as method the destructors for the class
1080 # to avoid double free
1082 if name
== destruct
:
1085 if file == "python_accessor":
1086 classes
.write(" # accessors for %s\n" % (classname
))
1087 txt
.write(" # accessors\n")
1089 classes
.write(" #\n")
1090 classes
.write(" # %s functions from module %s\n" % (
1092 txt
.write("\n # functions from module %s\n" % file)
1093 classes
.write(" #\n\n")
1095 classes
.write(" def %s(self" % func
)
1096 txt
.write(" %s()\n" % func
);
1100 classes
.write(", %s" % arg
[0])
1102 classes
.write("):\n")
1103 writeDoc(name
, args
, ' ', classes
);
1106 if classes_type
.has_key(arg
[1]):
1108 classes
.write(" if %s is None: %s__o = None\n" %
1110 classes
.write(" else: %s__o = %s%s\n" %
1111 (arg
[0], arg
[0], classes_type
[arg
[1]][0]))
1113 if ret
[0] != "void":
1114 classes
.write(" ret = ");
1117 classes
.write("libvirtmod.%s(" % name
)
1121 classes
.write(", ");
1123 classes
.write("%s" % arg
[0])
1124 if classes_type
.has_key(arg
[1]):
1125 classes
.write("__o");
1127 classes
.write("self");
1128 if classes_type
.has_key(arg
[1]):
1129 classes
.write(classes_type
[arg
[1]][0])
1131 classes
.write(")\n");
1133 if name
== "virConnectClose":
1134 classes
.write(" self._o = None\n")
1136 # For functions returning object types:
1137 if ret
[0] != "void":
1138 if classes_type
.has_key(ret
[0]):
1140 # Raise an exception
1142 if functions_noexcept
.has_key(name
):
1144 " if ret is None:return None\n");
1146 if classname
== "virConnect":
1148 " if ret is None:raise libvirtError('%s() failed', conn=self)\n" %
1150 elif classname
== "virDomain":
1152 " if ret is None:raise libvirtError('%s() failed', dom=self)\n" %
1154 elif classname
== "virNetwork":
1156 " if ret is None:raise libvirtError('%s() failed', net=self)\n" %
1158 elif classname
== "virInterface":
1160 " if ret is None:raise libvirtError('%s() failed', net=self)\n" %
1162 elif classname
== "virStoragePool":
1164 " if ret is None:raise libvirtError('%s() failed', pool=self)\n" %
1166 elif classname
== "virStorageVol":
1168 " if ret is None:raise libvirtError('%s() failed', vol=self)\n" %
1172 " if ret is None:raise libvirtError('%s() failed')\n" %
1176 # generate the returned class wrapper for the object
1178 classes
.write(" __tmp = ");
1179 classes
.write(classes_type
[ret
[0]][1] % ("ret"));
1180 classes
.write("\n");
1183 # Sometime one need to keep references of the source
1184 # class in the returned class object.
1185 # See reference_keepers for the list
1187 tclass
= classes_type
[ret
[0]][2]
1188 if reference_keepers
.has_key(tclass
):
1189 list = reference_keepers
[tclass
]
1191 if pref
[0] == classname
:
1192 classes
.write(" __tmp.%s = self\n" %
1195 # Post-processing - just before we return.
1196 if function_post
.has_key(name
):
1197 classes
.write(" %s\n" %
1198 (function_post
[name
]));
1203 classes
.write(" return __tmp\n");
1204 elif converter_type
.has_key(ret
[0]):
1206 # Raise an exception
1208 if functions_noexcept
.has_key(name
):
1210 " if ret is None:return None");
1212 # Post-processing - just before we return.
1213 if function_post
.has_key(name
):
1214 classes
.write(" %s\n" %
1215 (function_post
[name
]));
1217 classes
.write(" return ");
1218 classes
.write(converter_type
[ret
[0]] % ("ret"));
1219 classes
.write("\n");
1221 # For functions returning an integral type there
1222 # are several things that we can do, depending on
1223 # the contents of functions_int_*:
1224 elif is_integral_type (ret
[0]):
1225 if not functions_noexcept
.has_key (name
):
1226 if functions_int_exception_test
.has_key (name
):
1227 test
= functions_int_exception_test
[name
]
1229 test
= functions_int_default_test
1230 if classname
== "virConnect":
1231 classes
.write ((" if " + test
+
1232 ": raise libvirtError ('%s() failed', conn=self)\n") %
1234 elif classname
== "virDomain":
1235 classes
.write ((" if " + test
+
1236 ": raise libvirtError ('%s() failed', dom=self)\n") %
1238 elif classname
== "virNetwork":
1239 classes
.write ((" if " + test
+
1240 ": raise libvirtError ('%s() failed', net=self)\n") %
1242 elif classname
== "virInterface":
1243 classes
.write ((" if " + test
+
1244 ": raise libvirtError ('%s() failed', net=self)\n") %
1246 elif classname
== "virStoragePool":
1247 classes
.write ((" if " + test
+
1248 ": raise libvirtError ('%s() failed', pool=self)\n") %
1250 elif classname
== "virStorageVol":
1251 classes
.write ((" if " + test
+
1252 ": raise libvirtError ('%s() failed', vol=self)\n") %
1255 classes
.write ((" if " + test
+
1256 ": raise libvirtError ('%s() failed')\n") %
1259 # Post-processing - just before we return.
1260 if function_post
.has_key(name
):
1261 classes
.write(" %s\n" %
1262 (function_post
[name
]));
1264 classes
.write (" return ret\n")
1266 elif is_list_type (ret
[0]):
1267 if not functions_noexcept
.has_key (name
):
1268 if functions_list_exception_test
.has_key (name
):
1269 test
= functions_list_exception_test
[name
]
1271 test
= functions_list_default_test
1272 if classname
== "virConnect":
1273 classes
.write ((" if " + test
+
1274 ": raise libvirtError ('%s() failed', conn=self)\n") %
1276 elif classname
== "virDomain":
1277 classes
.write ((" if " + test
+
1278 ": raise libvirtError ('%s() failed', dom=self)\n") %
1280 elif classname
== "virNetwork":
1281 classes
.write ((" if " + test
+
1282 ": raise libvirtError ('%s() failed', net=self)\n") %
1284 elif classname
== "virInterface":
1285 classes
.write ((" if " + test
+
1286 ": raise libvirtError ('%s() failed', net=self)\n") %
1288 elif classname
== "virStoragePool":
1289 classes
.write ((" if " + test
+
1290 ": raise libvirtError ('%s() failed', pool=self)\n") %
1292 elif classname
== "virStorageVol":
1293 classes
.write ((" if " + test
+
1294 ": raise libvirtError ('%s() failed', vol=self)\n") %
1297 classes
.write ((" if " + test
+
1298 ": raise libvirtError ('%s() failed')\n") %
1301 # Post-processing - just before we return.
1302 if function_post
.has_key(name
):
1303 classes
.write(" %s\n" %
1304 (function_post
[name
]));
1306 classes
.write (" return ret\n")
1309 # Post-processing - just before we return.
1310 if function_post
.has_key(name
):
1311 classes
.write(" %s\n" %
1312 (function_post
[name
]));
1314 classes
.write(" return ret\n");
1316 classes
.write("\n");
1317 # Append "<classname>.py" to class def, iff it exists
1319 extra
= open(classname
+ ".py", "r")
1320 classes
.write (" #\n")
1321 classes
.write (" # %s methods from %s.py (hand coded)\n" % (classname
,classname
))
1322 classes
.write (" #\n")
1323 classes
.writelines(extra
.readlines())
1329 # Generate enum constants
1331 for type,enum
in enums
.items():
1332 classes
.write("# %s\n" % type)
1333 items
= enum
.items()
1334 items
.sort(lambda i1
,i2
: cmp(long(i1
[1]),long(i2
[1])))
1335 for name
,value
in items
:
1336 classes
.write("%s = %s\n" % (name
,value
))
1337 classes
.write("\n");
1339 if len(functions_skipped
) != 0:
1340 txt
.write("\nFunctions skipped:\n")
1341 for function
in functions_skipped
:
1342 txt
.write(" %s\n" % function
)
1343 if len(functions_failed
) != 0:
1344 txt
.write("\nFunctions failed:\n")
1345 for function
in functions_failed
:
1346 txt
.write(" %s\n" % function
)
1350 if buildStubs() < 0: