xref: /openbsd-src/gnu/llvm/lldb/examples/summaries/cocoa/NSURL.py (revision 061da546b983eb767bad15e67af1174fb0bcf31c)
1*061da546Spatrick"""
2*061da546SpatrickLLDB AppKit formatters
3*061da546Spatrick
4*061da546SpatrickPart of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5*061da546SpatrickSee https://llvm.org/LICENSE.txt for license information.
6*061da546SpatrickSPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7*061da546Spatrick"""
8*061da546Spatrick# summary provider for NSURL
9*061da546Spatrickimport lldb
10*061da546Spatrickimport ctypes
11*061da546Spatrickimport lldb.runtime.objc.objc_runtime
12*061da546Spatrickimport lldb.formatters.metrics
13*061da546Spatrickimport CFString
14*061da546Spatrickimport lldb.formatters.Logger
15*061da546Spatrick
16*061da546Spatrickstatistics = lldb.formatters.metrics.Metrics()
17*061da546Spatrickstatistics.add_metric('invalid_isa')
18*061da546Spatrickstatistics.add_metric('invalid_pointer')
19*061da546Spatrickstatistics.add_metric('unknown_class')
20*061da546Spatrickstatistics.add_metric('code_notrun')
21*061da546Spatrick
22*061da546Spatrick# despite the similary to synthetic children providers, these classes are not
23*061da546Spatrick# trying to provide anything but a summary for an NSURL, so they need not
24*061da546Spatrick# obey the interface specification for synthetic children providers
25*061da546Spatrick
26*061da546Spatrick
27*061da546Spatrickclass NSURLKnown_SummaryProvider:
28*061da546Spatrick
29*061da546Spatrick    def adjust_for_architecture(self):
30*061da546Spatrick        pass
31*061da546Spatrick
32*061da546Spatrick    def __init__(self, valobj, params):
33*061da546Spatrick        logger = lldb.formatters.Logger.Logger()
34*061da546Spatrick        self.valobj = valobj
35*061da546Spatrick        self.sys_params = params
36*061da546Spatrick        if not(self.sys_params.types_cache.NSString):
37*061da546Spatrick            self.sys_params.types_cache.NSString = self.valobj.GetTarget(
38*061da546Spatrick            ).FindFirstType('NSString').GetPointerType()
39*061da546Spatrick        if not(self.sys_params.types_cache.NSURL):
40*061da546Spatrick            self.sys_params.types_cache.NSURL = self.valobj.GetTarget(
41*061da546Spatrick            ).FindFirstType('NSURL').GetPointerType()
42*061da546Spatrick        self.update()
43*061da546Spatrick
44*061da546Spatrick    def update(self):
45*061da546Spatrick        logger = lldb.formatters.Logger.Logger()
46*061da546Spatrick        self.adjust_for_architecture()
47*061da546Spatrick
48*061da546Spatrick    # one pointer is the ISA
49*061da546Spatrick    # then there is one more pointer and 8 bytes of plain data
50*061da546Spatrick    # (which are also present on a 32-bit system)
51*061da546Spatrick    # then there is a pointer to an NSString which is the url text
52*061da546Spatrick    # optionally, the next pointer is another NSURL which is the "base"
53*061da546Spatrick    # of this one when doing NSURLs composition (incidentally, NSURLs can
54*061da546Spatrick    # recurse the base+text mechanism to any desired depth)
55*061da546Spatrick    def offset_text(self):
56*061da546Spatrick        logger = lldb.formatters.Logger.Logger()
57*061da546Spatrick        return 24 if self.sys_params.is_64_bit else 16
58*061da546Spatrick
59*061da546Spatrick    def offset_base(self):
60*061da546Spatrick        logger = lldb.formatters.Logger.Logger()
61*061da546Spatrick        return self.offset_text() + self.sys_params.pointer_size
62*061da546Spatrick
63*061da546Spatrick    def url_text(self):
64*061da546Spatrick        logger = lldb.formatters.Logger.Logger()
65*061da546Spatrick        text = self.valobj.CreateChildAtOffset(
66*061da546Spatrick            "text", self.offset_text(), self.sys_params.types_cache.NSString)
67*061da546Spatrick        base = self.valobj.CreateChildAtOffset(
68*061da546Spatrick            "base", self.offset_base(), self.sys_params.types_cache.NSURL)
69*061da546Spatrick        my_string = CFString.CFString_SummaryProvider(text, None)
70*061da546Spatrick        if len(my_string) > 0 and base.GetValueAsUnsigned(0) != 0:
71*061da546Spatrick            # remove final " from myself
72*061da546Spatrick            my_string = my_string[0:len(my_string) - 1]
73*061da546Spatrick            my_string = my_string + ' -- '
74*061da546Spatrick            my_base_string = NSURL_SummaryProvider(base, None)
75*061da546Spatrick            if len(my_base_string) > 2:
76*061da546Spatrick                # remove @" marker from base URL string
77*061da546Spatrick                my_base_string = my_base_string[2:]
78*061da546Spatrick            my_string = my_string + my_base_string
79*061da546Spatrick        return my_string
80*061da546Spatrick
81*061da546Spatrick
82*061da546Spatrickclass NSURLUnknown_SummaryProvider:
83*061da546Spatrick
84*061da546Spatrick    def adjust_for_architecture(self):
85*061da546Spatrick        pass
86*061da546Spatrick
87*061da546Spatrick    def __init__(self, valobj, params):
88*061da546Spatrick        logger = lldb.formatters.Logger.Logger()
89*061da546Spatrick        self.valobj = valobj
90*061da546Spatrick        self.sys_params = params
91*061da546Spatrick        self.update()
92*061da546Spatrick
93*061da546Spatrick    def update(self):
94*061da546Spatrick        logger = lldb.formatters.Logger.Logger()
95*061da546Spatrick        self.adjust_for_architecture()
96*061da546Spatrick
97*061da546Spatrick    def url_text(self):
98*061da546Spatrick        logger = lldb.formatters.Logger.Logger()
99*061da546Spatrick        stream = lldb.SBStream()
100*061da546Spatrick        self.valobj.GetExpressionPath(stream)
101*061da546Spatrick        url_text_vo = self.valobj.CreateValueFromExpression(
102*061da546Spatrick            "url", "(NSString*)[" + stream.GetData() + " description]")
103*061da546Spatrick        if url_text_vo.IsValid():
104*061da546Spatrick            return CFString.CFString_SummaryProvider(url_text_vo, None)
105*061da546Spatrick        return '<variable is not NSURL>'
106*061da546Spatrick
107*061da546Spatrick
108*061da546Spatrickdef GetSummary_Impl(valobj):
109*061da546Spatrick    logger = lldb.formatters.Logger.Logger()
110*061da546Spatrick    global statistics
111*061da546Spatrick    class_data, wrapper = lldb.runtime.objc.objc_runtime.Utilities.prepare_class_detection(
112*061da546Spatrick        valobj, statistics)
113*061da546Spatrick    if wrapper:
114*061da546Spatrick        return wrapper
115*061da546Spatrick
116*061da546Spatrick    name_string = class_data.class_name()
117*061da546Spatrick    logger >> "class name is: " + str(name_string)
118*061da546Spatrick
119*061da546Spatrick    if name_string == 'NSURL':
120*061da546Spatrick        wrapper = NSURLKnown_SummaryProvider(valobj, class_data.sys_params)
121*061da546Spatrick        statistics.metric_hit('code_notrun', valobj)
122*061da546Spatrick    else:
123*061da546Spatrick        wrapper = NSURLUnknown_SummaryProvider(valobj, class_data.sys_params)
124*061da546Spatrick        statistics.metric_hit(
125*061da546Spatrick            'unknown_class',
126*061da546Spatrick            valobj.GetName() +
127*061da546Spatrick            " seen as " +
128*061da546Spatrick            name_string)
129*061da546Spatrick    return wrapper
130*061da546Spatrick
131*061da546Spatrick
132*061da546Spatrickdef NSURL_SummaryProvider(valobj, dict):
133*061da546Spatrick    logger = lldb.formatters.Logger.Logger()
134*061da546Spatrick    provider = GetSummary_Impl(valobj)
135*061da546Spatrick    if provider is not None:
136*061da546Spatrick        if isinstance(
137*061da546Spatrick                provider,
138*061da546Spatrick                lldb.runtime.objc.objc_runtime.SpecialSituation_Description):
139*061da546Spatrick            return provider.message()
140*061da546Spatrick        try:
141*061da546Spatrick            summary = provider.url_text()
142*061da546Spatrick        except:
143*061da546Spatrick            summary = None
144*061da546Spatrick        logger >> "got summary " + str(summary)
145*061da546Spatrick        if summary is None or summary == '':
146*061da546Spatrick            summary = '<variable is not NSURL>'
147*061da546Spatrick        return summary
148*061da546Spatrick    return 'Summary Unavailable'
149*061da546Spatrick
150*061da546Spatrick
151*061da546Spatrickdef __lldb_init_module(debugger, dict):
152*061da546Spatrick    debugger.HandleCommand(
153*061da546Spatrick        "type summary add -F NSURL.NSURL_SummaryProvider NSURL CFURLRef")
154