forked from qt-creator/qt-creator
		
	Add make std::string usable as "compact" key.
Change-Id: Idbfcf9d299e2dde392025166a20c3d0ab60239a6
(cherry picked from commit 2776536a7e)
Reviewed-by: Christian Stenger <christian.stenger@digia.com>
		
	
		
			
				
	
	
		
			253 lines
		
	
	
		
			8.8 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			253 lines
		
	
	
		
			8.8 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
 | 
						|
import pdb;
 | 
						|
import sys;
 | 
						|
import linecache
 | 
						|
 | 
						|
def qdebug(options = None,
 | 
						|
            expanded = None,
 | 
						|
            typeformats = None,
 | 
						|
            individualformats = None,
 | 
						|
            watchers = None):
 | 
						|
 | 
						|
    class QDebug:
 | 
						|
        def __init__(self,
 | 
						|
                options = None,
 | 
						|
                expanded = None,
 | 
						|
                typeformats = None,
 | 
						|
                individualformats = None,
 | 
						|
                watchers = None):
 | 
						|
            self.options = options
 | 
						|
            self.expandedINames = expanded
 | 
						|
            self.typeformats = typeformats
 | 
						|
            self.individualformats = individualformats
 | 
						|
            self.watchers = watchers
 | 
						|
            self.buffer = ""
 | 
						|
            if self.options == "listmodules":
 | 
						|
                self.handleListModules()
 | 
						|
            elif self.options == "listsymbols":
 | 
						|
                self.handleListSymbols(expanded)
 | 
						|
            else:
 | 
						|
                self.handleListVars()
 | 
						|
 | 
						|
        def put(self, value):
 | 
						|
            #sys.stdout.write(value)
 | 
						|
            self.buffer += value
 | 
						|
 | 
						|
        def putField(self, name, value):
 | 
						|
            self.put('%s="%s",' % (name, value))
 | 
						|
 | 
						|
        def putItemCount(self, count):
 | 
						|
            self.put('value="<%s items>",' % count)
 | 
						|
 | 
						|
        def putEllipsis(self):
 | 
						|
            self.put('{name="<incomplete>",value="",type="",numchild="0"},')
 | 
						|
 | 
						|
        def cleanType(self, type):
 | 
						|
            t = str(type)
 | 
						|
            if t.startswith("<type '") and t.endswith("'>"):
 | 
						|
                t = t[7:-2]
 | 
						|
            if t.startswith("<class '") and t.endswith("'>"):
 | 
						|
                t = t[8:-2]
 | 
						|
            return t
 | 
						|
 | 
						|
        def putType(self, type, priority = 0):
 | 
						|
            self.putField("type", self.cleanType(type))
 | 
						|
 | 
						|
        def putAddress(self, addr):
 | 
						|
            self.put('addr="%s",' % cleanAddress(addr))
 | 
						|
 | 
						|
        def putNumChild(self, numchild):
 | 
						|
            self.put('numchild="%s",' % numchild)
 | 
						|
 | 
						|
        def putValue(self, value, encoding = None, priority = 0):
 | 
						|
            self.putField("value", value)
 | 
						|
 | 
						|
        def putName(self, name):
 | 
						|
            self.put('name="%s",' % name)
 | 
						|
 | 
						|
        def isExpanded(self, iname):
 | 
						|
            #self.warn("IS EXPANDED: %s in %s" % (iname, self.expandedINames))
 | 
						|
            if iname.startswith("None"):
 | 
						|
                raise "Illegal iname '%s'" % iname
 | 
						|
            #self.warn("   --> %s" % (iname in self.expandedINames))
 | 
						|
            return iname in self.expandedINames
 | 
						|
 | 
						|
        def isExpandedIName(self, iname):
 | 
						|
            return iname in self.expandedINames
 | 
						|
 | 
						|
        def itemFormat(self, item):
 | 
						|
            format = self.formats.get(str(cleanAddress(item.value.address)))
 | 
						|
            if format is None:
 | 
						|
                format = self.typeformats.get(self.stripClassTag(str(item.value.type)))
 | 
						|
            return format
 | 
						|
 | 
						|
        def dumpFrame(self, frame):
 | 
						|
            for var in frame.f_locals.keys():
 | 
						|
                if var == "__file__":
 | 
						|
                    continue
 | 
						|
                #if var == "__name__":
 | 
						|
                #    continue
 | 
						|
                if var == "__package__":
 | 
						|
                    continue
 | 
						|
                if var == "qdebug":
 | 
						|
                    continue
 | 
						|
                if var != '__builtins__':
 | 
						|
                    value = frame.f_locals[var]
 | 
						|
                    self.dumpValue(value, var, "local.%s" % var)
 | 
						|
 | 
						|
        def dumpValue(self, value, name, iname):
 | 
						|
            t = type(value)
 | 
						|
            tt = self.cleanType(t)
 | 
						|
            if tt == "module" or tt == "function":
 | 
						|
                return
 | 
						|
            if str(value).startswith("<class '"):
 | 
						|
                return
 | 
						|
            # FIXME: Should we?
 | 
						|
            if str(value).startswith("<enum-item "):
 | 
						|
                return
 | 
						|
            self.put("{")
 | 
						|
            self.putField("iname", iname)
 | 
						|
            self.putName(name)
 | 
						|
            self.putType(tt)
 | 
						|
            if tt == "NoneType":
 | 
						|
                self.putValue("None")
 | 
						|
                self.putNumChild(0)
 | 
						|
            elif tt == "list" or tt == "tuple":
 | 
						|
                self.putItemCount(len(value))
 | 
						|
                #self.putValue(value)
 | 
						|
                self.put("children=[")
 | 
						|
                for i in xrange(len(value)):
 | 
						|
                    self.dumpValue(value[i], str(i), "%s.%d" % (iname, i))
 | 
						|
                self.put("]")
 | 
						|
            elif tt == "str":
 | 
						|
                v = value
 | 
						|
                self.putValue(v.encode('hex'))
 | 
						|
                self.putField("valueencoded", 6)
 | 
						|
                self.putNumChild(0)
 | 
						|
            elif tt == "unicode":
 | 
						|
                v = value
 | 
						|
                self.putValue(v.encode('hex'))
 | 
						|
                self.putField("valueencoded", 6)
 | 
						|
                self.putNumChild(0)
 | 
						|
            elif tt == "buffer":
 | 
						|
                v = str(value)
 | 
						|
                self.putValue(v.encode('hex'))
 | 
						|
                self.putField("valueencoded", 6)
 | 
						|
                self.putNumChild(0)
 | 
						|
            elif tt == "xrange":
 | 
						|
                b = iter(value).next()
 | 
						|
                e = b + len(value)
 | 
						|
                self.putValue("(%d, %d)" % (b, e))
 | 
						|
                self.putNumChild(0)
 | 
						|
            elif tt == "dict":
 | 
						|
                self.putItemCount(len(value))
 | 
						|
                self.putField("childnumchild", 2)
 | 
						|
                self.put("children=[")
 | 
						|
                i = 0
 | 
						|
                for (k, v) in value.iteritems():
 | 
						|
                    self.put("{")
 | 
						|
                    self.putType(" ")
 | 
						|
                    self.putValue("%s: %s" % (k, v))
 | 
						|
                    if self.isExpanded(iname):
 | 
						|
                        self.put("children=[")
 | 
						|
                        self.dumpValue(k, "key", "%s.%d.k" % (iname, i))
 | 
						|
                        self.dumpValue(v, "value", "%s.%d.v" % (iname, i))
 | 
						|
                        self.put("]")
 | 
						|
                    self.put("},")
 | 
						|
                    i += 1
 | 
						|
                self.put("]")
 | 
						|
            elif tt == "class":
 | 
						|
                pass
 | 
						|
            elif tt == "module":
 | 
						|
                pass
 | 
						|
            elif tt == "function":
 | 
						|
                pass
 | 
						|
            elif str(value).startswith("<enum-item "):
 | 
						|
                # FIXME: Having enums always shown like this is not nice.
 | 
						|
                self.putValue(str(value)[11:-1])
 | 
						|
                self.putNumChild(0)
 | 
						|
            else:
 | 
						|
                v = str(value)
 | 
						|
                p = v.find(" object at ")
 | 
						|
                if p > 1:
 | 
						|
                    v = "@" + v[p + 11:-1]
 | 
						|
                self.putValue(v)
 | 
						|
                if self.isExpanded(iname):
 | 
						|
                    self.put("children=[")
 | 
						|
                    for child in dir(value):
 | 
						|
                        if child == "__dict__":
 | 
						|
                            continue
 | 
						|
                        if child == "__doc__":
 | 
						|
                            continue
 | 
						|
                        if child == "__module__":
 | 
						|
                            continue
 | 
						|
                        attr = getattr(value, child)
 | 
						|
                        if callable(attr):
 | 
						|
                            continue
 | 
						|
                        try:
 | 
						|
                            self.dumpValue(attr, child, "%s.%s" % (iname, child))
 | 
						|
                        except:
 | 
						|
                            pass
 | 
						|
                    self.put("],")
 | 
						|
            self.put("},")
 | 
						|
 | 
						|
 | 
						|
        def warn(self, msg):
 | 
						|
            self.putField("warning", msg)
 | 
						|
 | 
						|
        def handleListVars(self):
 | 
						|
            # Trigger error to get a backtrace.
 | 
						|
            frame = None
 | 
						|
            #self.warn("frame: %s" % frame)
 | 
						|
            try:
 | 
						|
                raise ZeroDivisionError
 | 
						|
            except ZeroDivisionError:
 | 
						|
                frame = sys.exc_info()[2].tb_frame.f_back
 | 
						|
 | 
						|
            limit = 30
 | 
						|
            n = 0
 | 
						|
            isActive = False
 | 
						|
            while frame is not None and n < limit:
 | 
						|
                #self.warn("frame: %s" % frame.f_locals.keys())
 | 
						|
                lineno = frame.f_lineno
 | 
						|
                code = frame.f_code
 | 
						|
                filename = code.co_filename
 | 
						|
                name = code.co_name
 | 
						|
                if isActive:
 | 
						|
                    linecache.checkcache(filename)
 | 
						|
                    line = linecache.getline(filename, lineno, frame.f_globals)
 | 
						|
                    self.dumpFrame(frame)
 | 
						|
                    if name == "<module>":
 | 
						|
                        isActive = False
 | 
						|
                if name == "trace_dispatch":
 | 
						|
                    isActive = True
 | 
						|
                frame = frame.f_back
 | 
						|
                n = n + 1
 | 
						|
            #sys.stdout.flush()
 | 
						|
 | 
						|
        def handleListModules(self):
 | 
						|
            self.put("modules=[");
 | 
						|
            for name in sys.modules:
 | 
						|
                self.put("{")
 | 
						|
                self.putName(name)
 | 
						|
                self.putValue(sys.modules[name])
 | 
						|
                self.put("},")
 | 
						|
            self.put("]")
 | 
						|
            #sys.stdout.flush()
 | 
						|
 | 
						|
        def handleListSymbols(self, module):
 | 
						|
            #self.put("symbols=%s" % dir(sys.modules[module]))
 | 
						|
            self.put("symbols=[");
 | 
						|
            for name in sys.modules:
 | 
						|
                self.put("{")
 | 
						|
                self.putName(name)
 | 
						|
                #self.putValue(sys.modules[name])
 | 
						|
                self.put("},")
 | 
						|
            self.put("]")
 | 
						|
            #sys.stdout.flush()
 | 
						|
 | 
						|
    d = QDebug(options, expanded, typeformats, individualformats, watchers)
 | 
						|
    #print d.buffer
 | 
						|
    sys.stdout.write(d.buffer)
 | 
						|
    sys.stdout.flush()
 |