1*f6aab3d8Srobert# Formatters for classes that derive from Message. 2*f6aab3d8Srobert# 3*f6aab3d8Srobert# Usage: 4*f6aab3d8Srobert# command script import ./example.py 5*f6aab3d8Srobert# type summary add --expand --recognizer-function --python-function example.message_summary example.is_message_type 6*f6aab3d8Srobert# type synth add --recognizer-function --python-class example.MessageChildProvider example.is_message_type 7*f6aab3d8Srobert 8*f6aab3d8Srobertimport sys 9*f6aab3d8Srobert 10*f6aab3d8Srobertdef is_message_type(t, internal_dict): 11*f6aab3d8Srobert for base in t.get_bases_array(): 12*f6aab3d8Srobert if base.GetName() == "Message": 13*f6aab3d8Srobert return True 14*f6aab3d8Srobert return False 15*f6aab3d8Srobert 16*f6aab3d8Srobertdef message_summary(value, internal_dict): 17*f6aab3d8Srobert # Could have used a summary string as well. All the work is done by the child 18*f6aab3d8Srobert # provider. 19*f6aab3d8Srobert return "Message" 20*f6aab3d8Srobert 21*f6aab3d8Srobertclass MessageChildProvider: 22*f6aab3d8Srobert def __init__(self, value, internal_dict): 23*f6aab3d8Srobert self.value = value 24*f6aab3d8Srobert self.synthetic_children = self._analyze_children(value) 25*f6aab3d8Srobert 26*f6aab3d8Srobert def has_children(self): 27*f6aab3d8Srobert return self.num_children() > 0 28*f6aab3d8Srobert 29*f6aab3d8Srobert def num_children(self): 30*f6aab3d8Srobert return len(self.synthetic_children) 31*f6aab3d8Srobert 32*f6aab3d8Srobert def get_child_index(self, name): 33*f6aab3d8Srobert for index, child in enumerate(self.synthetic_children): 34*f6aab3d8Srobert if child.GetName() == name: 35*f6aab3d8Srobert return index 36*f6aab3d8Srobert return None 37*f6aab3d8Srobert 38*f6aab3d8Srobert def get_child_at_index(self, index): 39*f6aab3d8Srobert return self.synthetic_children[index] 40*f6aab3d8Srobert 41*f6aab3d8Srobert def _rename_sbvalue(self, value): 42*f6aab3d8Srobert # We want to display the field with its original name without a trailing 43*f6aab3d8Srobert # underscore. So we create a new SBValue with the same type and address but 44*f6aab3d8Srobert # a different name. 45*f6aab3d8Srobert name = value.GetName() 46*f6aab3d8Srobert assert name.endswith("_") 47*f6aab3d8Srobert new_name = name[:-1] 48*f6aab3d8Srobert return value.CreateValueFromAddress(new_name, value.GetLoadAddress(), 49*f6aab3d8Srobert value.GetType()) 50*f6aab3d8Srobert 51*f6aab3d8Srobert def _analyze_children(self, value): 52*f6aab3d8Srobert result = [] 53*f6aab3d8Srobert for i in range(value.GetNumChildren()): 54*f6aab3d8Srobert child = value.GetChildAtIndex(i) 55*f6aab3d8Srobert child_name = child.GetName() 56*f6aab3d8Srobert if child_name.startswith("_"): 57*f6aab3d8Srobert continue # Internal field, skip 58*f6aab3d8Srobert # Normal field. Check presence bit. 59*f6aab3d8Srobert presence_bit = value.GetChildMemberWithName("_has_" + child_name) 60*f6aab3d8Srobert if presence_bit.GetValueAsUnsigned() != 0: 61*f6aab3d8Srobert result.append(self._rename_sbvalue(child)) 62*f6aab3d8Srobert return result 63*f6aab3d8Srobert 64