1# Synthetic children provider example for class MaskedData 2# to use me: 3# command script import ./example.py --allow-reload 4# type synthetic add MaskedData --python-class 5# example.MaskedData_SyntheticChildrenProvider 6 7 8class MaskedData_SyntheticChildrenProvider: 9 def __init__(self, valobj, dict): 10 # remember the SBValue since you will not have another chance to get it 11 # :-) 12 self.valobj = valobj 13 14 def num_children(self): 15 # you could perform calculations involving the SBValue and/or its children to determine this value 16 # here, we have an hardcoded value - but since you have stored the SBValue you could use it to 17 # help figure out the correct thing to return here. if you return a number N, you should be prepared to 18 # answer questions about N children 19 return 4 20 21 def has_children(self): 22 # we simply say True here because we know we have 4 children 23 # in general, you want to make this calculation as simple as possible 24 # and return True if in doubt (you can always return num_children == 0 25 # later) 26 return True 27 28 def get_child_index(self, name): 29 # given a name, return its index 30 # you can return None if you don't know the answer for a given name 31 if name == "value": 32 return 0 33 # here, we are using a reserved C++ keyword as a child name - we could not do that in the source code 34 # but we are free to use the names we like best in the synthetic children provider class 35 # we are also not respecting the order of declaration in the C++ class itself - as long as 36 # we are consistent, we can do that freely 37 if name == "operator": 38 return 1 39 if name == "mask": 40 return 2 41 # this member does not exist in the original class - we will compute its value and show it to the user 42 # when returning synthetic children, there is no need to only stick to 43 # what already exists in memory 44 if name == "apply()": 45 return 3 46 return None # no clue, just say none 47 48 def get_child_at_index(self, index): 49 # precautionary measures 50 if index < 0: 51 return None 52 if index > self.num_children(): 53 return None 54 if not self.valobj.IsValid(): 55 return None 56 if index == 0: 57 return self.valobj.GetChildMemberWithName("value") 58 if index == 1: 59 # fetch the value of the operator 60 op_chosen = self.valobj.GetChildMemberWithName("oper").GetValueAsUnsigned() 61 # if it is a known value, return a descriptive string for it 62 # we are not doing this in the most efficient possible way, but the code is very readable 63 # and easy to maintain - if you change the values on the C++ side, 64 # the same changes must be made here 65 if op_chosen == 0: 66 return self.valobj.CreateValueFromExpression( 67 "operator", '(const char*)"none"' 68 ) 69 elif op_chosen == 1: 70 return self.valobj.CreateValueFromExpression( 71 "operator", '(const char*)"AND"' 72 ) 73 elif op_chosen == 2: 74 return self.valobj.CreateValueFromExpression( 75 "operator", '(const char*)"OR"' 76 ) 77 elif op_chosen == 3: 78 return self.valobj.CreateValueFromExpression( 79 "operator", '(const char*)"XOR"' 80 ) 81 elif op_chosen == 4: 82 return self.valobj.CreateValueFromExpression( 83 "operator", '(const char*)"NAND"' 84 ) 85 elif op_chosen == 5: 86 return self.valobj.CreateValueFromExpression( 87 "operator", '(const char*)"NOR"' 88 ) 89 else: 90 return self.valobj.CreateValueFromExpression( 91 "operator", '(const char*)"unknown"' 92 ) # something else 93 if index == 2: 94 return self.valobj.GetChildMemberWithName("mask") 95 if index == 3: 96 # for this, we must fetch all the other elements 97 # in an efficient implementation, we would be caching this data for 98 # efficiency 99 value = self.valobj.GetChildMemberWithName("value").GetValueAsUnsigned() 100 operator = self.valobj.GetChildMemberWithName("oper").GetValueAsUnsigned() 101 mask = self.valobj.GetChildMemberWithName("mask").GetValueAsUnsigned() 102 # compute the masked value according to the operator 103 if operator == 1: 104 value = value & mask 105 elif operator == 2: 106 value = value | mask 107 elif operator == 3: 108 value = value ^ mask 109 elif operator == 4: 110 value = ~(value & mask) 111 elif operator == 5: 112 value = ~(value | mask) 113 else: 114 pass 115 value &= ( 116 0xFFFFFFFF # make sure Python does not extend our values to 64-bits 117 ) 118 # return it - again, not the most efficient possible way. we should actually be pushing the computed value 119 # into an SBData, and using the SBData to create an SBValue - this 120 # has the advantage of readability 121 return self.valobj.CreateValueFromExpression( 122 "apply()", "(uint32_t)(" + str(value) + ")" 123 ) 124 125 def update(self): 126 # we do not do anything special in update - but this would be the right place to lookup 127 # the data we use in get_child_at_index and cache it 128 pass 129