diff options
Diffstat (limited to 'src/main-gdb-head.py')
-rw-r--r-- | src/main-gdb-head.py | 75 |
1 files changed, 65 insertions, 10 deletions
diff --git a/src/main-gdb-head.py b/src/main-gdb-head.py index d8f2001..2dac471 100644 --- a/src/main-gdb-head.py +++ b/src/main-gdb-head.py @@ -30,24 +30,57 @@ def get_basic_type(type_): return type_.unqualified() def finish(): - global finish, initial_globals, FastPrinters + global finish, initial_globals, FastPrinters, EnumPrinter final_globals = {id(v):v for v in globals().values()} - diff = final_globals.keys() - initial_globals.keys() \ + diff = set(final_globals.keys()) - set(initial_globals.keys()) \ - {'finish', 'initial_globals', 'FastPrinters'} fp = FastPrinters() + ep = EnumPrinter # After this, don't access any more globals in this function. - del finish, initial_globals, FastPrinters + del finish, initial_globals, FastPrinters, EnumPrinter for i in diff: v = final_globals[i] if hasattr(v, 'children') or hasattr(v, 'to_string'): fp.add_printer(v) - gdb.current_objfile().pretty_printers.append(fp) - print('Added %d custom printers for %s' - % (len(fp.printers), gdb.current_objfile().filename)) + obj = gdb.current_objfile() + if obj is None: + obj = gdb + filename = '<unknown>' + else: + filename = obj.filename + obj.pretty_printers.append(fp) + obj.pretty_printers.append(ep) + print('Added %d+1 custom printers for %s' + % (len(fp.printers), filename)) + +class EnumPrinter(object): + __slots__ = ('_value') + name = 'enum-class' + enabled = True + + def __new__(cls, v): + type = get_basic_type(v.type) + if type.code != gdb.TYPE_CODE_ENUM: + return None + return object.__new__(cls) + + def __init__(self, v): + self._value = v + + def to_string(self): + v = self._value + self.__class__.enabled = False + try: + name = str(v) + finally: + self.__class__.enabled = True + name = name.split('::')[-1] + scope = get_basic_type(v.type).tag + return '%s::%s' % (scope, name) class FastPrinters(object): ''' printer dispatch the way gdb *should* have done it @@ -63,7 +96,7 @@ class FastPrinters(object): assert hasattr(cls, 'enabled') # TODO: check if the class name exists # this is really hard since templates are involved - self.printers[cls.name] = cls + self.printers[(cls.name, getattr(cls, 'depth', 0))] = cls @property def subprinters(self): @@ -76,14 +109,36 @@ class FastPrinters(object): name, changed = __pattern.subn('', name) return name + def get_tag_and_depth(self, type): + depth = 0 + while True: + type = get_basic_type(type) + if type.code != gdb.TYPE_CODE_PTR: + break + type = type.target() + depth += 1 + return (str(type), depth) + def __call__(self, value): - stype = get_basic_type(value.type).tag - #dtype = get_basic_type(value.dynamic_type).tag + (stype, depth) = self.get_tag_and_depth(value.type) + #(dtype, _) = self.get_tag_and_depth(value.dynamic_type) if stype is None: return stype = self.strip_templates(stype) - p = self.printers.get(stype) + p = self.printers.get((stype, depth)) if p is not None and p.enabled: return p(value) return None + +class char(object): + __slots__ = ('_value') + name = 'char' + depth = 1 + enabled = True + + def __init__(self, value): + self._value = value + + def to_string(self): + return self._value.lazy_string() |