Skip to content
NSBundle.py 3.85 KiB
Newer Older
"""
LLDB AppKit formatters

part of The LLVM Compiler Infrastructure
This file is distributed under the University of Illinois Open Source
License. See LICENSE.TXT for details.
"""
# summary provider for NSBundle
import lldb
import ctypes
import objc_runtime
import metrics
import NSURL
import Logger

statistics = metrics.Metrics()
statistics.add_metric('invalid_isa')
statistics.add_metric('invalid_pointer')
statistics.add_metric('unknown_class')
statistics.add_metric('code_notrun')

# despite the similary to synthetic children providers, these classes are not
# trying to provide anything but a summary for an NSURL, so they need not
# obey the interface specification for synthetic children providers
class NSBundleKnown_SummaryProvider:
	def adjust_for_architecture(self):
		logger = Logger.Logger()
		self.sys_params = params
		if not(self.sys_params.types_cache.NSString):
			self.sys_params.types_cache.NSString = self.valobj.GetTarget().FindFirstType('NSString').GetPointerType()
		logger = Logger.Logger()
		self.adjust_for_architecture();

	# we need to skip the ISA, plus four other values
	# that are luckily each a pointer in size
	# which makes our computation trivial :-)
	def offset(self):
		logger = Logger.Logger()
		return 5 * self.sys_params.pointer_size
		logger = Logger.Logger()
		global statistics
		text = self.valobj.CreateChildAtOffset("text",
							self.offset(),
							self.sys_params.types_cache.NSString)
		my_string = text.GetSummary()
		if (my_string == None) or (my_string == ''):
			statistics.metric_hit('unknown_class',str(self.valobj.GetName()) + " triggered unkown pointer location")
			return NSBundleUnknown_SummaryProvider(self.valobj, self.sys_params).url_text()
		else:
			statistics.metric_hit('code_notrun',self.valobj)
			return my_string


class NSBundleUnknown_SummaryProvider:
	def adjust_for_architecture(self):
		logger = Logger.Logger()
		logger = Logger.Logger()
		self.adjust_for_architecture();

	def url_text(self):
		logger = Logger.Logger()
		stream = lldb.SBStream()
		self.valobj.GetExpressionPath(stream)
		expr = "(NSString*)[" + stream.GetData() + " bundlePath]"
		url_text_vo = self.valobj.CreateValueFromExpression("path",expr);
		if url_text_vo.IsValid():
			return url_text_vo.GetSummary()
		return '<variable is not NSBundle>'
	logger = Logger.Logger()
	class_data,wrapper = objc_runtime.Utilities.prepare_class_detection(valobj,statistics)
	if wrapper:
		return wrapper
	logger >> "class name is: " + str(name_string)
	
		wrapper = NSBundleKnown_SummaryProvider(valobj, class_data.sys_params)
		# [NSBundle mainBundle] does return an object that is
		# not correctly filled out for our purposes, so we still
		# end up having to run code in that case
		#statistics.metric_hit('code_notrun',valobj)
	else:
		wrapper = NSBundleUnknown_SummaryProvider(valobj, class_data.sys_params)
		statistics.metric_hit('unknown_class',valobj.GetName() + " seen as " + name_string)
	return wrapper;

def NSBundle_SummaryProvider (valobj,dict):
	logger = Logger.Logger()
	provider = GetSummary_Impl(valobj);
	if provider != None:
		if isinstance(provider,objc_runtime.SpecialSituation_Description):
			return provider.message()
		try:
			summary = provider.url_text();
		except:
			summary = None
		logger >> "got summary " + str(summary)
		if summary == None or summary == '':
			summary = '<variable is not NSBundle>'
		return summary
	return 'Summary Unavailable'

def __lldb_init_module(debugger,dict):
	debugger.HandleCommand("type summary add -F NSBundle.NSBundle_SummaryProvider NSBundle")