blob: ad28849a44d6c7dfb37cd0f053178f5bf4dc3141 [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 Granataeb4a4792012-02-23 23:10:27 +00008# summary provider for NSURL
9import lldb
10import ctypes
Enrico Granata28399ad2012-04-25 01:39:27 +000011import lldb.runtime.objc.objc_runtime
12import lldb.formatters.metrics
Enrico Granataeb4a4792012-02-23 23:10:27 +000013import CFString
Enrico Granata28399ad2012-04-25 01:39:27 +000014import lldb.formatters.Logger
Enrico Granataeb4a4792012-02-23 23:10:27 +000015
Enrico Granata28399ad2012-04-25 01:39:27 +000016statistics = lldb.formatters.metrics.Metrics()
Enrico Granataeb4a4792012-02-23 23:10:27 +000017statistics.add_metric('invalid_isa')
18statistics.add_metric('invalid_pointer')
19statistics.add_metric('unknown_class')
20statistics.add_metric('code_notrun')
21
22# despite the similary to synthetic children providers, these classes are not
23# trying to provide anything but a summary for an NSURL, so they need not
24# obey the interface specification for synthetic children providers
Kate Stoneb9c1b512016-09-06 20:57:50 +000025
26
Enrico Granataeb4a4792012-02-23 23:10:27 +000027class NSURLKnown_SummaryProvider:
Enrico Granataeb4a4792012-02-23 23:10:27 +000028
Kate Stoneb9c1b512016-09-06 20:57:50 +000029 def adjust_for_architecture(self):
30 pass
Enrico Granataeb4a4792012-02-23 23:10:27 +000031
Kate Stoneb9c1b512016-09-06 20:57:50 +000032 def __init__(self, valobj, params):
33 logger = lldb.formatters.Logger.Logger()
34 self.valobj = valobj
35 self.sys_params = params
36 if not(self.sys_params.types_cache.NSString):
37 self.sys_params.types_cache.NSString = self.valobj.GetTarget(
38 ).FindFirstType('NSString').GetPointerType()
39 if not(self.sys_params.types_cache.NSURL):
40 self.sys_params.types_cache.NSURL = self.valobj.GetTarget(
41 ).FindFirstType('NSURL').GetPointerType()
42 self.update()
Enrico Granataeb4a4792012-02-23 23:10:27 +000043
Kate Stoneb9c1b512016-09-06 20:57:50 +000044 def update(self):
45 logger = lldb.formatters.Logger.Logger()
46 self.adjust_for_architecture()
Enrico Granataeb4a4792012-02-23 23:10:27 +000047
Kate Stoneb9c1b512016-09-06 20:57:50 +000048 # one pointer is the ISA
49 # then there is one more pointer and 8 bytes of plain data
50 # (which are also present on a 32-bit system)
51 # then there is a pointer to an NSString which is the url text
52 # optionally, the next pointer is another NSURL which is the "base"
53 # of this one when doing NSURLs composition (incidentally, NSURLs can
54 # recurse the base+text mechanism to any desired depth)
55 def offset_text(self):
56 logger = lldb.formatters.Logger.Logger()
57 return 24 if self.sys_params.is_64_bit else 16
58
59 def offset_base(self):
60 logger = lldb.formatters.Logger.Logger()
61 return self.offset_text() + self.sys_params.pointer_size
62
63 def url_text(self):
64 logger = lldb.formatters.Logger.Logger()
65 text = self.valobj.CreateChildAtOffset(
66 "text", self.offset_text(), self.sys_params.types_cache.NSString)
67 base = self.valobj.CreateChildAtOffset(
68 "base", self.offset_base(), self.sys_params.types_cache.NSURL)
69 my_string = CFString.CFString_SummaryProvider(text, None)
70 if len(my_string) > 0 and base.GetValueAsUnsigned(0) != 0:
71 # remove final " from myself
72 my_string = my_string[0:len(my_string) - 1]
73 my_string = my_string + ' -- '
74 my_base_string = NSURL_SummaryProvider(base, None)
75 if len(my_base_string) > 2:
76 # remove @" marker from base URL string
77 my_base_string = my_base_string[2:]
78 my_string = my_string + my_base_string
79 return my_string
Enrico Granataeb4a4792012-02-23 23:10:27 +000080
81
82class NSURLUnknown_SummaryProvider:
Enrico Granataeb4a4792012-02-23 23:10:27 +000083
Kate Stoneb9c1b512016-09-06 20:57:50 +000084 def adjust_for_architecture(self):
85 pass
Enrico Granataeb4a4792012-02-23 23:10:27 +000086
Kate Stoneb9c1b512016-09-06 20:57:50 +000087 def __init__(self, valobj, params):
88 logger = lldb.formatters.Logger.Logger()
89 self.valobj = valobj
90 self.sys_params = params
91 self.update()
Enrico Granataeb4a4792012-02-23 23:10:27 +000092
Kate Stoneb9c1b512016-09-06 20:57:50 +000093 def update(self):
94 logger = lldb.formatters.Logger.Logger()
95 self.adjust_for_architecture()
96
97 def url_text(self):
98 logger = lldb.formatters.Logger.Logger()
99 stream = lldb.SBStream()
100 self.valobj.GetExpressionPath(stream)
101 url_text_vo = self.valobj.CreateValueFromExpression(
102 "url", "(NSString*)[" + stream.GetData() + " description]")
103 if url_text_vo.IsValid():
104 return CFString.CFString_SummaryProvider(url_text_vo, None)
105 return '<variable is not NSURL>'
Enrico Granataeb4a4792012-02-23 23:10:27 +0000106
107
108def GetSummary_Impl(valobj):
Kate Stoneb9c1b512016-09-06 20:57:50 +0000109 logger = lldb.formatters.Logger.Logger()
110 global statistics
111 class_data, wrapper = lldb.runtime.objc.objc_runtime.Utilities.prepare_class_detection(
112 valobj, statistics)
113 if wrapper:
114 return wrapper
Enrico Granata247bd412012-04-02 16:39:29 +0000115
Kate Stoneb9c1b512016-09-06 20:57:50 +0000116 name_string = class_data.class_name()
117 logger >> "class name is: " + str(name_string)
Enrico Granataeb4a4792012-02-23 23:10:27 +0000118
Kate Stoneb9c1b512016-09-06 20:57:50 +0000119 if name_string == 'NSURL':
120 wrapper = NSURLKnown_SummaryProvider(valobj, class_data.sys_params)
121 statistics.metric_hit('code_notrun', valobj)
122 else:
123 wrapper = NSURLUnknown_SummaryProvider(valobj, class_data.sys_params)
124 statistics.metric_hit(
125 'unknown_class',
126 valobj.GetName() +
127 " seen as " +
128 name_string)
129 return wrapper
Enrico Granataeb4a4792012-02-23 23:10:27 +0000130
Kate Stoneb9c1b512016-09-06 20:57:50 +0000131
132def NSURL_SummaryProvider(valobj, dict):
133 logger = lldb.formatters.Logger.Logger()
134 provider = GetSummary_Impl(valobj)
135 if provider is not None:
136 if isinstance(
137 provider,
138 lldb.runtime.objc.objc_runtime.SpecialSituation_Description):
139 return provider.message()
140 try:
141 summary = provider.url_text()
142 except:
143 summary = None
144 logger >> "got summary " + str(summary)
145 if summary is None or summary == '':
146 summary = '<variable is not NSURL>'
147 return summary
148 return 'Summary Unavailable'
149
150
151def __lldb_init_module(debugger, dict):
152 debugger.HandleCommand(
153 "type summary add -F NSURL.NSURL_SummaryProvider NSURL CFURLRef")