blob: b38b027a35a9c3ce58a443e9d78196eff9f8d50d [file] [log] [blame]
Enrico Granataeb4a4792012-02-23 23:10:27 +00001# summary provider for NSBundle
2import lldb
3import ctypes
4import objc_runtime
5import metrics
6import NSURL
7
8statistics = metrics.Metrics()
9statistics.add_metric('invalid_isa')
10statistics.add_metric('invalid_pointer')
11statistics.add_metric('unknown_class')
12statistics.add_metric('code_notrun')
13
14# despite the similary to synthetic children providers, these classes are not
15# trying to provide anything but a summary for an NSURL, so they need not
16# obey the interface specification for synthetic children providers
17class NSBundleKnown_SummaryProvider:
18 def adjust_for_architecture(self):
Enrico Granatacfdafa32012-03-05 19:56:33 +000019 pass
Enrico Granataeb4a4792012-02-23 23:10:27 +000020
Enrico Granatacfdafa32012-03-05 19:56:33 +000021 def __init__(self, valobj, params):
Enrico Granataeb4a4792012-02-23 23:10:27 +000022 self.valobj = valobj;
Enrico Granatacfdafa32012-03-05 19:56:33 +000023 self.sys_params = params
24 if not(self.sys_params.types_cache.NSString):
25 self.sys_params.types_cache.NSString = self.valobj.GetTarget().FindFirstType('NSString').GetPointerType()
Enrico Granataeb4a4792012-02-23 23:10:27 +000026 self.update();
27
28 def update(self):
29 self.adjust_for_architecture();
Enrico Granataeb4a4792012-02-23 23:10:27 +000030
31 # we need to skip the ISA, plus four other values
32 # that are luckily each a pointer in size
33 # which makes our computation trivial :-)
34 def offset(self):
Enrico Granatacfdafa32012-03-05 19:56:33 +000035 return 5 * self.sys_params.pointer_size
Enrico Granataeb4a4792012-02-23 23:10:27 +000036
37 def url_text(self):
38 global statistics
39 text = self.valobj.CreateChildAtOffset("text",
40 self.offset(),
Enrico Granatacfdafa32012-03-05 19:56:33 +000041 self.sys_params.types_cache.NSString)
Enrico Granataeb4a4792012-02-23 23:10:27 +000042 my_string = text.GetSummary()
43 if (my_string == None) or (my_string == ''):
44 statistics.metric_hit('unknown_class',str(self.valobj) + " triggered unkown pointer location")
Enrico Granatacfdafa32012-03-05 19:56:33 +000045 return NSBundleUnknown_SummaryProvider(self.valobj, self.sys_params).url_text()
Enrico Granataeb4a4792012-02-23 23:10:27 +000046 else:
47 statistics.metric_hit('code_notrun',self.valobj)
48 return my_string
49
50
51class NSBundleUnknown_SummaryProvider:
52 def adjust_for_architecture(self):
Enrico Granatacfdafa32012-03-05 19:56:33 +000053 pass
Enrico Granataeb4a4792012-02-23 23:10:27 +000054
Enrico Granatacfdafa32012-03-05 19:56:33 +000055 def __init__(self, valobj, params):
Enrico Granataeb4a4792012-02-23 23:10:27 +000056 self.valobj = valobj;
Enrico Granatacfdafa32012-03-05 19:56:33 +000057 self.sys_params = params
Enrico Granataeb4a4792012-02-23 23:10:27 +000058 self.update()
59
60 def update(self):
61 self.adjust_for_architecture();
Enrico Granataeb4a4792012-02-23 23:10:27 +000062
63 def url_text(self):
64 stream = lldb.SBStream()
65 self.valobj.GetExpressionPath(stream)
66 expr = "(NSString*)[" + stream.GetData() + " bundlePath]"
67 url_text_vo = self.valobj.CreateValueFromExpression("path",expr);
68 return url_text_vo.GetSummary()
69
70
71def GetSummary_Impl(valobj):
72 global statistics
73 class_data = objc_runtime.ObjCRuntime(valobj)
74 if class_data.is_valid() == False:
75 statistics.metric_hit('invalid_pointer',valobj)
76 wrapper = None
77 return
78 class_data = class_data.read_class_data()
79 if class_data.is_valid() == False:
80 statistics.metric_hit('invalid_isa',valobj)
81 wrapper = None
82 return
83 if class_data.is_kvo():
84 class_data = class_data.get_superclass()
85 if class_data.is_valid() == False:
86 statistics.metric_hit('invalid_isa',valobj)
87 wrapper = None
88 return
89
90 name_string = class_data.class_name()
91 if name_string == 'NSBundle':
Enrico Granatacfdafa32012-03-05 19:56:33 +000092 wrapper = NSBundleKnown_SummaryProvider(valobj, class_data.sys_params)
Enrico Granataeb4a4792012-02-23 23:10:27 +000093 # [NSBundle mainBundle] does return an object that is
94 # not correctly filled out for our purposes, so we still
95 # end up having to run code in that case
96 #statistics.metric_hit('code_notrun',valobj)
97 else:
Enrico Granatacfdafa32012-03-05 19:56:33 +000098 wrapper = NSBundleUnknown_SummaryProvider(valobj, class_data.sys_params)
Enrico Granataeb4a4792012-02-23 23:10:27 +000099 statistics.metric_hit('unknown_class',str(valobj) + " seen as " + name_string)
100 return wrapper;
101
102def NSBundle_SummaryProvider (valobj,dict):
103 provider = GetSummary_Impl(valobj);
104 if provider != None:
105 try:
106 summary = provider.url_text();
107 except:
108 summary = None
109 if summary == None or summary == '':
110 summary = 'no valid NSBundle here'
111 return summary
112 return ''
113
114def __lldb_init_module(debugger,dict):
115 debugger.HandleCommand("type summary add -F NSBundle.NSBundle_SummaryProvider NSBundle")