blob: 5e6b11a6fc0b67ed8a6e693c7c43d1f29290fd4d [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):
19 self.lp64 = (self.valobj.GetTarget().GetProcess().GetAddressByteSize() == 8)
20 self.is_little = (self.valobj.GetTarget().GetProcess().GetByteOrder() == lldb.eByteOrderLittle)
21 self.pointer_size = self.valobj.GetTarget().GetProcess().GetAddressByteSize()
22
23 def __init__(self, valobj):
24 self.valobj = valobj;
25 self.update();
26
27 def update(self):
28 self.adjust_for_architecture();
29 self.id_type = self.valobj.GetType().GetBasicType(lldb.eBasicTypeObjCID)
30 if self.lp64:
31 self.NSUInteger = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedLong)
32 self.pointer_size = 8
33 else:
34 self.NSUInteger = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedInt)
35 self.pointer_size = 4
36 self.NSString = self.valobj.GetTarget().FindFirstType('NSString')
37 self.NSURL = self.valobj.GetTarget().FindFirstType('NSURL')
38
39 # we need to skip the ISA, plus four other values
40 # that are luckily each a pointer in size
41 # which makes our computation trivial :-)
42 def offset(self):
43 return 5 * self.pointer_size
44
45 def url_text(self):
46 global statistics
47 text = self.valobj.CreateChildAtOffset("text",
48 self.offset(),
49 self.NSString.GetPointerType())
50 my_string = text.GetSummary()
51 if (my_string == None) or (my_string == ''):
52 statistics.metric_hit('unknown_class',str(self.valobj) + " triggered unkown pointer location")
53 return NSBundleUnknown_SummaryProvider(self.valobj).url_text()
54 else:
55 statistics.metric_hit('code_notrun',self.valobj)
56 return my_string
57
58
59class NSBundleUnknown_SummaryProvider:
60 def adjust_for_architecture(self):
61 self.lp64 = (self.valobj.GetTarget().GetProcess().GetAddressByteSize() == 8)
62 self.is_little = (self.valobj.GetTarget().GetProcess().GetByteOrder() == lldb.eByteOrderLittle)
63 self.pointer_size = self.valobj.GetTarget().GetProcess().GetAddressByteSize()
64
65 def __init__(self, valobj):
66 self.valobj = valobj;
67 self.update()
68
69 def update(self):
70 self.adjust_for_architecture();
71 self.id_type = self.valobj.GetType().GetBasicType(lldb.eBasicTypeObjCID)
72
73 def url_text(self):
74 stream = lldb.SBStream()
75 self.valobj.GetExpressionPath(stream)
76 expr = "(NSString*)[" + stream.GetData() + " bundlePath]"
77 url_text_vo = self.valobj.CreateValueFromExpression("path",expr);
78 return url_text_vo.GetSummary()
79
80
81def GetSummary_Impl(valobj):
82 global statistics
83 class_data = objc_runtime.ObjCRuntime(valobj)
84 if class_data.is_valid() == False:
85 statistics.metric_hit('invalid_pointer',valobj)
86 wrapper = None
87 return
88 class_data = class_data.read_class_data()
89 if class_data.is_valid() == False:
90 statistics.metric_hit('invalid_isa',valobj)
91 wrapper = None
92 return
93 if class_data.is_kvo():
94 class_data = class_data.get_superclass()
95 if class_data.is_valid() == False:
96 statistics.metric_hit('invalid_isa',valobj)
97 wrapper = None
98 return
99
100 name_string = class_data.class_name()
101 if name_string == 'NSBundle':
102 wrapper = NSBundleKnown_SummaryProvider(valobj)
103 # [NSBundle mainBundle] does return an object that is
104 # not correctly filled out for our purposes, so we still
105 # end up having to run code in that case
106 #statistics.metric_hit('code_notrun',valobj)
107 else:
108 wrapper = NSBundleUnknown_SummaryProvider(valobj)
109 statistics.metric_hit('unknown_class',str(valobj) + " seen as " + name_string)
110 return wrapper;
111
112def NSBundle_SummaryProvider (valobj,dict):
113 provider = GetSummary_Impl(valobj);
114 if provider != None:
115 try:
116 summary = provider.url_text();
117 except:
118 summary = None
119 if summary == None or summary == '':
120 summary = 'no valid NSBundle here'
121 return summary
122 return ''
123
124def __lldb_init_module(debugger,dict):
125 debugger.HandleCommand("type summary add -F NSBundle.NSBundle_SummaryProvider NSBundle")