aboutsummaryrefslogtreecommitdiff
path: root/examples/summaries/cocoa/CFBitVector.py
diff options
context:
space:
mode:
Diffstat (limited to 'examples/summaries/cocoa/CFBitVector.py')
-rw-r--r--examples/summaries/cocoa/CFBitVector.py175
1 files changed, 175 insertions, 0 deletions
diff --git a/examples/summaries/cocoa/CFBitVector.py b/examples/summaries/cocoa/CFBitVector.py
new file mode 100644
index 000000000000..b0c9e7912106
--- /dev/null
+++ b/examples/summaries/cocoa/CFBitVector.py
@@ -0,0 +1,175 @@
+"""
+LLDB AppKit formatters
+
+part of The LLVM Compiler Infrastructure
+This file is distributed under the University of Illinois Open Source
+License. See LICENSE.TXT for details.
+"""
+# summary provider for CF(Mutable)BitVector
+import lldb
+import ctypes
+import lldb.runtime.objc.objc_runtime
+import lldb.formatters.metrics
+import lldb.formatters.Logger
+
+# first define some utility functions
+def byte_index(abs_pos):
+ logger = lldb.formatters.Logger.Logger()
+ return abs_pos/8
+
+def bit_index(abs_pos):
+ logger = lldb.formatters.Logger.Logger()
+ return abs_pos & 7
+
+def get_bit(byte,index):
+ logger = lldb.formatters.Logger.Logger()
+ if index < 0 or index > 7:
+ return None
+ return (byte >> (7-index)) & 1
+
+def grab_array_item_data(pointer,index):
+ logger = lldb.formatters.Logger.Logger()
+ return pointer.GetPointeeData(index,1)
+
+statistics = lldb.formatters.metrics.Metrics()
+statistics.add_metric('invalid_isa')
+statistics.add_metric('invalid_pointer')
+statistics.add_metric('unknown_class')
+statistics.add_metric('code_notrun')
+
+# despite the similary to synthetic children providers, these classes are not
+# trying to provide anything but a summary for a CF*BitVector, so they need not
+# obey the interface specification for synthetic children providers
+class CFBitVectorKnown_SummaryProvider:
+ def adjust_for_architecture(self):
+ logger = lldb.formatters.Logger.Logger()
+ self.uiint_size = self.sys_params.types_cache.NSUInteger.GetByteSize()
+ pass
+
+ def __init__(self, valobj, params):
+ logger = lldb.formatters.Logger.Logger()
+ self.valobj = valobj;
+ self.sys_params = params
+ if not(self.sys_params.types_cache.NSUInteger):
+ if self.sys_params.is_64_bit:
+ self.sys_params.types_cache.NSUInteger = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedLong)
+ else:
+ self.sys_params.types_cache.NSUInteger = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedInt)
+ if not(self.sys_params.types_cache.charptr):
+ self.sys_params.types_cache.charptr = self.valobj.GetType().GetBasicType(lldb.eBasicTypeChar).GetPointerType()
+ self.update();
+
+ def update(self):
+ logger = lldb.formatters.Logger.Logger()
+ self.adjust_for_architecture();
+
+ # we skip the CFRuntimeBase
+ # then the next CFIndex is the count
+ # then we skip another CFIndex and then we get at a byte array
+ # that wraps the individual bits
+
+ def contents(self):
+ logger = lldb.formatters.Logger.Logger()
+ count_vo = self.valobj.CreateChildAtOffset("count",self.sys_params.cfruntime_size,
+ self.sys_params.types_cache.NSUInteger)
+ count = count_vo.GetValueAsUnsigned(0)
+ if count == 0:
+ return '(empty)'
+
+ array_vo = self.valobj.CreateChildAtOffset("data",
+ self.sys_params.cfruntime_size+2*self.uiint_size,
+ self.sys_params.types_cache.charptr)
+
+ data_list = []
+ cur_byte_pos = None
+ for i in range(0,count):
+ if cur_byte_pos == None:
+ cur_byte_pos = byte_index(i)
+ cur_byte = grab_array_item_data(array_vo,cur_byte_pos)
+ cur_byte_val = cur_byte.uint8[0]
+ else:
+ byte_pos = byte_index(i)
+ # do not fetch the pointee data every single time through
+ if byte_pos != cur_byte_pos:
+ cur_byte_pos = byte_pos
+ cur_byte = grab_array_item_data(array_vo,cur_byte_pos)
+ cur_byte_val = cur_byte.uint8[0]
+ bit = get_bit(cur_byte_val,bit_index(i))
+ if (i % 4) == 0:
+ data_list.append(' ')
+ if bit == 1:
+ data_list.append('1')
+ else:
+ data_list.append('0')
+ return ''.join(data_list)
+
+
+class CFBitVectorUnknown_SummaryProvider:
+ def adjust_for_architecture(self):
+ pass
+
+ def __init__(self, valobj, params):
+ logger = lldb.formatters.Logger.Logger()
+ self.valobj = valobj;
+ self.sys_params = params
+ self.update();
+
+ def update(self):
+ logger = lldb.formatters.Logger.Logger()
+ self.adjust_for_architecture();
+
+ def contents(self):
+ logger = lldb.formatters.Logger.Logger()
+ return '<unable to summarize this CFBitVector>'
+
+
+def GetSummary_Impl(valobj):
+ logger = lldb.formatters.Logger.Logger()
+ global statistics
+ class_data,wrapper =lldb.runtime.objc.objc_runtime.Utilities.prepare_class_detection(valobj,statistics)
+ if wrapper:
+ return wrapper
+
+ name_string = class_data.class_name()
+ actual_name = name_string
+
+ logger >> "name string got was " + str(name_string) + " but actual name is " + str(actual_name)
+
+ if class_data.is_cftype():
+ # CFBitVectorRef does not expose an actual NSWrapper type, so we have to check that this is
+ # an NSCFType and then check we are a pointer-to CFBitVectorRef
+ valobj_type = valobj.GetType()
+ if valobj_type.IsValid() and valobj_type.IsPointerType():
+ valobj_type = valobj_type.GetPointeeType()
+ if valobj_type.IsValid():
+ actual_name = valobj_type.GetName()
+ if actual_name == '__CFBitVector' or actual_name == '__CFMutableBitVector':
+ wrapper = CFBitVectorKnown_SummaryProvider(valobj, class_data.sys_params)
+ statistics.metric_hit('code_notrun',valobj)
+ else:
+ wrapper = CFBitVectorUnknown_SummaryProvider(valobj, class_data.sys_params)
+ print actual_name
+ else:
+ wrapper = CFBitVectorUnknown_SummaryProvider(valobj, class_data.sys_params)
+ print name_string
+ statistics.metric_hit('unknown_class',valobj.GetName() + " seen as " + name_string)
+ return wrapper;
+
+def CFBitVector_SummaryProvider (valobj,dict):
+ logger = lldb.formatters.Logger.Logger()
+ provider = GetSummary_Impl(valobj);
+ if provider != None:
+ if isinstance(provider,lldb.runtime.objc.objc_runtime.SpecialSituation_Description):
+ return provider.message()
+ try:
+ summary = provider.contents();
+ except:
+ summary = None
+ logger >> "summary got from provider: " + str(summary)
+ if summary == None or summary == '':
+ summary = '<variable is not CFBitVector>'
+ return summary
+ return 'Summary Unavailable'
+
+def __lldb_init_module(debugger,dict):
+ debugger.HandleCommand("type summary add -F CFBitVector.CFBitVector_SummaryProvider CFBitVectorRef CFMutableBitVectorRef")