64 lines
2.0 KiB
Python
64 lines
2.0 KiB
Python
# Formatters for classes that derive from Message.
|
|
#
|
|
# Usage:
|
|
# command script import ./example.py
|
|
# type summary add --expand --recognizer-function --python-function example.message_summary example.is_message_type
|
|
# type synth add --recognizer-function --python-class example.MessageChildProvider example.is_message_type
|
|
|
|
import sys
|
|
|
|
def is_message_type(t, internal_dict):
|
|
for base in t.get_bases_array():
|
|
if base.GetName() == "Message":
|
|
return True
|
|
return False
|
|
|
|
def message_summary(value, internal_dict):
|
|
# Could have used a summary string as well. All the work is done by the child
|
|
# provider.
|
|
return "Message"
|
|
|
|
class MessageChildProvider:
|
|
def __init__(self, value, internal_dict):
|
|
self.value = value
|
|
self.synthetic_children = self._analyze_children(value)
|
|
|
|
def has_children(self):
|
|
return self.num_children() > 0
|
|
|
|
def num_children(self):
|
|
return len(self.synthetic_children)
|
|
|
|
def get_child_index(self, name):
|
|
for index, child in enumerate(self.synthetic_children):
|
|
if child.GetName() == name:
|
|
return index
|
|
return None
|
|
|
|
def get_child_at_index(self, index):
|
|
return self.synthetic_children[index]
|
|
|
|
def _rename_sbvalue(self, value):
|
|
# We want to display the field with its original name without a trailing
|
|
# underscore. So we create a new SBValue with the same type and address but
|
|
# a different name.
|
|
name = value.GetName()
|
|
assert name.endswith("_")
|
|
new_name = name[:-1]
|
|
return value.CreateValueFromAddress(new_name, value.GetLoadAddress(),
|
|
value.GetType())
|
|
|
|
def _analyze_children(self, value):
|
|
result = []
|
|
for i in range(value.GetNumChildren()):
|
|
child = value.GetChildAtIndex(i)
|
|
child_name = child.GetName()
|
|
if child_name.startswith("_"):
|
|
continue # Internal field, skip
|
|
# Normal field. Check presence bit.
|
|
presence_bit = value.GetChildMemberWithName("_has_" + child_name)
|
|
if presence_bit.GetValueAsUnsigned() != 0:
|
|
result.append(self._rename_sbvalue(child))
|
|
return result
|
|
|