]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - examples/summaries/cocoa/NSDate.py
Vendor import of lldb trunk r256945:
[FreeBSD/FreeBSD.git] / examples / summaries / cocoa / NSDate.py
1 """
2 LLDB AppKit formatters
3
4 part of The LLVM Compiler Infrastructure
5 This file is distributed under the University of Illinois Open Source
6 License. See LICENSE.TXT for details.
7 """
8 # example summary provider for NSDate
9 # the real summary is now C++ code built into LLDB
10 import lldb
11 import ctypes
12 import lldb.runtime.objc.objc_runtime
13 import lldb.formatters.metrics
14 import struct
15 import time
16 import datetime
17 import CFString
18 import lldb.formatters.Logger
19
20 statistics = lldb.formatters.metrics.Metrics()
21 statistics.add_metric('invalid_isa')
22 statistics.add_metric('invalid_pointer')
23 statistics.add_metric('unknown_class')
24 statistics.add_metric('code_notrun')
25
26 # Python promises to start counting time at midnight on Jan 1st on the epoch year
27 # hence, all we need to know is the epoch year
28 python_epoch = time.gmtime(0).tm_year
29
30 osx_epoch = datetime.date(2001,1,1).timetuple()
31
32 def mkgmtime(t):
33         logger = lldb.formatters.Logger.Logger()
34         return time.mktime(t)-time.timezone
35
36 osx_epoch = mkgmtime(osx_epoch)
37
38 def osx_to_python_time(osx):
39         logger = lldb.formatters.Logger.Logger()
40         if python_epoch <= 2001:
41                 return osx + osx_epoch
42         else:
43                 return osx - osx_epoch
44
45 # represent a struct_time as a string in the format used by Xcode
46 def xcode_format_time(X):
47         logger = lldb.formatters.Logger.Logger()
48         return time.strftime('%Y-%m-%d %H:%M:%S %Z',X)
49
50 # represent a count-since-epoch as a string in the format used by Xcode
51 def xcode_format_count(X):
52         logger = lldb.formatters.Logger.Logger()
53         return xcode_format_time(time.localtime(X))
54
55 # despite the similary to synthetic children providers, these classes are not
56 # trying to provide anything but the summary for NSDate, so they need not
57 # obey the interface specification for synthetic children providers
58 class NSTaggedDate_SummaryProvider:
59         def adjust_for_architecture(self):
60                 pass
61
62         def __init__(self, valobj, info_bits, data, params):
63                 logger = lldb.formatters.Logger.Logger()
64                 self.valobj = valobj;
65                 self.sys_params = params
66                 self.update();
67                 # NSDate is not using its info_bits for info like NSNumber is
68                 # so we need to regroup info_bits and data
69                 self.data = ((data << 8) | (info_bits << 4))
70
71         def update(self):
72                 logger = lldb.formatters.Logger.Logger()
73                 self.adjust_for_architecture();
74
75         def value(self):
76                 logger = lldb.formatters.Logger.Logger()
77                 # the value of the date-time object is wrapped into the pointer value
78                 # unfortunately, it is made as a time-delta after Jan 1 2001 midnight GMT
79                 # while all Python knows about is the "epoch", which is a platform-dependent
80                 # year (1970 of *nix) whose Jan 1 at midnight is taken as reference
81                 value_double = struct.unpack('d', struct.pack('Q', self.data))[0]
82                 if value_double == -63114076800.0:
83                         return '0001-12-30 00:00:00 +0000'
84                 return xcode_format_count(osx_to_python_time(value_double))
85
86
87 class NSUntaggedDate_SummaryProvider:
88         def adjust_for_architecture(self):
89                 pass
90
91         def __init__(self, valobj, params):
92                 logger = lldb.formatters.Logger.Logger()
93                 self.valobj = valobj;
94                 self.sys_params = params
95                 if not (self.sys_params.types_cache.double):
96                         self.sys_params.types_cache.double = self.valobj.GetType().GetBasicType(lldb.eBasicTypeDouble)
97                 self.update()
98
99         def update(self):
100                 logger = lldb.formatters.Logger.Logger()
101                 self.adjust_for_architecture();
102
103         def offset(self):
104                 logger = lldb.formatters.Logger.Logger()
105                 return self.sys_params.pointer_size
106
107         def value(self):
108                 logger = lldb.formatters.Logger.Logger()
109                 value = self.valobj.CreateChildAtOffset("value",
110                                                         self.offset(),
111                                                         self.sys_params.types_cache.double)
112                 value_double = struct.unpack('d', struct.pack('Q', value.GetData().uint64[0]))[0]
113                 if value_double == -63114076800.0:
114                         return '0001-12-30 00:00:00 +0000'
115                 return xcode_format_count(osx_to_python_time(value_double))
116
117 class NSCalendarDate_SummaryProvider:
118         def adjust_for_architecture(self):
119                 pass
120
121         def __init__(self, valobj, params):
122                 logger = lldb.formatters.Logger.Logger()
123                 self.valobj = valobj;
124                 self.sys_params = params
125                 if not (self.sys_params.types_cache.double):
126                         self.sys_params.types_cache.double = self.valobj.GetType().GetBasicType(lldb.eBasicTypeDouble)
127                 self.update()
128
129         def update(self):
130                 logger = lldb.formatters.Logger.Logger()
131                 self.adjust_for_architecture();
132
133         def offset(self):
134                 logger = lldb.formatters.Logger.Logger()
135                 return 2*self.sys_params.pointer_size
136
137         def value(self):
138                 logger = lldb.formatters.Logger.Logger()
139                 value = self.valobj.CreateChildAtOffset("value",
140                                                         self.offset(),
141                                                         self.sys_params.types_cache.double)
142                 value_double = struct.unpack('d', struct.pack('Q', value.GetData().uint64[0]))[0]
143                 return xcode_format_count(osx_to_python_time(value_double))
144
145 class NSTimeZoneClass_SummaryProvider:
146         def adjust_for_architecture(self):
147                 pass
148
149         def __init__(self, valobj, params):
150                 logger = lldb.formatters.Logger.Logger()
151                 self.valobj = valobj;
152                 self.sys_params = params
153                 if not (self.sys_params.types_cache.voidptr):
154                         self.sys_params.types_cache.voidptr = self.valobj.GetType().GetBasicType(lldb.eBasicTypeVoid).GetPointerType()
155                 self.update()
156
157         def update(self):
158                 logger = lldb.formatters.Logger.Logger()
159                 self.adjust_for_architecture();
160
161         def offset(self):
162                 logger = lldb.formatters.Logger.Logger()
163                 return self.sys_params.pointer_size
164
165         def timezone(self):
166                 logger = lldb.formatters.Logger.Logger()
167                 tz_string = self.valobj.CreateChildAtOffset("tz_name",
168                                                         self.offset(),
169                                                         self.sys_params.types_cache.voidptr)
170                 return CFString.CFString_SummaryProvider(tz_string,None)
171
172 class NSUnknownDate_SummaryProvider:
173         def adjust_for_architecture(self):
174                 pass
175
176         def __init__(self, valobj):
177                 logger = lldb.formatters.Logger.Logger()
178                 self.valobj = valobj;
179                 self.update()
180
181         def update(self):
182                 logger = lldb.formatters.Logger.Logger()
183                 self.adjust_for_architecture();
184
185         def value(self):
186                 logger = lldb.formatters.Logger.Logger()
187                 stream = lldb.SBStream()
188                 self.valobj.GetExpressionPath(stream)
189                 expr = "(NSString*)[" + stream.GetData() + " description]"
190                 num_children_vo = self.valobj.CreateValueFromExpression("str",expr);
191                 if num_children_vo.IsValid():
192                         return num_children_vo.GetSummary()
193                 return '<variable is not NSDate>'
194
195 def GetSummary_Impl(valobj):
196         logger = lldb.formatters.Logger.Logger()
197         global statistics
198         class_data,wrapper =lldb.runtime.objc.objc_runtime.Utilities.prepare_class_detection(valobj,statistics)
199         if wrapper:
200                 return wrapper
201         
202         name_string = class_data.class_name()
203         logger >> "class name is: " + str(name_string)
204
205         if name_string == 'NSDate' or name_string == '__NSDate' or name_string == '__NSTaggedDate':
206                 if class_data.is_tagged():
207                         wrapper = NSTaggedDate_SummaryProvider(valobj,class_data.info_bits(),class_data.value(), class_data.sys_params)
208                         statistics.metric_hit('code_notrun',valobj)
209                 else:
210                         wrapper = NSUntaggedDate_SummaryProvider(valobj, class_data.sys_params)
211                         statistics.metric_hit('code_notrun',valobj)
212         elif name_string == 'NSCalendarDate':
213                 wrapper = NSCalendarDate_SummaryProvider(valobj, class_data.sys_params)
214                 statistics.metric_hit('code_notrun',valobj)
215         elif name_string == '__NSTimeZone':
216                 wrapper = NSTimeZoneClass_SummaryProvider(valobj, class_data.sys_params)
217                 statistics.metric_hit('code_notrun',valobj)
218         else:
219                 wrapper = NSUnknownDate_SummaryProvider(valobj)
220                 statistics.metric_hit('unknown_class',valobj.GetName() + " seen as " + name_string)
221         return wrapper;
222
223
224 def NSDate_SummaryProvider (valobj,dict):
225         logger = lldb.formatters.Logger.Logger()
226         provider = GetSummary_Impl(valobj);
227         if provider != None:
228                 if isinstance(provider,lldb.runtime.objc.objc_runtime.SpecialSituation_Description):
229                         return provider.message()
230                 try:
231                         summary = provider.value();
232                 except:
233                         summary = None
234                 if summary == None:
235                         summary = '<variable is not NSDate>'
236                 return str(summary)
237         return 'Summary Unavailable'
238
239 def NSTimeZone_SummaryProvider (valobj,dict):
240         logger = lldb.formatters.Logger.Logger()
241         provider = GetSummary_Impl(valobj);
242         if provider != None:
243                 if isinstance(provider,lldb.runtime.objc.objc_runtime.SpecialSituation_Description):
244                         return provider.message()
245                 try:
246                         summary = provider.timezone();
247                 except:
248                         summary = None
249                 logger >> "got summary " + str(summary)
250                 if summary == None:
251                         summary = '<variable is not NSTimeZone>'
252                 return str(summary)
253         return 'Summary Unavailable'
254
255
256 def CFAbsoluteTime_SummaryProvider (valobj,dict):
257         logger = lldb.formatters.Logger.Logger()
258         try:
259                 value_double = struct.unpack('d', struct.pack('Q', valobj.GetData().uint64[0]))[0]
260                 return xcode_format_count(osx_to_python_time(value_double))
261         except:
262                 return 'Summary Unavailable'
263
264
265 def __lldb_init_module(debugger,dict):
266         debugger.HandleCommand("type summary add -F NSDate.NSDate_SummaryProvider NSDate")
267         debugger.HandleCommand("type summary add -F NSDate.CFAbsoluteTime_SummaryProvider CFAbsoluteTime")
268         debugger.HandleCommand("type summary add -F NSDate.NSTimeZone_SummaryProvider NSTimeZone CFTimeZoneRef")
269