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