4 Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5 See https://llvm.org/LICENSE.txt for license information.
6 SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
8 # summary provider for NSURL
11 import lldb
.runtime
.objc
.objc_runtime
12 import lldb
.formatters
.metrics
14 import lldb
.formatters
.Logger
16 statistics
= lldb
.formatters
.metrics
.Metrics()
17 statistics
.add_metric("invalid_isa")
18 statistics
.add_metric("invalid_pointer")
19 statistics
.add_metric("unknown_class")
20 statistics
.add_metric("code_notrun")
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
27 class NSURLKnown_SummaryProvider
:
28 def adjust_for_architecture(self
):
31 def __init__(self
, valobj
, params
):
32 logger
= lldb
.formatters
.Logger
.Logger()
34 self
.sys_params
= params
35 if not (self
.sys_params
.types_cache
.NSString
):
36 self
.sys_params
.types_cache
.NSString
= (
37 self
.valobj
.GetTarget().FindFirstType("NSString").GetPointerType()
39 if not (self
.sys_params
.types_cache
.NSURL
):
40 self
.sys_params
.types_cache
.NSURL
= (
41 self
.valobj
.GetTarget().FindFirstType("NSURL").GetPointerType()
46 logger
= lldb
.formatters
.Logger
.Logger()
47 self
.adjust_for_architecture()
49 # one pointer is the ISA
50 # then there is one more pointer and 8 bytes of plain data
51 # (which are also present on a 32-bit system)
52 # then there is a pointer to an NSString which is the url text
53 # optionally, the next pointer is another NSURL which is the "base"
54 # of this one when doing NSURLs composition (incidentally, NSURLs can
55 # recurse the base+text mechanism to any desired depth)
56 def offset_text(self
):
57 logger
= lldb
.formatters
.Logger
.Logger()
58 return 24 if self
.sys_params
.is_64_bit
else 16
60 def offset_base(self
):
61 logger
= lldb
.formatters
.Logger
.Logger()
62 return self
.offset_text() + self
.sys_params
.pointer_size
65 logger
= lldb
.formatters
.Logger
.Logger()
66 text
= self
.valobj
.CreateChildAtOffset(
67 "text", self
.offset_text(), self
.sys_params
.types_cache
.NSString
69 base
= self
.valobj
.CreateChildAtOffset(
70 "base", self
.offset_base(), self
.sys_params
.types_cache
.NSURL
72 my_string
= CFString
.CFString_SummaryProvider(text
, None)
73 if len(my_string
) > 0 and base
.GetValueAsUnsigned(0) != 0:
74 # remove final " from myself
75 my_string
= my_string
[0 : len(my_string
) - 1]
76 my_string
= my_string
+ " -- "
77 my_base_string
= NSURL_SummaryProvider(base
, None)
78 if len(my_base_string
) > 2:
79 # remove @" marker from base URL string
80 my_base_string
= my_base_string
[2:]
81 my_string
= my_string
+ my_base_string
85 class NSURLUnknown_SummaryProvider
:
86 def adjust_for_architecture(self
):
89 def __init__(self
, valobj
, params
):
90 logger
= lldb
.formatters
.Logger
.Logger()
92 self
.sys_params
= params
96 logger
= lldb
.formatters
.Logger
.Logger()
97 self
.adjust_for_architecture()
100 logger
= lldb
.formatters
.Logger
.Logger()
101 stream
= lldb
.SBStream()
102 self
.valobj
.GetExpressionPath(stream
)
103 url_text_vo
= self
.valobj
.CreateValueFromExpression(
104 "url", "(NSString*)[" + stream
.GetData() + " description]"
106 if url_text_vo
.IsValid():
107 return CFString
.CFString_SummaryProvider(url_text_vo
, None)
108 return "<variable is not NSURL>"
111 def GetSummary_Impl(valobj
):
112 logger
= lldb
.formatters
.Logger
.Logger()
117 ) = lldb
.runtime
.objc
.objc_runtime
.Utilities
.prepare_class_detection(
123 name_string
= class_data
.class_name()
124 logger
>> "class name is: " + str(name_string
)
126 if name_string
== "NSURL":
127 wrapper
= NSURLKnown_SummaryProvider(valobj
, class_data
.sys_params
)
128 statistics
.metric_hit("code_notrun", valobj
)
130 wrapper
= NSURLUnknown_SummaryProvider(valobj
, class_data
.sys_params
)
131 statistics
.metric_hit(
132 "unknown_class", valobj
.GetName() + " seen as " + name_string
137 def NSURL_SummaryProvider(valobj
, dict):
138 logger
= lldb
.formatters
.Logger
.Logger()
139 provider
= GetSummary_Impl(valobj
)
140 if provider
is not None:
142 provider
, lldb
.runtime
.objc
.objc_runtime
.SpecialSituation_Description
144 return provider
.message()
146 summary
= provider
.url_text()
149 logger
>> "got summary " + str(summary
)
150 if summary
is None or summary
== "":
151 summary
= "<variable is not NSURL>"
153 return "Summary Unavailable"
156 def __lldb_init_module(debugger
, dict):
157 debugger
.HandleCommand(
158 "type summary add -F NSURL.NSURL_SummaryProvider NSURL CFURLRef"