blob: ac47be365e5ab6bd169f6ecf282172ebb184cfc0 [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
25class NSURLKnown_SummaryProvider:
26 def adjust_for_architecture(self):
Enrico Granatacfdafa32012-03-05 19:56:33 +000027 pass
Enrico Granataeb4a4792012-02-23 23:10:27 +000028
Enrico Granatacfdafa32012-03-05 19:56:33 +000029 def __init__(self, valobj, params):
Enrico Granata28399ad2012-04-25 01:39:27 +000030 logger = lldb.formatters.Logger.Logger()
Enrico Granataeb4a4792012-02-23 23:10:27 +000031 self.valobj = valobj;
Enrico Granatacfdafa32012-03-05 19:56:33 +000032 self.sys_params = params
33 if not(self.sys_params.types_cache.NSString):
34 self.sys_params.types_cache.NSString = self.valobj.GetTarget().FindFirstType('NSString').GetPointerType()
35 if not(self.sys_params.types_cache.NSURL):
36 self.sys_params.types_cache.NSURL = self.valobj.GetTarget().FindFirstType('NSURL').GetPointerType()
Enrico Granataeb4a4792012-02-23 23:10:27 +000037 self.update();
38
39 def update(self):
Enrico Granata28399ad2012-04-25 01:39:27 +000040 logger = lldb.formatters.Logger.Logger()
Enrico Granataeb4a4792012-02-23 23:10:27 +000041 self.adjust_for_architecture();
Enrico Granataeb4a4792012-02-23 23:10:27 +000042
43 # one pointer is the ISA
44 # then there is one more pointer and 8 bytes of plain data
45 # (which are also present on a 32-bit system)
Enrico Granata01261322012-12-18 19:22:05 +000046 # then there is a pointer to an NSString which is the url text
47 # optionally, the next pointer is another NSURL which is the "base"
48 # of this one when doing NSURLs composition (incidentally, NSURLs can
49 # recurse the base+text mechanism to any desired depth)
Enrico Granatacfdafa32012-03-05 19:56:33 +000050 def offset_text(self):
Enrico Granata28399ad2012-04-25 01:39:27 +000051 logger = lldb.formatters.Logger.Logger()
Enrico Granatacfdafa32012-03-05 19:56:33 +000052 return 24 if self.sys_params.is_64_bit else 16
53 def offset_base(self):
Enrico Granata28399ad2012-04-25 01:39:27 +000054 logger = lldb.formatters.Logger.Logger()
Enrico Granatacfdafa32012-03-05 19:56:33 +000055 return self.offset_text()+self.sys_params.pointer_size
Enrico Granataeb4a4792012-02-23 23:10:27 +000056
57 def url_text(self):
Enrico Granata28399ad2012-04-25 01:39:27 +000058 logger = lldb.formatters.Logger.Logger()
Enrico Granataeb4a4792012-02-23 23:10:27 +000059 text = self.valobj.CreateChildAtOffset("text",
Enrico Granatacfdafa32012-03-05 19:56:33 +000060 self.offset_text(),
61 self.sys_params.types_cache.NSString)
Enrico Granataeb4a4792012-02-23 23:10:27 +000062 base = self.valobj.CreateChildAtOffset("base",
Enrico Granatacfdafa32012-03-05 19:56:33 +000063 self.offset_base(),
64 self.sys_params.types_cache.NSURL)
Enrico Granataeb4a4792012-02-23 23:10:27 +000065 my_string = CFString.CFString_SummaryProvider(text,None)
Enrico Granata8c69c962012-03-13 00:25:59 +000066 if len(my_string) > 0 and base.GetValueAsUnsigned(0) != 0:
67 # remove final " from myself
68 my_string = my_string[0:len(my_string)-1]
69 my_string = my_string + ' -- '
70 my_base_string = NSURL_SummaryProvider(base,None)
71 if len(my_base_string) > 2:
72 # remove @" marker from base URL string
73 my_base_string = my_base_string[2:]
74 my_string = my_string + my_base_string
Enrico Granataeb4a4792012-02-23 23:10:27 +000075 return my_string
76
77
78class NSURLUnknown_SummaryProvider:
79 def adjust_for_architecture(self):
Enrico Granatacfdafa32012-03-05 19:56:33 +000080 pass
Enrico Granataeb4a4792012-02-23 23:10:27 +000081
Enrico Granatacfdafa32012-03-05 19:56:33 +000082 def __init__(self, valobj, params):
Enrico Granata28399ad2012-04-25 01:39:27 +000083 logger = lldb.formatters.Logger.Logger()
Enrico Granataeb4a4792012-02-23 23:10:27 +000084 self.valobj = valobj;
Enrico Granatacfdafa32012-03-05 19:56:33 +000085 self.sys_params = params
Enrico Granataeb4a4792012-02-23 23:10:27 +000086 self.update()
87
88 def update(self):
Enrico Granata28399ad2012-04-25 01:39:27 +000089 logger = lldb.formatters.Logger.Logger()
Enrico Granataeb4a4792012-02-23 23:10:27 +000090 self.adjust_for_architecture();
Enrico Granataeb4a4792012-02-23 23:10:27 +000091
92 def url_text(self):
Enrico Granata28399ad2012-04-25 01:39:27 +000093 logger = lldb.formatters.Logger.Logger()
Enrico Granataeb4a4792012-02-23 23:10:27 +000094 stream = lldb.SBStream()
95 self.valobj.GetExpressionPath(stream)
Enrico Granata3f1052b2012-03-13 21:52:00 +000096 url_text_vo = self.valobj.CreateValueFromExpression("url","(NSString*)[" + stream.GetData() + " description]")
97 if url_text_vo.IsValid():
98 return CFString.CFString_SummaryProvider(url_text_vo,None)
99 return '<variable is not NSURL>'
Enrico Granataeb4a4792012-02-23 23:10:27 +0000100
101
102def GetSummary_Impl(valobj):
Enrico Granata28399ad2012-04-25 01:39:27 +0000103 logger = lldb.formatters.Logger.Logger()
Enrico Granataeb4a4792012-02-23 23:10:27 +0000104 global statistics
Enrico Granata7d222212012-04-25 17:53:41 +0000105 class_data,wrapper =lldb.runtime.objc.objc_runtime.Utilities.prepare_class_detection(valobj,statistics)
Enrico Granata3f1052b2012-03-13 21:52:00 +0000106 if wrapper:
107 return wrapper
Enrico Granataeb4a4792012-02-23 23:10:27 +0000108
109 name_string = class_data.class_name()
Enrico Granata247bd412012-04-02 16:39:29 +0000110 logger >> "class name is: " + str(name_string)
111
Enrico Granataeb4a4792012-02-23 23:10:27 +0000112 if name_string == 'NSURL':
Enrico Granatacfdafa32012-03-05 19:56:33 +0000113 wrapper = NSURLKnown_SummaryProvider(valobj, class_data.sys_params)
Enrico Granataeb4a4792012-02-23 23:10:27 +0000114 statistics.metric_hit('code_notrun',valobj)
115 else:
Enrico Granatacfdafa32012-03-05 19:56:33 +0000116 wrapper = NSURLUnknown_SummaryProvider(valobj, class_data.sys_params)
Enrico Granataa7daeeb2012-03-30 00:51:12 +0000117 statistics.metric_hit('unknown_class',valobj.GetName() + " seen as " + name_string)
Enrico Granataeb4a4792012-02-23 23:10:27 +0000118 return wrapper;
119
120def NSURL_SummaryProvider (valobj,dict):
Enrico Granata28399ad2012-04-25 01:39:27 +0000121 logger = lldb.formatters.Logger.Logger()
Enrico Granataeb4a4792012-02-23 23:10:27 +0000122 provider = GetSummary_Impl(valobj);
123 if provider != None:
Enrico Granata7d222212012-04-25 17:53:41 +0000124 if isinstance(provider,lldb.runtime.objc.objc_runtime.SpecialSituation_Description):
Enrico Granata3f1052b2012-03-13 21:52:00 +0000125 return provider.message()
126 try:
127 summary = provider.url_text();
128 except:
129 summary = None
Enrico Granata247bd412012-04-02 16:39:29 +0000130 logger >> "got summary " + str(summary)
Enrico Granata3f1052b2012-03-13 21:52:00 +0000131 if summary == None or summary == '':
132 summary = '<variable is not NSURL>'
133 return summary
134 return 'Summary Unavailable'
Enrico Granataeb4a4792012-02-23 23:10:27 +0000135
136def __lldb_init_module(debugger,dict):
137 debugger.HandleCommand("type summary add -F NSURL.NSURL_SummaryProvider NSURL CFURLRef")