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.
"""
Enrico Granata
committed
# summary provider for NSBundle
import lldb
import ctypes
import objc_runtime
import metrics
import NSURL
Enrico Granata
committed
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):
pass
Enrico Granata
committed
def __init__(self, valobj, params):
Enrico Granata
committed
self.valobj = valobj;
self.sys_params = params
if not(self.sys_params.types_cache.NSString):
self.sys_params.types_cache.NSString = self.valobj.GetTarget().FindFirstType('NSString').GetPointerType()
Enrico Granata
committed
self.update();
def update(self):
Enrico Granata
committed
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):
return 5 * self.sys_params.pointer_size
Enrico Granata
committed
def url_text(self):
Enrico Granata
committed
global statistics
text = self.valobj.CreateChildAtOffset("text",
self.offset(),
self.sys_params.types_cache.NSString)
Enrico Granata
committed
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()
Enrico Granata
committed
else:
statistics.metric_hit('code_notrun',self.valobj)
return my_string
class NSBundleUnknown_SummaryProvider:
def adjust_for_architecture(self):
pass
Enrico Granata
committed
def __init__(self, valobj, params):
Enrico Granata
committed
self.valobj = valobj;
self.sys_params = params
Enrico Granata
committed
self.update()
def update(self):
Enrico Granata
committed
self.adjust_for_architecture();
def url_text(self):
Enrico Granata
committed
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>'
Enrico Granata
committed
def GetSummary_Impl(valobj):
Enrico Granata
committed
global statistics
class_data,wrapper = objc_runtime.Utilities.prepare_class_detection(valobj,statistics)
if wrapper:
return wrapper
Enrico Granata
committed
name_string = class_data.class_name()
logger >> "class name is: " + str(name_string)
Enrico Granata
committed
if name_string == 'NSBundle':
wrapper = NSBundleKnown_SummaryProvider(valobj, class_data.sys_params)
Enrico Granata
committed
# [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)
Enrico Granata
committed
return wrapper;
def NSBundle_SummaryProvider (valobj,dict):
Enrico Granata
committed
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
if summary == None or summary == '':
summary = '<variable is not NSBundle>'
return summary
return 'Summary Unavailable'
Enrico Granata
committed
def __lldb_init_module(debugger,dict):
debugger.HandleCommand("type summary add -F NSBundle.NSBundle_SummaryProvider NSBundle")