[Scummvm-git-logs] scummvm master -> 16df5b080a2608cb3ab52b7b40e50c01e5914aca
grisenti
noreply at scummvm.org
Tue Sep 12 18:15:52 UTC 2023
This automated email contains information about 1 new commit which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
16df5b080a DEVTOOLS: Add gdb pretty printers for some Common types
Commit: 16df5b080a2608cb3ab52b7b40e50c01e5914aca
https://github.com/scummvm/scummvm/commit/16df5b080a2608cb3ab52b7b40e50c01e5914aca
Author: grisenti (emanuele at grisenti.net)
Date: 2023-09-12T20:15:06+02:00
Commit Message:
DEVTOOLS: Add gdb pretty printers for some Common types
Changed paths:
A devtools/gdb_pretty_printers.py
diff --git a/devtools/gdb_pretty_printers.py b/devtools/gdb_pretty_printers.py
new file mode 100644
index 00000000000..61b26bd616b
--- /dev/null
+++ b/devtools/gdb_pretty_printers.py
@@ -0,0 +1,162 @@
+class StringPrinter:
+ "Prints Common::String and Common::U32String"
+
+ def __init__(self, val):
+ self.val = val
+
+ def to_string(self):
+ return self.val["_str"].string()
+
+ def display_hint(self):
+ return "string"
+
+
+class ArrayPrinter:
+ "Prints Common::Array"
+
+ class _iterator:
+ def __init__(self, start, item_count):
+ self.current_item = start
+ self.item_count = item_count
+ self.current_item_count = 0
+ self.item_size = 8 * start.dereference().type.sizeof
+
+ def __iter__(self):
+ return self
+
+ def __next__(self):
+ if self.current_item_count == self.item_count:
+ raise StopIteration
+ value = self.current_item.dereference()
+ index = self.current_item_count
+ self.current_item_count += 1
+ self.current_item += 1
+ return f"[{index}]", value
+
+ def __init__(self, val):
+ self.val = val
+
+ def to_string(self):
+ size = self.val["_size"]
+ capacity = self.val["_capacity"]
+ return f"{self.val.type.name} of length {size}, capacity {capacity}"
+
+ def children(self):
+ return self._iterator(self.val["_storage"], self.val["_size"])
+
+ def display_hint(self):
+ return "array"
+
+class RBTreeIterator:
+ "Utility iterator for Common::RBTree"
+
+ def __init__(self, leftmost, item_count):
+ self.current_node = leftmost
+ self.item_count = item_count
+ self.current_item_count = 0
+
+ def __iter__(self):
+ return self
+
+ def __next__(self):
+ if self.current_item_count == self.item_count:
+ raise StopIteration
+ value = self.current_node.dereference()["value"]
+ self.current_item_count += 1
+ if self.current_node.dereference()["right"]:
+ while self.current_node.dereference()["left"]:
+ self.current_node = self.current_node.dereference()["left"]
+ else:
+ parent = self.current_node.dereference()["parent"]
+ while parent and parent.dereference()["right"] == self.current_node.dereference()["right"]:
+ self.current_node = parent
+ parent = self.current_node.dereference()["parent"]
+ return value
+
+class StableMapPrinter:
+ "Prints Common::StableMap"
+
+ class _iterator:
+ def __init__(self, rb_tree):
+ self.iter = RBTreeIterator(rb_tree["_leftmost"], rb_tree["_size"])
+ self.count = 0
+
+ def __iter__(self):
+ return self
+
+ def __next__(self):
+ if self.count % 2 == 0:
+ value = next(self.iter)
+ self.current_pair = value
+ item = value["first"]
+ else:
+ item = self.current_pair["second"]
+ self.count += 1
+ return f"{self.count}", item
+
+ def __init__(self, val):
+ self.val = val
+
+ def to_string(self):
+ size = self.val["_items"]["_size"]
+ return f"{self.val.type.name} of length {size}"
+
+ def children(self):
+ return self._iterator(self.val["_items"])
+
+ def display_hint(self):
+ return "map"
+
+
+class ListPrinter:
+ "Prints Common::List"
+
+ class _iterator:
+ def __init__(self, anchor, typename):
+ self.anchor = anchor
+ self.current_node = anchor["_next"].dereference()
+ self.current_item_count = 0
+ self.node_type = gdb.lookup_type(f"{typename}::Node")
+
+ def __iter__(self):
+ return self
+
+ def __next__(self):
+ if self.current_node.address == self.anchor.address:
+ raise StopIteration
+ value = self.current_node.cast(self.node_type)["_data"]
+ index = self.current_item_count
+ self.current_item_count += 1
+ self.current_node = self.current_node["_next"].dereference()
+ return f"[{index}]", value
+
+ def __init__(self, val):
+ self.val = val
+
+ def to_string(self):
+ if self.val["_anchor"]["_next"] == self.val["_anchor"].address:
+ return f"empty {self.val.type.name}"
+ return self.val.type.name
+
+ def children(self):
+ return self._iterator(self.val["_anchor"], self.val.type.name)
+
+ def display_hint(self):
+ return "array"
+
+import gdb.printing
+
+def build_pretty_printer():
+ pp = gdb.printing.RegexpCollectionPrettyPrinter(
+ "Common")
+ pp.add_printer('String', '^Common::String$', StringPrinter)
+ pp.add_printer('U32String', '^Common::U32String$', StringPrinter)
+ pp.add_printer('Array', '^Common::Array<.*>$', ArrayPrinter)
+ pp.add_printer('StableMap', '^Common::StableMap<.*>$', StableMapPrinter)
+ pp.add_printer('List', '^Common::List<.*>$', ListPrinter)
+ return pp
+
+gdb.printing.register_pretty_printer(
+ gdb.current_objfile(),
+ build_pretty_printer()
+)
\ No newline at end of file
More information about the Scummvm-git-logs
mailing list