|
@@ -1,4 +1,5 @@
|
|
|
import gdb.printing
|
|
|
+import re
|
|
|
|
|
|
def create_iter(item, end, idx):
|
|
|
return vectorPrinter._iterator(item, end, idx)
|
|
@@ -35,12 +36,78 @@ class vectorPrinter:
|
|
|
def children(self):
|
|
|
return self._iterator(self.val['m_arr'], self.val['m_arr'] + self.val['m_size'], 0)
|
|
|
|
|
|
+def _leftmost(node):
|
|
|
+ ret = node
|
|
|
+ while ret['left'] != 0:
|
|
|
+ ret = ret['left'].dereference()
|
|
|
+ return ret
|
|
|
+
|
|
|
+def _next(node):
|
|
|
+ if node['right']:
|
|
|
+ return _leftmost(node['right'].dereference())
|
|
|
+ else:
|
|
|
+ if node['parent'] == 0:
|
|
|
+ return None
|
|
|
+ parent = node['parent'].dereference()
|
|
|
+ if parent['left'] == node.address:
|
|
|
+ return parent
|
|
|
+ ret = node
|
|
|
+ while True:
|
|
|
+ ret = ret['parent'].dereference()
|
|
|
+ if ret['parent'] == 0:
|
|
|
+ return None
|
|
|
+ if ret['parent'].dereference()['left'] == ret.address:
|
|
|
+ break
|
|
|
+ return ret['parent'].dereference()
|
|
|
+
|
|
|
+class mapPrinter:
|
|
|
+ def __init__(self, val):
|
|
|
+ self.val = val
|
|
|
+
|
|
|
+ def to_string(self):
|
|
|
+ return "types::map"
|
|
|
+
|
|
|
+ def display_hint(self):
|
|
|
+ return 'array'
|
|
|
+
|
|
|
+ def children(self):
|
|
|
+ yield '[root]', self.val['root']
|
|
|
+ if self.val['root'] == 0:
|
|
|
+ return
|
|
|
+
|
|
|
+ nd = _leftmost(self.val['root'].dereference())
|
|
|
+ i = 0
|
|
|
+ while True:
|
|
|
+ yield "[%d]" % i, nd['v']
|
|
|
+ nd = _next(nd)
|
|
|
+ i += 1
|
|
|
+ if nd == None:
|
|
|
+ break
|
|
|
+
|
|
|
class stringPrinter:
|
|
|
def __init__(self, val):
|
|
|
self.val = val
|
|
|
|
|
|
def to_string(self):
|
|
|
return self.val['m_arr']
|
|
|
+
|
|
|
+ def children(self):
|
|
|
+ yield 'str', self.val['m_arr']
|
|
|
+
|
|
|
+ if self.val['m_arr'] == 0:
|
|
|
+ return
|
|
|
+
|
|
|
+ yield 'length', self.val['m_size'] - 1
|
|
|
+
|
|
|
+ ptr = self.val['m_arr']
|
|
|
+ i = 0
|
|
|
+
|
|
|
+ while ptr.dereference() != 0:
|
|
|
+ yield '[%d]' % i, ptr.dereference()
|
|
|
+ ptr += 1
|
|
|
+ i += 1
|
|
|
+
|
|
|
+ yield '[%d]' % i, 0
|
|
|
|
|
|
class listPrinter:
|
|
|
def __init__(self, val):
|
|
@@ -53,21 +120,48 @@ class listPrinter:
|
|
|
return 'array'
|
|
|
|
|
|
def children(self):
|
|
|
- node = self.val['head']['next']
|
|
|
+ head = self.val['head']
|
|
|
end = self.val['tail']
|
|
|
+
|
|
|
+ yield '[head]', head
|
|
|
+ yield '[tail]', end
|
|
|
+
|
|
|
+ if head == 0 or end == 0:
|
|
|
+ return
|
|
|
+
|
|
|
+ node = head['next']
|
|
|
idx = 0
|
|
|
while node != end:
|
|
|
yield '[%d]' % idx, node['value']
|
|
|
idx += 1
|
|
|
node = node['next']
|
|
|
|
|
|
-def build_pretty_printer():
|
|
|
- pp = gdb.printing.RegexpCollectionPrettyPrinter("gbos")
|
|
|
- pp.add_printer("vector", "^types::vector<.*?>$", vectorPrinter)
|
|
|
- pp.add_printer("string", "^types::string<.*?>$", stringPrinter)
|
|
|
- pp.add_printer("list", "^types::list<.*?>$", listPrinter)
|
|
|
- return pp
|
|
|
+def build_pretty_printer(val):
|
|
|
+ type = val.type
|
|
|
+
|
|
|
+ if type.code == gdb.TYPE_CODE_REF:
|
|
|
+ type = type.target()
|
|
|
+ if type.code == gdb.TYPE_CODE_PTR:
|
|
|
+ type = type.target()
|
|
|
+
|
|
|
+ type = type.unqualified().strip_typedefs()
|
|
|
+ typename = type.tag
|
|
|
+
|
|
|
+ if typename == None:
|
|
|
+ return None
|
|
|
+
|
|
|
+ if re.compile(r"^types::list<.*?>$").match(typename):
|
|
|
+ return listPrinter(val)
|
|
|
+
|
|
|
+ if re.compile(r"^types::vector<.*?>$").match(typename):
|
|
|
+ return vectorPrinter(val)
|
|
|
+
|
|
|
+ if re.compile(r"^types::string<.*?>$").match(typename):
|
|
|
+ return stringPrinter(val)
|
|
|
+
|
|
|
+ if re.compile(r"^types::map<.*?>$").match(typename):
|
|
|
+ return mapPrinter(val)
|
|
|
+
|
|
|
+ return None
|
|
|
|
|
|
-gdb.printing.register_pretty_printer(
|
|
|
- gdb.current_objfile(),
|
|
|
- build_pretty_printer())
|
|
|
+gdb.pretty_printers.append(build_pretty_printer)
|