1579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata"""
2579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico GranataLLDB AppKit formatters
3579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata
4579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granatapart of The LLVM Compiler Infrastructure
5579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico GranataThis file is distributed under the University of Illinois Open Source
6579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico GranataLicense. See LICENSE.TXT for details.
7579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata"""
8b370df27c76fd875f3312be487868528121a4838Enrico Granata# summary provider for NSURL
9b370df27c76fd875f3312be487868528121a4838Enrico Granataimport lldb
10b370df27c76fd875f3312be487868528121a4838Enrico Granataimport ctypes
110d235d5864e996d95f485df1a0df406126e1ccdeEnrico Granataimport lldb.runtime.objc.objc_runtime
120d235d5864e996d95f485df1a0df406126e1ccdeEnrico Granataimport lldb.formatters.metrics
13b370df27c76fd875f3312be487868528121a4838Enrico Granataimport CFString
140d235d5864e996d95f485df1a0df406126e1ccdeEnrico Granataimport lldb.formatters.Logger
15b370df27c76fd875f3312be487868528121a4838Enrico Granata
160d235d5864e996d95f485df1a0df406126e1ccdeEnrico Granatastatistics = lldb.formatters.metrics.Metrics()
17b370df27c76fd875f3312be487868528121a4838Enrico Granatastatistics.add_metric('invalid_isa')
18b370df27c76fd875f3312be487868528121a4838Enrico Granatastatistics.add_metric('invalid_pointer')
19b370df27c76fd875f3312be487868528121a4838Enrico Granatastatistics.add_metric('unknown_class')
20b370df27c76fd875f3312be487868528121a4838Enrico Granatastatistics.add_metric('code_notrun')
21b370df27c76fd875f3312be487868528121a4838Enrico Granata
22b370df27c76fd875f3312be487868528121a4838Enrico Granata# despite the similary to synthetic children providers, these classes are not
23b370df27c76fd875f3312be487868528121a4838Enrico Granata# trying to provide anything but a summary for an NSURL, so they need not
24b370df27c76fd875f3312be487868528121a4838Enrico Granata# obey the interface specification for synthetic children providers
25b370df27c76fd875f3312be487868528121a4838Enrico Granataclass NSURLKnown_SummaryProvider:
26b370df27c76fd875f3312be487868528121a4838Enrico Granata	def adjust_for_architecture(self):
27f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata		pass
28b370df27c76fd875f3312be487868528121a4838Enrico Granata
29f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata	def __init__(self, valobj, params):
300d235d5864e996d95f485df1a0df406126e1ccdeEnrico Granata		logger = lldb.formatters.Logger.Logger()
31b370df27c76fd875f3312be487868528121a4838Enrico Granata		self.valobj = valobj;
32f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata		self.sys_params = params
33f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata		if not(self.sys_params.types_cache.NSString):
34f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata			self.sys_params.types_cache.NSString = self.valobj.GetTarget().FindFirstType('NSString').GetPointerType()
35f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata		if not(self.sys_params.types_cache.NSURL):
36f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata			self.sys_params.types_cache.NSURL = self.valobj.GetTarget().FindFirstType('NSURL').GetPointerType()
37b370df27c76fd875f3312be487868528121a4838Enrico Granata		self.update();
38b370df27c76fd875f3312be487868528121a4838Enrico Granata
39b370df27c76fd875f3312be487868528121a4838Enrico Granata	def update(self):
400d235d5864e996d95f485df1a0df406126e1ccdeEnrico Granata		logger = lldb.formatters.Logger.Logger()
41b370df27c76fd875f3312be487868528121a4838Enrico Granata		self.adjust_for_architecture();
42b370df27c76fd875f3312be487868528121a4838Enrico Granata
43b370df27c76fd875f3312be487868528121a4838Enrico Granata	# one pointer is the ISA
44b370df27c76fd875f3312be487868528121a4838Enrico Granata	# then there is one more pointer and 8 bytes of plain data
45b370df27c76fd875f3312be487868528121a4838Enrico Granata	# (which are also present on a 32-bit system)
4608d6681715eaf4c24d7d42b8c514d055c8125c7aEnrico Granata	# then there is a pointer to an NSString which is the url text
4708d6681715eaf4c24d7d42b8c514d055c8125c7aEnrico Granata	# optionally, the next pointer is another NSURL which is the "base"
4808d6681715eaf4c24d7d42b8c514d055c8125c7aEnrico Granata	# of this one when doing NSURLs composition (incidentally, NSURLs can
4908d6681715eaf4c24d7d42b8c514d055c8125c7aEnrico Granata	# recurse the base+text mechanism to any desired depth)
50f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata	def offset_text(self):
510d235d5864e996d95f485df1a0df406126e1ccdeEnrico Granata		logger = lldb.formatters.Logger.Logger()
52f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata		return 24 if self.sys_params.is_64_bit else 16
53f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata	def offset_base(self):
540d235d5864e996d95f485df1a0df406126e1ccdeEnrico Granata		logger = lldb.formatters.Logger.Logger()
55f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata		return self.offset_text()+self.sys_params.pointer_size
56b370df27c76fd875f3312be487868528121a4838Enrico Granata
57b370df27c76fd875f3312be487868528121a4838Enrico Granata	def url_text(self):
580d235d5864e996d95f485df1a0df406126e1ccdeEnrico Granata		logger = lldb.formatters.Logger.Logger()
59b370df27c76fd875f3312be487868528121a4838Enrico Granata		text = self.valobj.CreateChildAtOffset("text",
60f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata							self.offset_text(),
61f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata							self.sys_params.types_cache.NSString)
62b370df27c76fd875f3312be487868528121a4838Enrico Granata		base = self.valobj.CreateChildAtOffset("base",
63f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata							self.offset_base(),
64f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata							self.sys_params.types_cache.NSURL)
65b370df27c76fd875f3312be487868528121a4838Enrico Granata		my_string = CFString.CFString_SummaryProvider(text,None)
667b9aacf4a454465af905e505f74245173714b23bEnrico Granata		if len(my_string) > 0 and base.GetValueAsUnsigned(0) != 0:
677b9aacf4a454465af905e505f74245173714b23bEnrico Granata			# remove final " from myself
687b9aacf4a454465af905e505f74245173714b23bEnrico Granata			my_string = my_string[0:len(my_string)-1]
697b9aacf4a454465af905e505f74245173714b23bEnrico Granata			my_string = my_string + ' -- '
707b9aacf4a454465af905e505f74245173714b23bEnrico Granata			my_base_string = NSURL_SummaryProvider(base,None)
717b9aacf4a454465af905e505f74245173714b23bEnrico Granata			if len(my_base_string) > 2:
727b9aacf4a454465af905e505f74245173714b23bEnrico Granata				# remove @" marker from base URL string
737b9aacf4a454465af905e505f74245173714b23bEnrico Granata				my_base_string = my_base_string[2:]
747b9aacf4a454465af905e505f74245173714b23bEnrico Granata			my_string = my_string + my_base_string
75b370df27c76fd875f3312be487868528121a4838Enrico Granata		return my_string
76b370df27c76fd875f3312be487868528121a4838Enrico Granata
77b370df27c76fd875f3312be487868528121a4838Enrico Granata
78b370df27c76fd875f3312be487868528121a4838Enrico Granataclass NSURLUnknown_SummaryProvider:
79b370df27c76fd875f3312be487868528121a4838Enrico Granata	def adjust_for_architecture(self):
80f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata		pass
81b370df27c76fd875f3312be487868528121a4838Enrico Granata
82f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata	def __init__(self, valobj, params):
830d235d5864e996d95f485df1a0df406126e1ccdeEnrico Granata		logger = lldb.formatters.Logger.Logger()
84b370df27c76fd875f3312be487868528121a4838Enrico Granata		self.valobj = valobj;
85f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata		self.sys_params = params
86b370df27c76fd875f3312be487868528121a4838Enrico Granata		self.update()
87b370df27c76fd875f3312be487868528121a4838Enrico Granata
88b370df27c76fd875f3312be487868528121a4838Enrico Granata	def update(self):
890d235d5864e996d95f485df1a0df406126e1ccdeEnrico Granata		logger = lldb.formatters.Logger.Logger()
90b370df27c76fd875f3312be487868528121a4838Enrico Granata		self.adjust_for_architecture();
91b370df27c76fd875f3312be487868528121a4838Enrico Granata
92b370df27c76fd875f3312be487868528121a4838Enrico Granata	def url_text(self):
930d235d5864e996d95f485df1a0df406126e1ccdeEnrico Granata		logger = lldb.formatters.Logger.Logger()
94b370df27c76fd875f3312be487868528121a4838Enrico Granata		stream = lldb.SBStream()
95b370df27c76fd875f3312be487868528121a4838Enrico Granata		self.valobj.GetExpressionPath(stream)
96579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata		url_text_vo = self.valobj.CreateValueFromExpression("url","(NSString*)[" + stream.GetData() + " description]")
97579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata		if url_text_vo.IsValid():
98579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata			return CFString.CFString_SummaryProvider(url_text_vo,None)
99579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata		return '<variable is not NSURL>'
100b370df27c76fd875f3312be487868528121a4838Enrico Granata
101b370df27c76fd875f3312be487868528121a4838Enrico Granata
102b370df27c76fd875f3312be487868528121a4838Enrico Granatadef GetSummary_Impl(valobj):
1030d235d5864e996d95f485df1a0df406126e1ccdeEnrico Granata	logger = lldb.formatters.Logger.Logger()
104b370df27c76fd875f3312be487868528121a4838Enrico Granata	global statistics
105a5c2ce05705f784fd4ada97823af6ff7006fea58Enrico Granata	class_data,wrapper =lldb.runtime.objc.objc_runtime.Utilities.prepare_class_detection(valobj,statistics)
106579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata	if wrapper:
107579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata		return wrapper
108b370df27c76fd875f3312be487868528121a4838Enrico Granata
109b370df27c76fd875f3312be487868528121a4838Enrico Granata	name_string = class_data.class_name()
1108f18240a09893310c43673901d863892ae7b0611Enrico Granata	logger >> "class name is: " + str(name_string)
1118f18240a09893310c43673901d863892ae7b0611Enrico Granata
112b370df27c76fd875f3312be487868528121a4838Enrico Granata	if name_string == 'NSURL':
113f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata		wrapper = NSURLKnown_SummaryProvider(valobj, class_data.sys_params)
114b370df27c76fd875f3312be487868528121a4838Enrico Granata		statistics.metric_hit('code_notrun',valobj)
115b370df27c76fd875f3312be487868528121a4838Enrico Granata	else:
116f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata		wrapper = NSURLUnknown_SummaryProvider(valobj, class_data.sys_params)
117805f79b15edd61887c26a3f0ea80457790ba5807Enrico Granata		statistics.metric_hit('unknown_class',valobj.GetName() + " seen as " + name_string)
118b370df27c76fd875f3312be487868528121a4838Enrico Granata	return wrapper;
119b370df27c76fd875f3312be487868528121a4838Enrico Granata
120b370df27c76fd875f3312be487868528121a4838Enrico Granatadef NSURL_SummaryProvider (valobj,dict):
1210d235d5864e996d95f485df1a0df406126e1ccdeEnrico Granata	logger = lldb.formatters.Logger.Logger()
122b370df27c76fd875f3312be487868528121a4838Enrico Granata	provider = GetSummary_Impl(valobj);
123b370df27c76fd875f3312be487868528121a4838Enrico Granata	if provider != None:
124a5c2ce05705f784fd4ada97823af6ff7006fea58Enrico Granata		if isinstance(provider,lldb.runtime.objc.objc_runtime.SpecialSituation_Description):
125579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata			return provider.message()
126579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata		try:
127579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata			summary = provider.url_text();
128579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata		except:
129579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata			summary = None
1308f18240a09893310c43673901d863892ae7b0611Enrico Granata		logger >> "got summary " + str(summary)
131579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata		if summary == None or summary == '':
132579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata			summary = '<variable is not NSURL>'
133579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata		return summary
134579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata	return 'Summary Unavailable'
135b370df27c76fd875f3312be487868528121a4838Enrico Granata
136b370df27c76fd875f3312be487868528121a4838Enrico Granatadef __lldb_init_module(debugger,dict):
137b370df27c76fd875f3312be487868528121a4838Enrico Granata	debugger.HandleCommand("type summary add -F NSURL.NSURL_SummaryProvider NSURL CFURLRef")
138