def handle_opaque_types(self): for tag in self.get_opaque_types(): mod, args = parse_string(tag) # just create a "fake type". self.objects[tag] = { 'tag': tag, 'class': {'STRUCT': 'Struct', 'UNION': 'Union'}[mod], 'name': args[0], # TODO? 'members': [], 'opaque': True, }
def generate_c_name(self, obj): """ Return the C name of the babbisch object *obj*. If naming is impossible (e.g. for unnamed structs), raise ``NamingImpossibleError``. """ # For structs and unions, it's just "struct %s" or "enum %s" if obj['class'] in ('Struct', 'Union', 'Enum'): mod, args = parse_string(obj['tag']) # Is it unnamed? if args[0].startswith('!Unnamed'): raise NamingImpossibleError("Can't be named: %r" % obj) elif args[0].startswith('!'): raise WTFError('WTF is this? %s %r' % (args[0], obj)) # Is it opaque? If yes, don't create a C name, please. # Because if we do, it will appear in the C source, and # *_class() will do a sizeof(), and everyone will be sad :( if obj.get('opaque', False): raise NamingImpossibleError("Can't be named: %r" % obj) # Okay. Please do it. def _struct(): return 'struct %s' % obj['name'] def _union(): return 'union %s' % obj['name'] def _enum(): return 'enum %s' % obj['name'] return { 'Struct': _struct, 'Union': _union, 'Enum': _enum, }[obj['class']]() # For typedefs, it's just the tag (name). elif obj['class'] == 'Typedef': return obj['tag'] # For functions, it's the name. elif obj['class'] == 'Function': return obj['name'] else: raise WTFError('Unknown type: %r' % obj)
def get_opaque_types(self): """ yield tags of opaque (i.e. unknown) types. """ for obj in self.objects.copy().itervalues(): # only handle typedefs ... if obj['class'] == 'Typedef': # get the first, typedef tag tag = obj['target'] while '(' in tag: mod, args = parse_string(tag) # is it wrapping a struct or union that is unknown? if (mod in ('STRUCT', 'UNION') and tag not in self.objects): # then it's opaque. yield tag break # proceed. tag = translate(args[0])
def get_ooc_type(self, tag): """ get the ooc type from the tag *tag*. It might be nested. And might be a pointer. Or an array. Whatever! It can be *anything*! """ # is it artificial? if yes, we already have a type. if tag in self.artificial: return self.artificial[tag] # is it an enum? TODO: not here, please :( elif tag.startswith('ENUM('): return 'Int' # is it a real object? elif tag in self.objects: return self.objects[tag]['ooc_name'] # nope. :( else: if '(' in tag: mod, args = parse_string(tag) def _pointer(): # A pointer to a function type is a Func. try: if args[0][0] == 'FUNCTIONTYPE': return 'Func' except IndexError: pass try: return self.get_ooc_type(translate(args[0])) + '*' except WTFError: # That might work well for unknown types. # TODO: print a message to stderr return 'Pointer' def _const(): return 'const %s' % self.get_ooc_type(translate(args[0])) def _array(): # TODO: that looks incorrect. return self.get_ooc_type(translate(args[0])) + '*' def _ignore(): return self.get_ooc_type(translate(args[0])) def _functiontype(): return 'Func' # TODO: correct? try: return { 'POINTER': _pointer, 'CONST': _const, 'ARRAY': _array, 'FUNCTIONTYPE': _functiontype, # Ignore `volatile` + `restrict` storage type. 'VOLATILE': _ignore, 'RESTRICT': _ignore, }[mod]() except KeyError: raise WTFError('WTF tag is this? %r' % tag) else: #raise WTFError('WTF tag is this? %r' % tag) return 'Pointer' # TODO: not so good