# Synthetic children provider example for class MaskedData # to use me: # command script import ./example.py --allow-reload # type synthetic add MaskedData --python-class # example.MaskedData_SyntheticChildrenProvider class MaskedData_SyntheticChildrenProvider: def __init__(self, valobj, dict): # remember the SBValue since you will not have another chance to get it # :-) self.valobj = valobj def num_children(self): # you could perform calculations involving the SBValue and/or its children to determine this value # here, we have an hardcoded value - but since you have stored the SBValue you could use it to # help figure out the correct thing to return here. if you return a number N, you should be prepared to # answer questions about N children return 4 def has_children(self): # we simply say True here because we know we have 4 children # in general, you want to make this calculation as simple as possible # and return True if in doubt (you can always return num_children == 0 # later) return True def get_child_index(self, name): # given a name, return its index # you can return None if you don't know the answer for a given name if name == "value": return 0 # here, we are using a reserved C++ keyword as a child name - we could not do that in the source code # but we are free to use the names we like best in the synthetic children provider class # we are also not respecting the order of declaration in the C++ class itself - as long as # we are consistent, we can do that freely if name == "operator": return 1 if name == "mask": return 2 # this member does not exist in the original class - we will compute its value and show it to the user # when returning synthetic children, there is no need to only stick to # what already exists in memory if name == "apply()": return 3 return None # no clue, just say none def get_child_at_index(self, index): # precautionary measures if index < 0: return None if index > self.num_children(): return None if self.valobj.IsValid() == False: return None if index == 0: return self.valobj.GetChildMemberWithName("value") if index == 1: # fetch the value of the operator op_chosen = self.valobj.GetChildMemberWithName( "oper").GetValueAsUnsigned() # if it is a known value, return a descriptive string for it # we are not doing this in the most efficient possible way, but the code is very readable # and easy to maintain - if you change the values on the C++ side, # the same changes must be made here if op_chosen == 0: return self.valobj.CreateValueFromExpression( "operator", '(const char*)"none"') elif op_chosen == 1: return self.valobj.CreateValueFromExpression( "operator", '(const char*)"AND"') elif op_chosen == 2: return self.valobj.CreateValueFromExpression( "operator", '(const char*)"OR"') elif op_chosen == 3: return self.valobj.CreateValueFromExpression( "operator", '(const char*)"XOR"') elif op_chosen == 4: return self.valobj.CreateValueFromExpression( "operator", '(const char*)"NAND"') elif op_chosen == 5: return self.valobj.CreateValueFromExpression( "operator", '(const char*)"NOR"') else: return self.valobj.CreateValueFromExpression( "operator", '(const char*)"unknown"') # something else if index == 2: return self.valobj.GetChildMemberWithName("mask") if index == 3: # for this, we must fetch all the other elements # in an efficient implementation, we would be caching this data for # efficiency value = self.valobj.GetChildMemberWithName( "value").GetValueAsUnsigned() operator = self.valobj.GetChildMemberWithName( "oper").GetValueAsUnsigned() mask = self.valobj.GetChildMemberWithName( "mask").GetValueAsUnsigned() # compute the masked value according to the operator if operator == 1: value = value & mask elif operator == 2: value = value | mask elif operator == 3: value = value ^ mask elif operator == 4: value = ~(value & mask) elif operator == 5: value = ~(value | mask) else: pass value &= 0xFFFFFFFF # make sure Python does not extend our values to 64-bits # return it - again, not the most efficient possible way. we should actually be pushing the computed value # into an SBData, and using the SBData to create an SBValue - this # has the advantage of readability return self.valobj.CreateValueFromExpression( "apply()", '(uint32_t)(' + str(value) + ')') def update(self): # we do not do anything special in update - but this would be the right place to lookup # the data we use in get_child_at_index and cache it pass