blob: ae1ff6b432b2f6fe1b3d08e23d1b34ee2709726d [file] [log] [blame]
Enrico Granata3f1052b2012-03-13 21:52:00 +00001"""
2LLDB AppKit formatters
3
4part of The LLVM Compiler Infrastructure
5This file is distributed under the University of Illinois Open Source
6License. See LICENSE.TXT for details.
7"""
Enrico Granata7bc0ec32012-02-29 03:28:49 +00008# summary provider for NSDate
9import lldb
10import ctypes
Enrico Granata28399ad2012-04-25 01:39:27 +000011import lldb.runtime.objc.objc_runtime
12import lldb.formatters.metrics
Enrico Granata7bc0ec32012-02-29 03:28:49 +000013import struct
14import time
15import datetime
Enrico Granata8d5c83f2012-03-02 00:55:53 +000016import CFString
Enrico Granata28399ad2012-04-25 01:39:27 +000017import lldb.formatters.Logger
Enrico Granata7bc0ec32012-02-29 03:28:49 +000018
Enrico Granata28399ad2012-04-25 01:39:27 +000019statistics = lldb.formatters.metrics.Metrics()
Enrico Granata7bc0ec32012-02-29 03:28:49 +000020statistics.add_metric('invalid_isa')
21statistics.add_metric('invalid_pointer')
22statistics.add_metric('unknown_class')
23statistics.add_metric('code_notrun')
24
25# Python promises to start counting time at midnight on Jan 1st on the epoch year
26# hence, all we need to know is the epoch year
27python_epoch = time.gmtime(0).tm_year
28
29osx_epoch = datetime.date(2001,1,1).timetuple()
30
31def mkgmtime(t):
Enrico Granata28399ad2012-04-25 01:39:27 +000032 logger = lldb.formatters.Logger.Logger()
Enrico Granata247bd412012-04-02 16:39:29 +000033 return time.mktime(t)-time.timezone
Enrico Granata7bc0ec32012-02-29 03:28:49 +000034
35osx_epoch = mkgmtime(osx_epoch)
36
37def osx_to_python_time(osx):
Enrico Granata28399ad2012-04-25 01:39:27 +000038 logger = lldb.formatters.Logger.Logger()
Enrico Granata896cd1d2012-03-01 19:32:33 +000039 if python_epoch <= 2001:
Enrico Granata7bc0ec32012-02-29 03:28:49 +000040 return osx + osx_epoch
41 else:
42 return osx - osx_epoch
43
Enrico Granata8c69c962012-03-13 00:25:59 +000044# represent a struct_time as a string in the format used by Xcode
45def xcode_format_time(X):
Enrico Granata28399ad2012-04-25 01:39:27 +000046 logger = lldb.formatters.Logger.Logger()
Enrico Granata8c69c962012-03-13 00:25:59 +000047 return time.strftime('%Y-%m-%d %H:%M:%S %Z',X)
48
49# represent a count-since-epoch as a string in the format used by Xcode
50def xcode_format_count(X):
Enrico Granata28399ad2012-04-25 01:39:27 +000051 logger = lldb.formatters.Logger.Logger()
Enrico Granata8c69c962012-03-13 00:25:59 +000052 return xcode_format_time(time.localtime(X))
Enrico Granata7bc0ec32012-02-29 03:28:49 +000053
54# despite the similary to synthetic children providers, these classes are not
Enrico Granata896cd1d2012-03-01 19:32:33 +000055# trying to provide anything but the summary for NSDate, so they need not
Enrico Granata7bc0ec32012-02-29 03:28:49 +000056# obey the interface specification for synthetic children providers
57class NSTaggedDate_SummaryProvider:
58 def adjust_for_architecture(self):
Enrico Granatacfdafa32012-03-05 19:56:33 +000059 pass
Enrico Granata7bc0ec32012-02-29 03:28:49 +000060
Enrico Granatacfdafa32012-03-05 19:56:33 +000061 def __init__(self, valobj, info_bits, data, params):
Enrico Granata28399ad2012-04-25 01:39:27 +000062 logger = lldb.formatters.Logger.Logger()
Enrico Granata7bc0ec32012-02-29 03:28:49 +000063 self.valobj = valobj;
Enrico Granatacfdafa32012-03-05 19:56:33 +000064 self.sys_params = params
Enrico Granata7bc0ec32012-02-29 03:28:49 +000065 self.update();
Enrico Granata896cd1d2012-03-01 19:32:33 +000066 # NSDate is not using its info_bits for info like NSNumber is
67 # so we need to regroup info_bits and data
68 self.data = ((data << 8) | (info_bits << 4))
Enrico Granata7bc0ec32012-02-29 03:28:49 +000069
70 def update(self):
Enrico Granata28399ad2012-04-25 01:39:27 +000071 logger = lldb.formatters.Logger.Logger()
Enrico Granata7bc0ec32012-02-29 03:28:49 +000072 self.adjust_for_architecture();
Enrico Granata7bc0ec32012-02-29 03:28:49 +000073
74 def value(self):
Enrico Granata28399ad2012-04-25 01:39:27 +000075 logger = lldb.formatters.Logger.Logger()
Enrico Granata7bc0ec32012-02-29 03:28:49 +000076 # the value of the date-time object is wrapped into the pointer value
Enrico Granata896cd1d2012-03-01 19:32:33 +000077 # unfortunately, it is made as a time-delta after Jan 1 2001 midnight GMT
Enrico Granata7bc0ec32012-02-29 03:28:49 +000078 # while all Python knows about is the "epoch", which is a platform-dependent
79 # year (1970 of *nix) whose Jan 1 at midnight is taken as reference
Enrico Granata896cd1d2012-03-01 19:32:33 +000080 value_double = struct.unpack('d', struct.pack('Q', self.data))[0]
Enrico Granata39cf67e2012-09-04 20:02:39 +000081 if value_double == -63114076800.0:
82 return '0001-12-30 00:00:00 +0000'
Enrico Granata8c69c962012-03-13 00:25:59 +000083 return xcode_format_count(osx_to_python_time(value_double))
Enrico Granata7bc0ec32012-02-29 03:28:49 +000084
85
86class NSUntaggedDate_SummaryProvider:
87 def adjust_for_architecture(self):
Enrico Granatacfdafa32012-03-05 19:56:33 +000088 pass
Enrico Granata7bc0ec32012-02-29 03:28:49 +000089
Enrico Granatacfdafa32012-03-05 19:56:33 +000090 def __init__(self, valobj, params):
Enrico Granata28399ad2012-04-25 01:39:27 +000091 logger = lldb.formatters.Logger.Logger()
Enrico Granata7bc0ec32012-02-29 03:28:49 +000092 self.valobj = valobj;
Enrico Granatacfdafa32012-03-05 19:56:33 +000093 self.sys_params = params
94 if not (self.sys_params.types_cache.double):
95 self.sys_params.types_cache.double = self.valobj.GetType().GetBasicType(lldb.eBasicTypeDouble)
Enrico Granata7bc0ec32012-02-29 03:28:49 +000096 self.update()
97
98 def update(self):
Enrico Granata28399ad2012-04-25 01:39:27 +000099 logger = lldb.formatters.Logger.Logger()
Enrico Granata7bc0ec32012-02-29 03:28:49 +0000100 self.adjust_for_architecture();
Enrico Granata7bc0ec32012-02-29 03:28:49 +0000101
102 def offset(self):
Enrico Granata28399ad2012-04-25 01:39:27 +0000103 logger = lldb.formatters.Logger.Logger()
Enrico Granatacfdafa32012-03-05 19:56:33 +0000104 return self.sys_params.pointer_size
Enrico Granata7bc0ec32012-02-29 03:28:49 +0000105
106 def value(self):
Enrico Granata28399ad2012-04-25 01:39:27 +0000107 logger = lldb.formatters.Logger.Logger()
Enrico Granata7bc0ec32012-02-29 03:28:49 +0000108 value = self.valobj.CreateChildAtOffset("value",
109 self.offset(),
Enrico Granatacfdafa32012-03-05 19:56:33 +0000110 self.sys_params.types_cache.double)
Enrico Granata7b3d2052012-10-24 19:05:32 +0000111 value_double = struct.unpack('d', struct.pack('Q', value.GetData().uint64[0]))[0]
Enrico Granata39cf67e2012-09-04 20:02:39 +0000112 if value_double == -63114076800.0:
113 return '0001-12-30 00:00:00 +0000'
Enrico Granata8c69c962012-03-13 00:25:59 +0000114 return xcode_format_count(osx_to_python_time(value_double))
Enrico Granata7bc0ec32012-02-29 03:28:49 +0000115
Enrico Granata896cd1d2012-03-01 19:32:33 +0000116class NSCalendarDate_SummaryProvider:
117 def adjust_for_architecture(self):
Enrico Granatacfdafa32012-03-05 19:56:33 +0000118 pass
Enrico Granata896cd1d2012-03-01 19:32:33 +0000119
Enrico Granatacfdafa32012-03-05 19:56:33 +0000120 def __init__(self, valobj, params):
Enrico Granata28399ad2012-04-25 01:39:27 +0000121 logger = lldb.formatters.Logger.Logger()
Enrico Granata896cd1d2012-03-01 19:32:33 +0000122 self.valobj = valobj;
Enrico Granatacfdafa32012-03-05 19:56:33 +0000123 self.sys_params = params
124 if not (self.sys_params.types_cache.double):
125 self.sys_params.types_cache.double = self.valobj.GetType().GetBasicType(lldb.eBasicTypeDouble)
Enrico Granata896cd1d2012-03-01 19:32:33 +0000126 self.update()
127
128 def update(self):
Enrico Granata28399ad2012-04-25 01:39:27 +0000129 logger = lldb.formatters.Logger.Logger()
Enrico Granata896cd1d2012-03-01 19:32:33 +0000130 self.adjust_for_architecture();
Enrico Granata896cd1d2012-03-01 19:32:33 +0000131
132 def offset(self):
Enrico Granata28399ad2012-04-25 01:39:27 +0000133 logger = lldb.formatters.Logger.Logger()
Enrico Granatacfdafa32012-03-05 19:56:33 +0000134 return 2*self.sys_params.pointer_size
Enrico Granata896cd1d2012-03-01 19:32:33 +0000135
136 def value(self):
Enrico Granata28399ad2012-04-25 01:39:27 +0000137 logger = lldb.formatters.Logger.Logger()
Enrico Granata896cd1d2012-03-01 19:32:33 +0000138 value = self.valobj.CreateChildAtOffset("value",
139 self.offset(),
Enrico Granatacfdafa32012-03-05 19:56:33 +0000140 self.sys_params.types_cache.double)
Enrico Granata7b3d2052012-10-24 19:05:32 +0000141 value_double = struct.unpack('d', struct.pack('Q', value.GetData().uint64[0]))[0]
Enrico Granata8c69c962012-03-13 00:25:59 +0000142 return xcode_format_count(osx_to_python_time(value_double))
Enrico Granata896cd1d2012-03-01 19:32:33 +0000143
Enrico Granata8d5c83f2012-03-02 00:55:53 +0000144class NSTimeZoneClass_SummaryProvider:
145 def adjust_for_architecture(self):
Enrico Granatacfdafa32012-03-05 19:56:33 +0000146 pass
Enrico Granata8d5c83f2012-03-02 00:55:53 +0000147
Enrico Granatacfdafa32012-03-05 19:56:33 +0000148 def __init__(self, valobj, params):
Enrico Granata28399ad2012-04-25 01:39:27 +0000149 logger = lldb.formatters.Logger.Logger()
Enrico Granata8d5c83f2012-03-02 00:55:53 +0000150 self.valobj = valobj;
Enrico Granatacfdafa32012-03-05 19:56:33 +0000151 self.sys_params = params
152 if not (self.sys_params.types_cache.voidptr):
153 self.sys_params.types_cache.voidptr = self.valobj.GetType().GetBasicType(lldb.eBasicTypeVoid).GetPointerType()
Enrico Granata8d5c83f2012-03-02 00:55:53 +0000154 self.update()
155
156 def update(self):
Enrico Granata28399ad2012-04-25 01:39:27 +0000157 logger = lldb.formatters.Logger.Logger()
Enrico Granata8d5c83f2012-03-02 00:55:53 +0000158 self.adjust_for_architecture();
Enrico Granata8d5c83f2012-03-02 00:55:53 +0000159
160 def offset(self):
Enrico Granata28399ad2012-04-25 01:39:27 +0000161 logger = lldb.formatters.Logger.Logger()
Enrico Granatacfdafa32012-03-05 19:56:33 +0000162 return self.sys_params.pointer_size
Enrico Granata8d5c83f2012-03-02 00:55:53 +0000163
164 def timezone(self):
Enrico Granata28399ad2012-04-25 01:39:27 +0000165 logger = lldb.formatters.Logger.Logger()
Enrico Granata8d5c83f2012-03-02 00:55:53 +0000166 tz_string = self.valobj.CreateChildAtOffset("tz_name",
167 self.offset(),
Enrico Granatacfdafa32012-03-05 19:56:33 +0000168 self.sys_params.types_cache.voidptr)
Enrico Granata8d5c83f2012-03-02 00:55:53 +0000169 return CFString.CFString_SummaryProvider(tz_string,None)
Enrico Granata896cd1d2012-03-01 19:32:33 +0000170
Enrico Granata7bc0ec32012-02-29 03:28:49 +0000171class NSUnknownDate_SummaryProvider:
172 def adjust_for_architecture(self):
Enrico Granatacfdafa32012-03-05 19:56:33 +0000173 pass
Enrico Granata7bc0ec32012-02-29 03:28:49 +0000174
175 def __init__(self, valobj):
Enrico Granata28399ad2012-04-25 01:39:27 +0000176 logger = lldb.formatters.Logger.Logger()
Enrico Granata7bc0ec32012-02-29 03:28:49 +0000177 self.valobj = valobj;
178 self.update()
179
180 def update(self):
Enrico Granata28399ad2012-04-25 01:39:27 +0000181 logger = lldb.formatters.Logger.Logger()
Enrico Granata7bc0ec32012-02-29 03:28:49 +0000182 self.adjust_for_architecture();
Enrico Granata7bc0ec32012-02-29 03:28:49 +0000183
184 def value(self):
Enrico Granata28399ad2012-04-25 01:39:27 +0000185 logger = lldb.formatters.Logger.Logger()
Enrico Granata7bc0ec32012-02-29 03:28:49 +0000186 stream = lldb.SBStream()
187 self.valobj.GetExpressionPath(stream)
188 expr = "(NSString*)[" + stream.GetData() + " description]"
189 num_children_vo = self.valobj.CreateValueFromExpression("str",expr);
Enrico Granata3f1052b2012-03-13 21:52:00 +0000190 if num_children_vo.IsValid():
191 return num_children_vo.GetSummary()
192 return '<variable is not NSDate>'
Enrico Granata7bc0ec32012-02-29 03:28:49 +0000193
194def GetSummary_Impl(valobj):
Enrico Granata28399ad2012-04-25 01:39:27 +0000195 logger = lldb.formatters.Logger.Logger()
Enrico Granata7bc0ec32012-02-29 03:28:49 +0000196 global statistics
Enrico Granata7d222212012-04-25 17:53:41 +0000197 class_data,wrapper =lldb.runtime.objc.objc_runtime.Utilities.prepare_class_detection(valobj,statistics)
Enrico Granata3f1052b2012-03-13 21:52:00 +0000198 if wrapper:
199 return wrapper
Enrico Granata7bc0ec32012-02-29 03:28:49 +0000200
201 name_string = class_data.class_name()
Enrico Granata247bd412012-04-02 16:39:29 +0000202 logger >> "class name is: " + str(name_string)
203
Enrico Granata7bc0ec32012-02-29 03:28:49 +0000204 if name_string == 'NSDate' or name_string == '__NSDate' or name_string == '__NSTaggedDate':
205 if class_data.is_tagged():
Enrico Granatacfdafa32012-03-05 19:56:33 +0000206 wrapper = NSTaggedDate_SummaryProvider(valobj,class_data.info_bits(),class_data.value(), class_data.sys_params)
Enrico Granata7bc0ec32012-02-29 03:28:49 +0000207 statistics.metric_hit('code_notrun',valobj)
208 else:
Enrico Granatacfdafa32012-03-05 19:56:33 +0000209 wrapper = NSUntaggedDate_SummaryProvider(valobj, class_data.sys_params)
Enrico Granata7bc0ec32012-02-29 03:28:49 +0000210 statistics.metric_hit('code_notrun',valobj)
Enrico Granata896cd1d2012-03-01 19:32:33 +0000211 elif name_string == 'NSCalendarDate':
Enrico Granatacfdafa32012-03-05 19:56:33 +0000212 wrapper = NSCalendarDate_SummaryProvider(valobj, class_data.sys_params)
Enrico Granata896cd1d2012-03-01 19:32:33 +0000213 statistics.metric_hit('code_notrun',valobj)
Enrico Granata8d5c83f2012-03-02 00:55:53 +0000214 elif name_string == '__NSTimeZone':
Enrico Granatacfdafa32012-03-05 19:56:33 +0000215 wrapper = NSTimeZoneClass_SummaryProvider(valobj, class_data.sys_params)
Enrico Granata8d5c83f2012-03-02 00:55:53 +0000216 statistics.metric_hit('code_notrun',valobj)
Enrico Granata7bc0ec32012-02-29 03:28:49 +0000217 else:
Enrico Granata73076f92012-04-26 01:40:38 +0000218 wrapper = NSUnknownDate_SummaryProvider(valobj)
Enrico Granataa7daeeb2012-03-30 00:51:12 +0000219 statistics.metric_hit('unknown_class',valobj.GetName() + " seen as " + name_string)
Enrico Granata7bc0ec32012-02-29 03:28:49 +0000220 return wrapper;
221
222
223def NSDate_SummaryProvider (valobj,dict):
Enrico Granata28399ad2012-04-25 01:39:27 +0000224 logger = lldb.formatters.Logger.Logger()
Enrico Granata7bc0ec32012-02-29 03:28:49 +0000225 provider = GetSummary_Impl(valobj);
226 if provider != None:
Enrico Granata7d222212012-04-25 17:53:41 +0000227 if isinstance(provider,lldb.runtime.objc.objc_runtime.SpecialSituation_Description):
Enrico Granata3f1052b2012-03-13 21:52:00 +0000228 return provider.message()
229 try:
230 summary = provider.value();
231 except:
232 summary = None
233 if summary == None:
234 summary = '<variable is not NSDate>'
235 return str(summary)
236 return 'Summary Unavailable'
Enrico Granata7bc0ec32012-02-29 03:28:49 +0000237
Enrico Granata8d5c83f2012-03-02 00:55:53 +0000238def NSTimeZone_SummaryProvider (valobj,dict):
Enrico Granata28399ad2012-04-25 01:39:27 +0000239 logger = lldb.formatters.Logger.Logger()
Enrico Granata8d5c83f2012-03-02 00:55:53 +0000240 provider = GetSummary_Impl(valobj);
241 if provider != None:
Enrico Granata7d222212012-04-25 17:53:41 +0000242 if isinstance(provider,lldb.runtime.objc.objc_runtime.SpecialSituation_Description):
Enrico Granata3f1052b2012-03-13 21:52:00 +0000243 return provider.message()
244 try:
245 summary = provider.timezone();
246 except:
247 summary = None
Enrico Granata247bd412012-04-02 16:39:29 +0000248 logger >> "got summary " + str(summary)
Enrico Granata3f1052b2012-03-13 21:52:00 +0000249 if summary == None:
250 summary = '<variable is not NSTimeZone>'
251 return str(summary)
252 return 'Summary Unavailable'
Enrico Granata8d5c83f2012-03-02 00:55:53 +0000253
254
Enrico Granata896cd1d2012-03-01 19:32:33 +0000255def CFAbsoluteTime_SummaryProvider (valobj,dict):
Enrico Granata28399ad2012-04-25 01:39:27 +0000256 logger = lldb.formatters.Logger.Logger()
Enrico Granata896cd1d2012-03-01 19:32:33 +0000257 try:
Enrico Granata7b3d2052012-10-24 19:05:32 +0000258 value_double = struct.unpack('d', struct.pack('Q', valobj.GetData().uint64[0]))[0]
Enrico Granata8c69c962012-03-13 00:25:59 +0000259 return xcode_format_count(osx_to_python_time(value_double))
Enrico Granata896cd1d2012-03-01 19:32:33 +0000260 except:
Enrico Granata3f1052b2012-03-13 21:52:00 +0000261 return 'Summary Unavailable'
Enrico Granata896cd1d2012-03-01 19:32:33 +0000262
Enrico Granata7bc0ec32012-02-29 03:28:49 +0000263
264def __lldb_init_module(debugger,dict):
265 debugger.HandleCommand("type summary add -F NSDate.NSDate_SummaryProvider NSDate")
Enrico Granata896cd1d2012-03-01 19:32:33 +0000266 debugger.HandleCommand("type summary add -F NSDate.CFAbsoluteTime_SummaryProvider CFAbsoluteTime")
Enrico Granata8d5c83f2012-03-02 00:55:53 +0000267 debugger.HandleCommand("type summary add -F NSDate.NSTimeZone_SummaryProvider NSTimeZone CFTimeZoneRef")
Enrico Granata7bc0ec32012-02-29 03:28:49 +0000268