aboutsummaryrefslogtreecommitdiff
path: root/examples/summaries/cocoa/NSDate.py
diff options
context:
space:
mode:
Diffstat (limited to 'examples/summaries/cocoa/NSDate.py')
-rw-r--r--examples/summaries/cocoa/NSDate.py269
1 files changed, 269 insertions, 0 deletions
diff --git a/examples/summaries/cocoa/NSDate.py b/examples/summaries/cocoa/NSDate.py
new file mode 100644
index 000000000000..4dd63b4a5c32
--- /dev/null
+++ b/examples/summaries/cocoa/NSDate.py
@@ -0,0 +1,269 @@
+"""
+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.
+"""
+# example summary provider for NSDate
+# the real summary is now C++ code built into LLDB
+import lldb
+import ctypes
+import lldb.runtime.objc.objc_runtime
+import lldb.formatters.metrics
+import struct
+import time
+import datetime
+import CFString
+import lldb.formatters.Logger
+
+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')
+
+# Python promises to start counting time at midnight on Jan 1st on the epoch year
+# hence, all we need to know is the epoch year
+python_epoch = time.gmtime(0).tm_year
+
+osx_epoch = datetime.date(2001,1,1).timetuple()
+
+def mkgmtime(t):
+ logger = lldb.formatters.Logger.Logger()
+ return time.mktime(t)-time.timezone
+
+osx_epoch = mkgmtime(osx_epoch)
+
+def osx_to_python_time(osx):
+ logger = lldb.formatters.Logger.Logger()
+ if python_epoch <= 2001:
+ return osx + osx_epoch
+ else:
+ return osx - osx_epoch
+
+# represent a struct_time as a string in the format used by Xcode
+def xcode_format_time(X):
+ logger = lldb.formatters.Logger.Logger()
+ return time.strftime('%Y-%m-%d %H:%M:%S %Z',X)
+
+# represent a count-since-epoch as a string in the format used by Xcode
+def xcode_format_count(X):
+ logger = lldb.formatters.Logger.Logger()
+ return xcode_format_time(time.localtime(X))
+
+# despite the similary to synthetic children providers, these classes are not
+# trying to provide anything but the summary for NSDate, so they need not
+# obey the interface specification for synthetic children providers
+class NSTaggedDate_SummaryProvider:
+ def adjust_for_architecture(self):
+ pass
+
+ def __init__(self, valobj, info_bits, data, params):
+ logger = lldb.formatters.Logger.Logger()
+ self.valobj = valobj;
+ self.sys_params = params
+ self.update();
+ # NSDate is not using its info_bits for info like NSNumber is
+ # so we need to regroup info_bits and data
+ self.data = ((data << 8) | (info_bits << 4))
+
+ def update(self):
+ logger = lldb.formatters.Logger.Logger()
+ self.adjust_for_architecture();
+
+ def value(self):
+ logger = lldb.formatters.Logger.Logger()
+ # the value of the date-time object is wrapped into the pointer value
+ # unfortunately, it is made as a time-delta after Jan 1 2001 midnight GMT
+ # while all Python knows about is the "epoch", which is a platform-dependent
+ # year (1970 of *nix) whose Jan 1 at midnight is taken as reference
+ value_double = struct.unpack('d', struct.pack('Q', self.data))[0]
+ if value_double == -63114076800.0:
+ return '0001-12-30 00:00:00 +0000'
+ return xcode_format_count(osx_to_python_time(value_double))
+
+
+class NSUntaggedDate_SummaryProvider:
+ def adjust_for_architecture(self):
+ 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.double):
+ self.sys_params.types_cache.double = self.valobj.GetType().GetBasicType(lldb.eBasicTypeDouble)
+ self.update()
+
+ def update(self):
+ logger = lldb.formatters.Logger.Logger()
+ self.adjust_for_architecture();
+
+ def offset(self):
+ logger = lldb.formatters.Logger.Logger()
+ return self.sys_params.pointer_size
+
+ def value(self):
+ logger = lldb.formatters.Logger.Logger()
+ value = self.valobj.CreateChildAtOffset("value",
+ self.offset(),
+ self.sys_params.types_cache.double)
+ value_double = struct.unpack('d', struct.pack('Q', value.GetData().uint64[0]))[0]
+ if value_double == -63114076800.0:
+ return '0001-12-30 00:00:00 +0000'
+ return xcode_format_count(osx_to_python_time(value_double))
+
+class NSCalendarDate_SummaryProvider:
+ def adjust_for_architecture(self):
+ 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.double):
+ self.sys_params.types_cache.double = self.valobj.GetType().GetBasicType(lldb.eBasicTypeDouble)
+ self.update()
+
+ def update(self):
+ logger = lldb.formatters.Logger.Logger()
+ self.adjust_for_architecture();
+
+ def offset(self):
+ logger = lldb.formatters.Logger.Logger()
+ return 2*self.sys_params.pointer_size
+
+ def value(self):
+ logger = lldb.formatters.Logger.Logger()
+ value = self.valobj.CreateChildAtOffset("value",
+ self.offset(),
+ self.sys_params.types_cache.double)
+ value_double = struct.unpack('d', struct.pack('Q', value.GetData().uint64[0]))[0]
+ return xcode_format_count(osx_to_python_time(value_double))
+
+class NSTimeZoneClass_SummaryProvider:
+ def adjust_for_architecture(self):
+ 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.voidptr):
+ self.sys_params.types_cache.voidptr = self.valobj.GetType().GetBasicType(lldb.eBasicTypeVoid).GetPointerType()
+ self.update()
+
+ def update(self):
+ logger = lldb.formatters.Logger.Logger()
+ self.adjust_for_architecture();
+
+ def offset(self):
+ logger = lldb.formatters.Logger.Logger()
+ return self.sys_params.pointer_size
+
+ def timezone(self):
+ logger = lldb.formatters.Logger.Logger()
+ tz_string = self.valobj.CreateChildAtOffset("tz_name",
+ self.offset(),
+ self.sys_params.types_cache.voidptr)
+ return CFString.CFString_SummaryProvider(tz_string,None)
+
+class NSUnknownDate_SummaryProvider:
+ def adjust_for_architecture(self):
+ pass
+
+ def __init__(self, valobj):
+ logger = lldb.formatters.Logger.Logger()
+ self.valobj = valobj;
+ self.update()
+
+ def update(self):
+ logger = lldb.formatters.Logger.Logger()
+ self.adjust_for_architecture();
+
+ def value(self):
+ logger = lldb.formatters.Logger.Logger()
+ stream = lldb.SBStream()
+ self.valobj.GetExpressionPath(stream)
+ expr = "(NSString*)[" + stream.GetData() + " description]"
+ num_children_vo = self.valobj.CreateValueFromExpression("str",expr);
+ if num_children_vo.IsValid():
+ return num_children_vo.GetSummary()
+ return '<variable is not NSDate>'
+
+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()
+ logger >> "class name is: " + str(name_string)
+
+ if name_string == 'NSDate' or name_string == '__NSDate' or name_string == '__NSTaggedDate':
+ if class_data.is_tagged():
+ wrapper = NSTaggedDate_SummaryProvider(valobj,class_data.info_bits(),class_data.value(), class_data.sys_params)
+ statistics.metric_hit('code_notrun',valobj)
+ else:
+ wrapper = NSUntaggedDate_SummaryProvider(valobj, class_data.sys_params)
+ statistics.metric_hit('code_notrun',valobj)
+ elif name_string == 'NSCalendarDate':
+ wrapper = NSCalendarDate_SummaryProvider(valobj, class_data.sys_params)
+ statistics.metric_hit('code_notrun',valobj)
+ elif name_string == '__NSTimeZone':
+ wrapper = NSTimeZoneClass_SummaryProvider(valobj, class_data.sys_params)
+ statistics.metric_hit('code_notrun',valobj)
+ else:
+ wrapper = NSUnknownDate_SummaryProvider(valobj)
+ statistics.metric_hit('unknown_class',valobj.GetName() + " seen as " + name_string)
+ return wrapper;
+
+
+def NSDate_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.value();
+ except:
+ summary = None
+ if summary == None:
+ summary = '<variable is not NSDate>'
+ return str(summary)
+ return 'Summary Unavailable'
+
+def NSTimeZone_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.timezone();
+ except:
+ summary = None
+ logger >> "got summary " + str(summary)
+ if summary == None:
+ summary = '<variable is not NSTimeZone>'
+ return str(summary)
+ return 'Summary Unavailable'
+
+
+def CFAbsoluteTime_SummaryProvider (valobj,dict):
+ logger = lldb.formatters.Logger.Logger()
+ try:
+ value_double = struct.unpack('d', struct.pack('Q', valobj.GetData().uint64[0]))[0]
+ return xcode_format_count(osx_to_python_time(value_double))
+ except:
+ return 'Summary Unavailable'
+
+
+def __lldb_init_module(debugger,dict):
+ debugger.HandleCommand("type summary add -F NSDate.NSDate_SummaryProvider NSDate")
+ debugger.HandleCommand("type summary add -F NSDate.CFAbsoluteTime_SummaryProvider CFAbsoluteTime")
+ debugger.HandleCommand("type summary add -F NSDate.NSTimeZone_SummaryProvider NSTimeZone CFTimeZoneRef")
+