1"""
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"""
8# example summary provider for NSNotification
9# the real summary is now C++ code built into LLDB
10import lldb.runtime.objc.objc_runtime
11import lldb.formatters.metrics
12import CFString
13import lldb
14import lldb.formatters.Logger
15
16statistics = lldb.formatters.metrics.Metrics()
17statistics.add_metric('invalid_isa')
18statistics.add_metric('invalid_pointer')
19statistics.add_metric('unknown_class')
20statistics.add_metric('code_notrun')
21
22class NSConcreteNotification_SummaryProvider:
23	def adjust_for_architecture(self):
24		pass
25
26	def __init__(self, valobj, params):
27		logger = lldb.formatters.Logger.Logger()
28		self.valobj = valobj;
29		self.sys_params = params
30		if not (self.sys_params.types_cache.id):
31			self.sys_params.types_cache.id = self.valobj.GetType().GetBasicType(lldb.eBasicTypeObjCID)
32		self.update();
33
34	def update(self):
35		logger = lldb.formatters.Logger.Logger()
36		self.adjust_for_architecture();
37
38	# skip the ISA and go to the name pointer
39	def offset(self):
40		logger = lldb.formatters.Logger.Logger()
41		return self.sys_params.pointer_size
42
43	def name(self):
44		logger = lldb.formatters.Logger.Logger()
45		string_ptr = self.valobj.CreateChildAtOffset("name",
46							self.offset(),
47							self.sys_params.types_cache.id)
48		return CFString.CFString_SummaryProvider(string_ptr,None)
49
50
51class NSNotificationUnknown_SummaryProvider:
52	def adjust_for_architecture(self):
53		pass
54
55	def __init__(self, valobj, params):
56		logger = lldb.formatters.Logger.Logger()
57		self.valobj = valobj;
58		self.sys_params = params
59		self.update()
60
61	def update(self):
62		logger = lldb.formatters.Logger.Logger()
63		self.adjust_for_architecture();
64
65	def name(self):
66		logger = lldb.formatters.Logger.Logger()
67		stream = lldb.SBStream()
68		self.valobj.GetExpressionPath(stream)
69		name_vo = self.valobj.CreateValueFromExpression("name","(NSString*)[" + stream.GetData() + " name]")
70		if name_vo.IsValid():
71			return CFString.CFString_SummaryProvider(name_vo,None)
72		return '<variable is not NSNotification>'
73
74
75def GetSummary_Impl(valobj):
76	logger = lldb.formatters.Logger.Logger()
77	global statistics
78	class_data,wrapper =lldb.runtime.objc.objc_runtime.Utilities.prepare_class_detection(valobj,statistics)
79	if wrapper:
80		return wrapper
81
82	name_string = class_data.class_name()
83	logger >> "class name is: " + str(name_string)
84
85	if name_string == 'NSConcreteNotification':
86		wrapper = NSConcreteNotification_SummaryProvider(valobj, class_data.sys_params)
87		statistics.metric_hit('code_notrun',valobj)
88	else:
89		wrapper = NSNotificationUnknown_SummaryProvider(valobj, class_data.sys_params)
90		statistics.metric_hit('unknown_class',valobj.GetName() + " seen as " + name_string)
91	return wrapper;
92
93def NSNotification_SummaryProvider (valobj,dict):
94	logger = lldb.formatters.Logger.Logger()
95	provider = GetSummary_Impl(valobj);
96	if provider != None:
97		if isinstance(provider,lldb.runtime.objc.objc_runtime.SpecialSituation_Description):
98			return provider.message()
99		try:
100			summary = provider.name();
101		except:
102			summary = None
103		logger >> "got summary " + str(summary)
104		if summary == None:
105			summary = '<variable is not NSNotification>'
106		return str(summary)
107	return 'Summary Unavailable'
108
109def __lldb_init_module(debugger,dict):
110	debugger.HandleCommand("type summary add -F NSNotification.NSNotification_SummaryProvider NSNotification")
111