diff options
author | Samuel Bronson <naesten@gmail.com> | 2013-04-23 16:06:43 -0400 |
---|---|---|
committer | Samuel Bronson <naesten@gmail.com> | 2013-04-23 17:06:37 -0400 |
commit | 898c4da0e230d1a4c377c45cfc3229bf1ba003e5 (patch) | |
tree | eb015b6023254a8b4167a255af11d5eb5c38b69e /crawl-ref/source/crawl-gdb.py | |
parent | c665ca8bc65ff6140be0e19564d1bbd90610014b (diff) | |
download | crawl-ref-898c4da0e230d1a4c377c45cfc3229bf1ba003e5.tar.gz crawl-ref-898c4da0e230d1a4c377c45cfc3229bf1ba003e5.zip |
Add pretty-printing of flags field for item_def.
Diffstat (limited to 'crawl-ref/source/crawl-gdb.py')
-rw-r--r-- | crawl-ref/source/crawl-gdb.py | 56 |
1 files changed, 55 insertions, 1 deletions
diff --git a/crawl-ref/source/crawl-gdb.py b/crawl-ref/source/crawl-gdb.py index 0cf1395686..49faffda90 100644 --- a/crawl-ref/source/crawl-gdb.py +++ b/crawl-ref/source/crawl-gdb.py @@ -3,6 +3,56 @@ import gdb.printing +## Copied from gdb.printing because, having an initial underscore, +## it's probably not a stable interface... +# A helper class for printing enum types. This class is instantiated +# with a list of enumerators to print a particular Value. +class _EnumInstance: + def __init__(self, enumerators, val): + self.enumerators = enumerators + self.val = val + + def to_string(self): + flag_list = [] + v = long(self.val) + any_found = False + for (e_name, e_value) in self.enumerators: + if v & e_value != 0: + flag_list.append(e_name) + v = v & ~e_value + any_found = True + if not any_found or v != 0: + # Leftover value. + flag_list.append('<unknown: 0x%x>' % v) + return "0x%x [%s]" % (self.val, " | ".join(flag_list)) + +def is_pow2(x): + # From http://stackoverflow.com/questions/600293/600306 + return (x != 0) and ((x & (x - 1)) == 0) + +class FlagsPrinter(gdb.printing.PrettyPrinter): + """Print values of enum types, assuming that every bit is really a + flag, and that other enumerators are just masks/shorthand.""" + + def __init__(self, enum_type): + super(FlagsPrinter, self).__init__(enum_type) + self.initialized = False + + def __call__(self, val): + if not self.initialized: + flags = gdb.lookup_type(self.name) + self.enumerators = [(field.name, field.enumval) + for field in flags.fields() + if is_pow2(field.enumval)] + self.enumerators.sort(key = lambda x: x[1]) + self.initialized = True + + if self.enabled: + return _EnumInstance(self.enumerators, val) + else: + return None + + class NeedLibstdcxxPrinters(Exception): def __str__(self): return """Oops!!! @@ -86,7 +136,7 @@ class item_def_printer: yield f('colour') yield f('rnd') yield f('quantity') - yield f('flags') + yield g('flags', 'item_status_flag_type') yield f('pos') yield f('link') @@ -205,6 +255,10 @@ def build_pretty_printer(): pp.add_printer('CrawlVector', '^CrawlVector$', CrawlVector_printer) pp.add_printer('CrawlStoreValue', '^CrawlStoreValue$', CrawlStoreValue_printer) + # XXX we really want to set this printer on iflags_t, but that doesn't work + pp.add_printer('item_status_flag_type', '^item_status_flag_type$', + FlagsPrinter('item_status_flag_type')) + return pp gdb.printing.register_pretty_printer( |