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