| # 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 |