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