bump product version to 5.0.4.1
[LibreOffice.git] / solenv / gdb / libreoffice / util / uno.py
bloba80fdd856d0d0f8900e3c1e03de5a1fc56e38f7e
1 # -*- tab-width: 4; indent-tabs-mode: nil; py-indent-offset: 4 -*-
3 # This file is part of the LibreOffice project.
5 # This Source Code Form is subject to the terms of the Mozilla Public
6 # License, v. 2.0. If a copy of the MPL was not distributed with this
7 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
10 import gdb
11 import re
12 import six
14 class UnsupportedType(Exception):
15 '''Represents exception thrown when an unsupported UNO type(like
16 array or union) is used.'''
18 def __init__(self, type):
19 self.type = type
21 class UnknownType(Exception):
22 '''Represents exception thrown when an unknown UNO type is used.'''
24 def __init__(self, type):
25 self.type = type
27 class TypeClass(object):
28 '''Represents type class of UNO type.'''
30 # type class of void
31 VOID = 0
32 # type class of char
33 CHAR = 1
34 # type class of boolean
35 BOOLEAN = 2
36 # type class of byte
37 BYTE = 3
38 # type class of short
39 SHORT = 4
40 # type class of unsigned short
41 UNSIGNED_SHORT = 5
42 # type class of long
43 LONG = 6
44 # type class of unsigned long
45 UNSIGNED_LONG = 7
46 # type class of hyper
47 HYPER = 8
48 # type class of unsigned hyper
49 UNSIGNED_HYPER = 9
50 # type class of float
51 FLOAT = 10
52 # type class of double
53 DOUBLE = 11
54 # type class of string
55 STRING = 12
56 # type class of type
57 TYPE = 13
58 # type class of any
59 ANY = 14
60 # type class of enum
61 ENUM = 15
62 # type class of typedef
63 TYPEDEF = 16
64 # type class of struct
65 STRUCT = 17
67 # type class of exception
68 EXCEPTION = 19
69 # type class of sequence
70 SEQUENCE = 20
72 # type class of interface
73 INTERFACE = 22
74 # type class of service (not implemented)
75 SERVICE = 23
76 # type class of module (not implemented)
77 MODULE = 24
78 # type class of interface method
79 INTERFACE_METHOD = 25
80 # type class of interface attribute
81 INTERFACE_ATTRIBUTE = 26
82 # type class of unknown type
83 UNKNOWN = 27
84 # type class of properties
85 PROPERTY = 28
86 # type class of constants
87 CONSTANT = 29
88 # type class of constants groups
89 CONSTANTS = 30
90 # type class of singletons
91 SINGLETON = 31
93 class TemplateType(object):
95 def __init__(self, template, *args):
96 self.template = template
97 self.args = args
99 def __str__(self):
100 argtypes = [str(gdb.lookup_type(arg).strip_typedefs()) for arg in self.args]
101 return self.template + '<' + ', '.join(argtypes) + '>'
103 class Type(object):
104 '''Describes a UNO type.'''
106 def __init__(self, typeclass, tag):
107 '''Constructs a new Type.
108 @param[in] typeclass value of com::sun::star::uno::TypeClass
109 @param[in] tag UNO name of the type
111 self.typeclass = typeclass
112 self.tag = tag
113 # C++ name of the type
114 self.typename = None
116 def type(self):
117 '''Gets gdb.Type for the type'''
118 if self.typename:
119 return gdb.lookup_type(str(self.typename))
120 return None
122 @staticmethod
123 def uno2cpp(typename):
124 return str(typename).replace('.', '::')[1:-1]
126 def strip_typedefs(self):
127 copy = self.copy()
128 copy.typename = self._strip_typedefs(self.typename)
129 return copy
131 def _strip_typedefs(self, typename):
132 template_args = re.compile('([^<]+)(<.*>)')
133 match = template_args.match(typename)
134 type = self._lookup_type(match.group(1))
135 types = []
136 if match.group(2):
137 list_delim = re.compile(', *')
138 # FIXME: this does not work with nested templates
139 for arg in match.group(2).split(list_delim):
140 types.append(self._lookup_type(arg))
142 typename = str(type)
143 if not types.empty():
144 typename += '<' + types.join(', ') + '>'
146 return typename
148 def _lookup_type(self, typename):
149 if typename != '':
150 type = gdb.lookup_type(typename)
151 if type:
152 type = type.strip_typedefs()
153 return type
155 def make_uno_type(val):
156 '''Creates a UNO type from gdb.Value of type
157 com::sun::star::uno::Type, typelib_TypeDescription, or
158 typelib_TypeDescriptionReference
161 cssu_type = 'com::sun::star::uno::Type'
162 type_desc = '_typelib_TypeDescription'
163 type_descs =(
164 type_desc,
165 '_typelib_CompoundTypeDescription',
166 '_typelib_StructTypeDescription',
167 '_typelib_IndirectTypeDescription',
168 '_typelib_EnumTypeDescription',
169 '_typelib_InterfaceMemberTypeDescription',
170 '_typelib_InterfaceMethodTypeDescription',
171 '_typelib_InterfaceAttributeTypeDescription',
172 '_typelib_InterfaceTypeDescription'
174 type_desc_ref = '_typelib_TypeDescriptionReference'
176 type = val.type.strip_typedefs()
178 if type.tag == cssu_type:
179 pvalue = val['_pType']
180 assert pvalue
181 val = pvalue.dereference()
182 type = val.type.strip_typedefs()
184 while type.tag == type_desc_ref:
185 pvalue = val['pType']
186 assert pvalue
187 val = pvalue.dereference()
188 type = val.type.strip_typedefs()
190 if type.tag not in type_descs:
191 return None
193 # determination of the UNO type
194 full_val = val
195 if type.tag != type_desc:
196 while 'aBase' in val:
197 val = val['aBase']
198 type_class = int(val['eTypeClass'])
199 name = val['pTypeName'].dereference()
200 uno_type = None
201 if type_class == TypeClass.VOID:
202 uno_type = VoidType()
203 elif type_class == TypeClass.CHAR:
204 uno_type = PrimitiveType(type_class, name, 'sal_Char')
205 elif type_class == TypeClass.BOOLEAN:
206 uno_type = PrimitiveType(type_class, name, 'sal_Bool')
207 elif type_class == TypeClass.BYTE:
208 uno_type = PrimitiveType(type_class, name, 'sal_Int8')
209 elif type_class == TypeClass.SHORT:
210 uno_type = PrimitiveType(type_class, name, 'sal_Int16')
211 elif type_class == TypeClass.UNSIGNED_SHORT:
212 uno_type = PrimitiveType(type_class, name, 'sal_uInt16')
213 elif type_class == TypeClass.LONG:
214 uno_type = PrimitiveType(type_class, name, 'sal_Int32')
215 elif type_class == TypeClass.UNSIGNED_LONG:
216 uno_type = PrimitiveType(type_class, name, 'sal_uInt32')
217 elif type_class == TypeClass.HYPER:
218 uno_type = PrimitiveType(type_class, name, 'sal_Int64')
219 elif type_class == TypeClass.UNSIGNED_HYPER:
220 uno_type = PrimitiveType(type_class, name, 'sal_uInt64')
221 elif type_class == TypeClass.FLOAT:
222 uno_type = PrimitiveType(type_class, name, 'float')
223 elif type_class == TypeClass.DOUBLE:
224 uno_type = PrimitiveType(type_class, name, 'double')
225 elif type_class == TypeClass.STRING:
226 uno_type = PrimitiveType(type_class, name, 'rtl::OUString')
227 elif type_class == TypeClass.TYPE:
228 uno_type = PrimitiveType(type_class, name, 'com::sun::star::uno::Type')
229 elif type_class == TypeClass.ANY:
230 uno_type = PrimitiveType(type_class, name, 'com::sun::star::uno::Any')
231 elif type_class == TypeClass.ENUM:
232 uno_type = EnumType(val, full_val)
233 elif type_class == TypeClass.TYPEDEF:
234 pass
235 elif type_class == TypeClass.STRUCT:
236 uno_type = StructType(val, full_val)
237 elif type_class == TypeClass.EXCEPTION:
238 uno_type = CompoundType(val, full_val)
239 elif type_class == TypeClass.SEQUENCE:
240 uno_type = IndirectType(val, full_val)
241 elif type_class == TypeClass.INTERFACE:
242 uno_type = InterfaceType(val, full_val)
243 elif type_class == TypeClass.SERVICE:
244 raise UnsupportedType('service')
245 elif type_class == TypeClass.MODULE:
246 raise UnsupportedType('module')
247 elif type_class == TypeClass.INTERFACE_METHOD:
248 uno_type = InterfaceMethodType(val, full_val)
249 elif type_class == TypeClass.INTERFACE_ATTRIBUTE:
250 uno_type = InterfaceAttributeType(val, full_val)
251 elif type_class == TypeClass.UNKNOWN:
252 raise UnknownType(type)
253 elif type_class == TypeClass.PROPERTY:
254 pass
255 elif type_class == TypeClass.CONSTANT:
256 pass
257 elif type_class == TypeClass.CONSTANTS:
258 pass
259 elif type_class == TypeClass.SINGLETON:
260 pass
261 else:
262 raise UnknownType(type)
264 assert uno_type
265 return uno_type
267 def uno_cast(type, val):
268 '''Casts val or pointer to UNO type represented by type'''
269 if val.type.code == gdb.TYPE_CODE_PTR:
270 return val.cast(type.type().pointer())
271 else:
272 return val.cast(type.type())
274 class VoidType(Type):
276 def __init__(self):
277 super(VoidType, self).__init__(TypeClass.VOID, "void")
278 self.typename = "void"
280 class PrimitiveType(Type):
282 def __init__(self, typeclass, typename_uno, typename_cpp):
283 super(PrimitiveType, self).__init__(typeclass, typename_uno)
284 self.typename = str(typename_cpp)
286 class CompoundType(Type):
288 def __init__(self, type, full_type):
289 super(CompoundType, self).__init__(type['eTypeClass'], type['pTypeName'].dereference())
290 self.typename = self.uno2cpp(self.tag)
291 self._type = full_type
293 class _iterator(six.Iterator):
295 def __init__(self, count, types, names):
296 self.count = count
297 self.members = members
298 self.names = names
299 self.pos = 0
301 def __iter__(self):
302 return self
304 def __next__(self):
305 assert self.pos >= 0 and self.pos <= self.count
306 if self.pos == self.count:
307 raise StopIteration
309 pmember = self.members[self.pos]
310 assert pmember
311 pname = self.names[self.i]
312 assert pname
313 self.pos = self.pos + 1
314 member = make_uno_type(pmember.dereference())
315 assert member
316 name = str(pname.dereference())
317 return (name, member)
319 def attributes(self):
320 return _iterator(self._type['nMembers'], self._type['ppTypeRefs'],
321 self._type['ppMemberNames'])
323 class StructType(CompoundType):
325 def __init__(self, type, full_type):
326 full_type = full_type.cast(gdb.lookup_type('_typelib_StructTypeDescription'))
327 super(StructType, self).__init__(type, full_type['aBase'])
329 class IndirectType(Type):
331 def __init__(self, type, full_type):
332 super(IndirectType, self).__init__(type['eTypeClass'], type['pTypeName'].dereference())
333 full_type = full_type.cast(gdb.lookup_type('_typelib_IndirectTypeDescription'))
334 pelem = full_type['pType']
335 assert pelem
336 self.element = make_uno_type(pelem.dereference())
337 assert self.element
338 self.typename = TemplateType('com::sun::star::uno::Sequence', self.element.typename)
340 class EnumType(Type):
342 def __init__(self, type, full_type):
343 super(EnumType, self).__init__(TypeClass.ENUM, type['pTypeName'].dereference())
344 self.typename = self.uno2cpp(self.tag)
345 self._type = full_type.cast(gdb.lookup_type('_typelib_EnumTypeDescription'))
347 class _iterator(six.Iterator):
349 def __init__(self, count, values, names):
350 self.count = count
351 self.values = values
352 self.names = names
353 self.pos = 0
355 def __iter__(self):
356 return self
358 def __next__(self):
359 assert self.pos >= 0 and self.pos <= self.count
360 if self.pos == self.count:
361 raise StopIteration
363 pvalue = self.values[self.pos]
364 assert pvalue
365 pname = self.names[self.pos]
366 assert pname
367 self.pos = self.pos + 1
368 val = int(pvalue.dereference())
369 name = str(pname.dereference())
370 return (name, val)
372 def values(self):
373 return _iterator(self._type['nEnumValues'],
374 self._type['ppEnumNames'], self._type['pEnumValues'])
376 def default_value(self):
377 return self._type['nDefaultEnumValue']
379 class InterfaceMemberType(Type):
381 def __init__(self, type, full_type):
382 super(InterfaceMemberType, self).__init__(type['eTypeClass'], type['pTypeName'].dereference())
383 (interface, delim, member) = self.tag.partition('::')
384 self.typename = self.uno2cpp(interface) + '::*' + member
385 full_type = full_type.cast(gdb.lookup_type('_typelib_InterfaceMemberTypeDescription'))
386 self.position = full_type['nPosition']
387 pname = full_type['pMemberName']
388 assert pname
389 self.name = pname.dereference()
391 class InterfaceMethodType(InterfaceMemberType):
393 def __init__(self, type, full_type):
394 full_type = full_type.cast(gdb.lookup_type('_typelib_InterfaceMethodTypeDescription'))
395 super(InterfaceMethodType, self).__init__(type, full_type['aBase'])
396 pret = full_type['pReturnTypeRef']
397 assert pret
398 self.return_type = make_uno_type(pret.dereference())
399 assert self.return_type
400 self.oneway = full_type['bOneWay']
401 self._type = full_type
403 class _iterator(six.Iterator):
405 def __init__(self, count, values):
406 self.count = count
407 self.values = values
408 self.pos = 0
409 assert values
411 def __iter__(self):
412 return self
414 def __next__(self):
415 assert self.pos >= 0 and self.pos <= self.count
416 if self.pos == self.count:
417 raise StopIteration
419 val = self.values[self.pos]
420 self.pos = self.pos + 1
421 return val
423 class parameter(tuple):
425 def __init__(self, type):
426 self.__init_tuple(type)
427 self.input = type['bIn']
428 self.output = type['bOut']
430 def _init_tuple(self, type):
431 pname = self['pName']
432 assert pname
433 ptype = self['pTypeRef']
434 assert ptype
435 name = str(pname.dereference())
436 type = make_uno_type(ptype.dereference())
437 assert type
438 super(parameter, self).__init__(name, type)
440 def parameters(self):
441 for param in _iterator(self._type['nParams'], self._type['pParams']):
442 yield parameter(param)
444 def exceptions(self):
445 def make_exception(self, pex):
446 assert pex
447 ex = make_uno_type(pex.dereference())
448 assert ex
449 return ex
451 for ex in _iterator(
452 self._type['nExceptions'], self._type['ppExceptions']):
453 yield make_exception(ex)
455 class InterfaceAttributeType(InterfaceMemberType):
457 def __init__(self, type, full_type):
458 full_type = full_type.cast(gdb.lookup_type('_typelib_InterfaceAttributeTypeDescription'))
459 super(InterfaceAttributeType, self).__init__(type, full_type['aBase'])
460 self.readonly = full_type['bReadOnly']
461 ptype = full_type['pAttributeTypeRef']
462 assert ptype
463 self.type = make_uno_type(ptype.dereference())
464 assert self.type
466 class MembersNotInitialized(Exception):
467 '''Represents exception raised when interface type' members haven't
468 been initialized(i.e. just level 1 initialization has been
469 performed)'''
470 pass
472 class InterfaceType(Type):
474 def __init__(self, type, full_type):
475 super(InterfaceType, self).__init__(TypeClass.INTERFACE, type['pTypeName'].dereference())
476 assert int(type['eTypeClass']) == TypeClass.INTERFACE
477 self.typename = self.uno2cpp(self.tag)
478 full_type = full_type.cast(gdb.lookup_type('_typelib_InterfaceTypeDescription'))
479 self.uik = full_type['aUik']
480 self._type = full_type
482 class _iterator(six.Iterator):
484 def __init__(self, count, values):
485 assert values
486 self.count = count
487 self.values = values
488 self.pos = 0
490 def __iter__(self):
491 return self
493 def __next__(self):
494 assert self.pos >= 0 and self.pos <= self.count
495 pvalue = self.values[self.pos]
496 assert pvalue
497 self.pos = self.pos + 1
498 uno = make_uno_type(pvalue.dereference())
499 assert uno
500 return uno
502 def members(self):
503 return __members(self._type['nMembers'], self._type['ppMembers'])
505 def all_members(self):
506 return __members(self._type['nAllMembers'], self._type['ppAllMembers'])
508 def __members(count, values):
509 if values == 0:
510 raise MembersNotInitialized
511 return _iterator(count, values)
513 def bases(self):
514 return _iterator(self._type['nBaseTypes'], self._type['ppBaseTypes'])
516 # vim:set shiftwidth=4 softtabstop=4 expandtab: