mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-05-17 22:03:07 -06:00
426 lines
10 KiB
Python
426 lines
10 KiB
Python
import gdb.printing
|
|
import re
|
|
|
|
# just for debugging purposes
|
|
def dump(obj):
|
|
'''return a printable representation of an object for debugging'''
|
|
newobj=obj
|
|
if '__dict__' in dir(obj):
|
|
newobj=obj.__dict__
|
|
if ' object at ' in str(obj) and not newobj.has_key('__type__'):
|
|
newobj['__type__']=str(obj)
|
|
for attr in newobj:
|
|
newobj[attr]=dump(newobj[attr])
|
|
return newobj
|
|
|
|
# Upp::String printer
|
|
class UppStringPrinter(object):
|
|
"Print an Upp::String"
|
|
|
|
def __init__(self, val):
|
|
self.val = val
|
|
|
|
def to_string(self):
|
|
try:
|
|
SMALL = 0
|
|
MEDIUM = 31
|
|
KIND = 14
|
|
SLEN = 15
|
|
LLEN = 2
|
|
CHR = self.val['chr']
|
|
IsSmall = (CHR[KIND] == SMALL)
|
|
if(IsSmall):
|
|
ptr = CHR
|
|
else:
|
|
ptr = self.val['ptr']
|
|
return '"' + ptr.string() + '"'
|
|
except Exception as inst:
|
|
return "<can't read string>"
|
|
|
|
def display_hint(self):
|
|
return 'String'
|
|
|
|
# Upp::String* printer
|
|
class UppStringPtrPrinter(object):
|
|
"Print an Upp::String *"
|
|
|
|
def __init__(self, val):
|
|
self.val = val
|
|
|
|
def to_string(self):
|
|
return '@' + str(self.val.address) + ': ' + UppStringPrinter(self.val).to_string()
|
|
|
|
def display_hint(self):
|
|
return 'String'
|
|
|
|
# Upp::Vector printer
|
|
class UppVectorPrinter(object):
|
|
"Print an Upp::Vector"
|
|
class _iterator:
|
|
def __init__ (self, val):
|
|
self.val = val
|
|
self.item = val['vector']
|
|
self.finish = self.item + val['items']
|
|
self.count = 0
|
|
|
|
def __iter__(self):
|
|
return self
|
|
|
|
def next(self):
|
|
count = self.count
|
|
self.count = self.count + 1
|
|
if count == 0:
|
|
return ('.items', self.val['items'])
|
|
if count == 1:
|
|
return ('.alloc', self.val['alloc'])
|
|
if self.item == self.finish:
|
|
raise StopIteration
|
|
elt = self.item.dereference()
|
|
self.item = self.item + 1
|
|
return ('[%d]' % (count-2), elt)
|
|
|
|
def __init__(self, typename, val):
|
|
self.typename = typename
|
|
self.val = val
|
|
|
|
def children(self):
|
|
return self._iterator(self.val)
|
|
|
|
def to_string(self):
|
|
start = 0
|
|
finish = self.val['items']
|
|
end = self.val['alloc']
|
|
return ('%s count %d alloc %d'
|
|
% (self.typename, int (finish - start), int (end - start)))
|
|
|
|
def display_hint(self):
|
|
return 'array'
|
|
|
|
# Upp::Array printer
|
|
class UppArrayPrinter(object):
|
|
"Print an Upp::Array"
|
|
class _iterator:
|
|
def __init__ (self, val):
|
|
self.val = val['vector']
|
|
self.item = self.val['vector']
|
|
self.finish = self.item + self.val['items']
|
|
self.count = 0
|
|
|
|
def __iter__(self):
|
|
return self
|
|
|
|
def next(self):
|
|
count = self.count
|
|
self.count = self.count + 1
|
|
if count == 0:
|
|
return ('.items', self.val['items'])
|
|
if count == 1:
|
|
return ('.alloc', self.val['alloc'])
|
|
if self.item == self.finish:
|
|
raise StopIteration
|
|
elt = self.item.dereference().dereference()
|
|
self.item = self.item + 1
|
|
return ('[%d]' % (count-2), elt)
|
|
|
|
def __init__(self, typename, val):
|
|
self.typename = typename
|
|
self.val = val
|
|
|
|
def children(self):
|
|
return self._iterator(self.val)
|
|
|
|
def to_string(self):
|
|
start = 0
|
|
finish = self.val['vector']['items']
|
|
end = self.val['vector']['alloc']
|
|
return ('%s count %d alloc %d'
|
|
% (self.typename, int (finish - start), int (end - start)))
|
|
|
|
def display_hint(self):
|
|
return 'array'
|
|
|
|
# Upp::VectorMap and ArrayMap printer
|
|
class UppMapPrinter(object):
|
|
"Print an Upp::VectorMap or ArrayMap"
|
|
|
|
def __init__(self, typename, val):
|
|
self.typename = typename
|
|
self.val = val
|
|
|
|
def children(self):
|
|
return [('.keys', self.val['key']), ('.values', self.val['value'])].__iter__()
|
|
|
|
def to_string(self):
|
|
count = self.val['key']['key']['items']
|
|
alloc = self.val['key']['key']['alloc']
|
|
return ('%s count %d alloc %d'
|
|
% (self.typename, count, alloc))
|
|
|
|
def display_hint(self):
|
|
return 'array'
|
|
|
|
# Upp::Value printer
|
|
class UppValuePrinter(object):
|
|
|
|
def __init__(self, val):
|
|
self.typeIds ={
|
|
0:'void',
|
|
1:'int',
|
|
2:'double',
|
|
3:'Upp::String',
|
|
4:'Upp::Date',
|
|
5:'Upp::Time',
|
|
6:'ERROR',
|
|
7:'Upp::Value',
|
|
8:'Upp::WString',
|
|
9:'Upp::ValueArray',
|
|
10:'int64',
|
|
11:'bool',
|
|
12:'Upp::ValueMap'
|
|
}
|
|
self.val = val
|
|
|
|
def to_string(self):
|
|
try:
|
|
magic = self.val['magic']
|
|
except Exception as inst:
|
|
return '<value inspectors not supported>'
|
|
if magic[0] != 0xc436d851 or magic[1] != 0x72f67c76 or magic[2] != 0x3e5e10fd or magic[3] != 0xc90d370b:
|
|
return '<value not initialized>'
|
|
typeId = Upp_Value_GetType(self.val)
|
|
if typeId == 0:
|
|
return '<void>'
|
|
elif typeId in (1, 2, 3, 4, 5, 7, 8, 10, 11):
|
|
return str(Upp_Value_GetString(self.val))
|
|
elif typeId == 6:
|
|
return '<ERROR VALUE>'
|
|
else:
|
|
strVal = str(Upp_Value_GetString(self.val))
|
|
if strVal != '':
|
|
return strVal
|
|
else:
|
|
if self.typeIds.has_key(typeId):
|
|
return "<unsupported value type '" + self.typeIds[typeId] + "'>"
|
|
else:
|
|
return "<unsupported value type '" + str(typeId) + "'>"
|
|
|
|
# Upp::Value* printer
|
|
class UppValuePtrPrinter(object):
|
|
"Print an Upp::Value *"
|
|
|
|
def __init__(self, val):
|
|
self.val = val
|
|
|
|
def to_string(self):
|
|
return '@' + str(self.val.address) + ': ' + UppValuePrinter(self.val.dereference()).to_string()
|
|
|
|
def display_hint(self):
|
|
return 'String'
|
|
|
|
# Upp::One<> printer
|
|
class UppOnePrinter(object):
|
|
|
|
def __init__(self, val):
|
|
self.val = val
|
|
|
|
def to_string(self):
|
|
return str(self.val['ptr'].dereference())
|
|
|
|
# Upp::Point printer
|
|
class UppPointPrinter(object):
|
|
"Print an Upp::Point"
|
|
|
|
def __init__(self, val):
|
|
self.val = val
|
|
|
|
def to_string(self):
|
|
return '(' + str(self.val['x']) + ',' + str(self.val['y']) + ')'
|
|
|
|
# Upp::Point* printer
|
|
class UppPointPtrPrinter(object):
|
|
"Print an Upp::Point *"
|
|
|
|
def __init__(self, val):
|
|
self.val = val
|
|
|
|
def to_string(self):
|
|
return '@' + str(self.val.address) + ': ' + UppPointPrinter(self.val).to_string()
|
|
|
|
# Upp::Size printer
|
|
class UppSizePrinter(object):
|
|
"Print an Upp::Size"
|
|
|
|
def __init__(self, val):
|
|
self.val = val
|
|
|
|
def to_string(self):
|
|
return '(' + str(self.val['cx']) + ',' + str(self.val['cy']) + ')'
|
|
|
|
# Upp::Size* printer
|
|
class UppSizePtrPrinter(object):
|
|
"Print an Upp::Size *"
|
|
|
|
def __init__(self, val):
|
|
self.val = val
|
|
|
|
def to_string(self):
|
|
return '@' + str(self.val.address) + ': ' + UppSizePrinter(self.val).to_string()
|
|
|
|
# Upp::Rect printer
|
|
class UppRectPrinter(object):
|
|
"Print an Upp::Rect"
|
|
|
|
def __init__(self, val):
|
|
self.val = val
|
|
|
|
def to_string(self):
|
|
return '[' + str(self.val['left']) + ',' + str(self.val['top']) + '],[' + str(self.val['right']) + ',' + str(self.val['bottom']) + ']'
|
|
|
|
# Upp::Rect* printer
|
|
class UppRectPtrPrinter(object):
|
|
"Print an Upp::Rect *"
|
|
|
|
def __init__(self, val):
|
|
self.val = val
|
|
|
|
def to_string(self):
|
|
return '@' + str(self.val.address) + ': ' + UppRectPrinter(self.val).to_string()
|
|
|
|
def UppLookupFunction(val):
|
|
typeStr = str(val.type)
|
|
|
|
if typeStr == 'Upp::String *':
|
|
return UppStringPtrPrinter(val)
|
|
|
|
if typeStr == 'const Upp::String *':
|
|
return UppStringPtrPrinter(val)
|
|
|
|
if typeStr == 'Upp::String &':
|
|
return UppStringPtrPrinter(val.address)
|
|
|
|
if typeStr == 'const Upp::String &':
|
|
return UppStringPtrPrinter(val.address)
|
|
|
|
if typeStr == 'Upp::String':
|
|
return UppStringPrinter(val)
|
|
|
|
if typeStr == 'const Upp::String':
|
|
return UppStringPrinter(val)
|
|
|
|
##########################################################################
|
|
# FOR VALUES -- EXPERIMENTAL
|
|
# 2012/08/05 - REMOVED AGAIN AS IT CAUSED SOME RANDOM CRASHES
|
|
# NEEDS DEEPER INVESTIGATION
|
|
# if typeStr == 'Upp::Value *' and Upp_Value_Inspectors:
|
|
# return UppValuePtrPrinter(val)
|
|
|
|
# if typeStr == 'const Upp::Value *' and Upp_Value_Inspectors:
|
|
# return UppValuePtrPrinter(val)
|
|
|
|
# if typeStr == 'Upp::Value &' and Upp_Value_Inspectors:
|
|
# return UppValuePtrPrinter(val.address)
|
|
|
|
# if typeStr == 'const Upp::Value &' and Upp_Value_Inspectors:
|
|
# return UppValuePtrPrinter(val.address)
|
|
|
|
# if typeStr == 'Upp::Value' and Upp_Value_Inspectors:
|
|
# return UppValuePrinter(val)
|
|
|
|
# if typeStr == 'const Upp::Value' and Upp_Value_Inspectors:
|
|
# return UppValuePrinter(val)
|
|
|
|
##########################################################################
|
|
if typeStr == 'Upp::Point' or typeStr == 'Upp::Pointf':
|
|
return UppPointPrinter(val)
|
|
|
|
if typeStr == 'const Upp::Point' or typeStr == 'const Upp::Pointf':
|
|
return UppPointPrinter(val)
|
|
|
|
if typeStr == 'Upp::Point *' or typeStr == 'Upp::Pointf *':
|
|
return UppPointPtrPrinter(val)
|
|
|
|
if typeStr == 'const Upp::Point *' or typeStr == 'const Upp::Pointf *':
|
|
return UppPointPtrPrinter(val)
|
|
|
|
if typeStr == 'Upp::Size' or typeStr == 'Upp::Sizef':
|
|
return UppSizePrinter(val)
|
|
|
|
if typeStr == 'const Upp::Size' or typeStr == 'const Upp::Sizef':
|
|
return UppSizePrinter(val)
|
|
|
|
if typeStr == 'Upp::Size *' or typeStr == 'Upp::Sizef *':
|
|
return UppSizePtrPrinter(val)
|
|
|
|
if typeStr == 'const Upp::Size *' or typeStr == 'const Upp::Sizef *':
|
|
return UppSizePtrPrinter(val)
|
|
|
|
if typeStr == 'Upp::Rect' or typeStr == 'Upp::Rectf':
|
|
return UppRectPrinter(val)
|
|
|
|
if typeStr == 'const Upp::Rect' or typeStr == 'const Upp::Rectf':
|
|
return UppRectPrinter(val)
|
|
|
|
if typeStr == 'Upp::Rect *' or typeStr == 'Upp::Rectf *':
|
|
return UppRectPtrPrinter(val)
|
|
|
|
if typeStr == 'const Upp::Rect *' or typeStr == 'const Upp::Rectf *':
|
|
return UppRectPtrPrinter(val)
|
|
|
|
lookup_tag = val.type.tag
|
|
if lookup_tag == None:
|
|
return None
|
|
|
|
regex = re.compile("^Upp::VectorMap<.*>$")
|
|
if regex.match(lookup_tag):
|
|
return UppMapPrinter(lookup_tag, val)
|
|
|
|
regex = re.compile("^Upp::ArrayMap<.*>$")
|
|
if regex.match(lookup_tag):
|
|
return UppMapPrinter(lookup_tag, val)
|
|
|
|
regex = re.compile("^Upp::Vector<.*>$")
|
|
if regex.match(lookup_tag):
|
|
return UppVectorPrinter(lookup_tag, val)
|
|
|
|
regex = re.compile("^Upp::Array<.*>$")
|
|
if regex.match(lookup_tag):
|
|
return UppArrayPrinter(lookup_tag, val)
|
|
|
|
regex = re.compile("^Upp::Index<.*>$")
|
|
if regex.match(lookup_tag):
|
|
return UppVectorPrinter(lookup_tag, val['key'])
|
|
|
|
regex = re.compile("^Upp::One<.*>$")
|
|
if regex.match(lookup_tag):
|
|
return UppOnePrinter(val)
|
|
|
|
return None
|
|
|
|
#check if Upp value inspecting support is enabled
|
|
Upp_Value_Inspectors = True
|
|
try:
|
|
Upp_Value_GetType = gdb.parse_and_eval('Upp::_DBG_Value_GetType')
|
|
Upp_Value_GetString = gdb.parse_and_eval('Upp::_DBG_Value_AsString')
|
|
except Exception as inst:
|
|
Upp_Value_Inspectors = False
|
|
|
|
#check if debug ungrab support is enabled
|
|
Upp_Ungrab_Support = True
|
|
try:
|
|
Upp_Ungrab = gdb.parse_and_eval('Upp::_DBG_Ungrab')
|
|
except Exception as inst:
|
|
Upp_Ungrab_Support = False
|
|
|
|
#ungrab mouse at debugger stop, if ungrab helper is available
|
|
def stop_handler(event):
|
|
if Upp_Ungrab_Support:
|
|
Upp_Ungrab()
|
|
|
|
gdb.events.stop.connect (stop_handler)
|
|
|
|
|
|
gdb.pretty_printers.append(UppLookupFunction)
|
|
|
|
#a couple of lines to test it quickly on gdb....
|
|
#source /home/massimo/sources/upp-svn/uppsrc/ide/Debuggers/PrettyPrinters.py
|
|
#python gdb.pretty_printers.remove(UppLookupFunction)
|