| 
									
										
										
										
											2013-09-11 21:35:39 +02:00
										 |  |  | ############################################################################ | 
					
						
							|  |  |  | # | 
					
						
							| 
									
										
										
										
											2016-01-15 14:53:55 +01:00
										 |  |  | # Copyright (C) 2016 The Qt Company Ltd. | 
					
						
							|  |  |  | # Contact: https://www.qt.io/licensing/ | 
					
						
							| 
									
										
										
										
											2013-09-11 21:35:39 +02:00
										 |  |  | # | 
					
						
							|  |  |  | # This file is part of Qt Creator. | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | # Commercial License Usage | 
					
						
							|  |  |  | # Licensees holding valid commercial Qt licenses may use this file in | 
					
						
							|  |  |  | # accordance with the commercial license agreement provided with the | 
					
						
							|  |  |  | # Software or, alternatively, in accordance with the terms contained in | 
					
						
							| 
									
										
										
										
											2016-01-15 14:53:55 +01:00
										 |  |  | # a written agreement between you and The Qt Company. For licensing terms | 
					
						
							|  |  |  | # and conditions see https://www.qt.io/terms-conditions. For further | 
					
						
							|  |  |  | # information use the contact form at https://www.qt.io/contact-us. | 
					
						
							| 
									
										
										
										
											2013-09-11 21:35:39 +02:00
										 |  |  | # | 
					
						
							| 
									
										
										
										
											2016-01-15 14:53:55 +01:00
										 |  |  | # GNU General Public License Usage | 
					
						
							|  |  |  | # Alternatively, this file may be used under the terms of the GNU | 
					
						
							|  |  |  | # General Public License version 3 as published by the Free Software | 
					
						
							|  |  |  | # Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT | 
					
						
							|  |  |  | # included in the packaging of this file. Please review the following | 
					
						
							|  |  |  | # information to ensure the GNU General Public License requirements will | 
					
						
							|  |  |  | # be met: https://www.gnu.org/licenses/gpl-3.0.html. | 
					
						
							| 
									
										
										
										
											2013-09-11 21:35:39 +02:00
										 |  |  | # | 
					
						
							|  |  |  | ############################################################################ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import os | 
					
						
							| 
									
										
										
										
											2014-01-24 15:13:20 +01:00
										 |  |  | import struct | 
					
						
							| 
									
										
										
										
											2013-09-11 21:35:39 +02:00
										 |  |  | import sys | 
					
						
							|  |  |  | import base64 | 
					
						
							| 
									
										
										
										
											2014-05-12 13:09:02 +02:00
										 |  |  | import re | 
					
						
							| 
									
										
										
										
											2015-01-21 15:18:57 +01:00
										 |  |  | import time | 
					
						
							| 
									
										
										
										
											2015-10-08 16:19:57 +02:00
										 |  |  | import json | 
					
						
							| 
									
										
										
										
											2015-01-23 19:09:08 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-09-11 21:35:39 +02:00
										 |  |  | if sys.version_info[0] >= 3: | 
					
						
							|  |  |  |     xrange = range | 
					
						
							|  |  |  |     toInteger = int | 
					
						
							|  |  |  | else: | 
					
						
							|  |  |  |     toInteger = long | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | verbosity = 0 | 
					
						
							|  |  |  | verbosity = 1 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-02 17:05:52 +02:00
										 |  |  | # Debugger start modes. Keep in sync with DebuggerStartMode in debuggerconstants.h | 
					
						
							|  |  |  | NoStartMode, \ | 
					
						
							|  |  |  | StartInternal, \ | 
					
						
							|  |  |  | StartExternal,  \ | 
					
						
							|  |  |  | AttachExternal,  \ | 
					
						
							|  |  |  | AttachCrashedExternal,  \ | 
					
						
							|  |  |  | AttachCore, \ | 
					
						
							|  |  |  | AttachToRemoteServer, \ | 
					
						
							|  |  |  | AttachToRemoteProcess, \ | 
					
						
							|  |  |  | StartRemoteProcess, \ | 
					
						
							| 
									
										
										
										
											2014-10-14 19:08:58 +03:00
										 |  |  |     = range(0, 9) | 
					
						
							| 
									
										
										
										
											2014-06-02 17:05:52 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-12 11:26:10 +02:00
										 |  |  | # Known special formats. Keep in sync with DisplayFormat in debuggerprotocol.h | 
					
						
							| 
									
										
										
										
											2015-03-20 16:03:59 +01:00
										 |  |  | AutomaticFormat, \ | 
					
						
							|  |  |  | RawFormat, \ | 
					
						
							|  |  |  | SimpleFormat, \ | 
					
						
							|  |  |  | EnhancedFormat, \ | 
					
						
							|  |  |  | SeparateFormat, \ | 
					
						
							| 
									
										
										
										
											2014-04-15 18:13:03 +02:00
										 |  |  | Latin1StringFormat, \ | 
					
						
							| 
									
										
										
										
											2015-03-20 16:03:59 +01:00
										 |  |  | SeparateLatin1StringFormat, \ | 
					
						
							| 
									
										
										
										
											2014-04-15 18:13:03 +02:00
										 |  |  | Utf8StringFormat, \ | 
					
						
							| 
									
										
										
										
											2015-03-20 16:03:59 +01:00
										 |  |  | SeparateUtf8StringFormat, \ | 
					
						
							| 
									
										
										
										
											2014-04-15 18:13:03 +02:00
										 |  |  | Local8BitStringFormat, \ | 
					
						
							|  |  |  | Utf16StringFormat, \ | 
					
						
							|  |  |  | Ucs4StringFormat, \ | 
					
						
							|  |  |  | Array10Format, \ | 
					
						
							|  |  |  | Array100Format, \ | 
					
						
							|  |  |  | Array1000Format, \ | 
					
						
							| 
									
										
										
										
											2014-05-27 22:35:54 +02:00
										 |  |  | Array10000Format, \ | 
					
						
							| 
									
										
										
										
											2015-03-20 16:03:59 +01:00
										 |  |  | ArrayPlotFormat, \ | 
					
						
							|  |  |  | CompactMapFormat, \ | 
					
						
							|  |  |  | DirectQListStorageFormat, \ | 
					
						
							|  |  |  | IndirectQListStorageFormat, \ | 
					
						
							|  |  |  |     = range(0, 20) | 
					
						
							| 
									
										
										
										
											2014-04-15 18:13:03 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-13 10:02:35 +01:00
										 |  |  | # Breakpoints. Keep synchronized with BreakpointType in breakpoint.h | 
					
						
							|  |  |  | UnknownType, \ | 
					
						
							|  |  |  | BreakpointByFileAndLine, \ | 
					
						
							|  |  |  | BreakpointByFunction, \ | 
					
						
							|  |  |  | BreakpointByAddress, \ | 
					
						
							|  |  |  | BreakpointAtThrow, \ | 
					
						
							|  |  |  | BreakpointAtCatch, \ | 
					
						
							|  |  |  | BreakpointAtMain, \ | 
					
						
							|  |  |  | BreakpointAtFork, \ | 
					
						
							|  |  |  | BreakpointAtExec, \ | 
					
						
							|  |  |  | BreakpointAtSysCall, \ | 
					
						
							|  |  |  | WatchpointAtAddress, \ | 
					
						
							|  |  |  | WatchpointAtExpression, \ | 
					
						
							|  |  |  | BreakpointOnQmlSignalEmit, \ | 
					
						
							|  |  |  | BreakpointAtJavaScriptThrow, \ | 
					
						
							|  |  |  |     = range(0, 14) | 
					
						
							| 
									
										
										
										
											2015-01-21 15:18:57 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-12 11:26:10 +02:00
										 |  |  | # Display modes. Keep that synchronized with DebuggerDisplay in debuggerprotocol.h | 
					
						
							| 
									
										
										
										
											2015-04-01 17:19:43 +02:00
										 |  |  | StopDisplay, \ | 
					
						
							|  |  |  | DisplayImageData, \ | 
					
						
							|  |  |  | DisplayUtf16String, \ | 
					
						
							|  |  |  | DisplayImageFile, \ | 
					
						
							|  |  |  | DisplayLatin1String, \ | 
					
						
							|  |  |  | DisplayUtf8String, \ | 
					
						
							|  |  |  | DisplayPlotData \ | 
					
						
							|  |  |  |     = range(7) | 
					
						
							| 
									
										
										
										
											2015-01-21 15:18:57 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def arrayForms(): | 
					
						
							| 
									
										
										
										
											2015-04-01 17:19:43 +02:00
										 |  |  |     return [ArrayPlotFormat] | 
					
						
							| 
									
										
										
										
											2015-01-21 15:18:57 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | def mapForms(): | 
					
						
							| 
									
										
										
										
											2015-03-20 16:03:59 +01:00
										 |  |  |     return [CompactMapFormat] | 
					
						
							| 
									
										
										
										
											2013-09-11 21:35:39 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-16 00:18:17 +02:00
										 |  |  | class ReportItem: | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     Helper structure to keep temporary "best" information about a value | 
					
						
							|  |  |  |     or a type scheduled to be reported. This might get overridden be | 
					
						
							|  |  |  |     subsequent better guesses during a putItem() run. | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2014-05-19 10:55:33 +02:00
										 |  |  |     def __init__(self, value = None, encoding = None, priority = -100, elided = None): | 
					
						
							|  |  |  |         self.value = value | 
					
						
							|  |  |  |         self.priority = priority | 
					
						
							|  |  |  |         self.encoding = encoding | 
					
						
							|  |  |  |         self.elided = elided | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def __str__(self): | 
					
						
							|  |  |  |         return "Item(value: %s, encoding: %s, priority: %s, elided: %s)" \ | 
					
						
							|  |  |  |             % (self.value, self.encoding, self.priority, self.elided) | 
					
						
							| 
									
										
										
										
											2014-05-16 00:18:17 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-23 15:30:51 +01:00
										 |  |  | class Blob(object): | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     Helper structure to keep a blob of bytes, possibly | 
					
						
							|  |  |  |     in the inferior. | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def __init__(self, data, isComplete = True): | 
					
						
							|  |  |  |         self.data = data | 
					
						
							|  |  |  |         self.size = len(data) | 
					
						
							|  |  |  |         self.isComplete = isComplete | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def size(self): | 
					
						
							|  |  |  |         return self.size | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-24 15:13:20 +01:00
										 |  |  |     def toBytes(self): | 
					
						
							|  |  |  |         """Retrieves "lazy" contents from memoryviews.""" | 
					
						
							|  |  |  |         data = self.data | 
					
						
							| 
									
										
										
										
											2014-06-04 13:28:50 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         major = sys.version_info[0] | 
					
						
							|  |  |  |         if major == 3 or (major == 2 and sys.version_info[1] >= 7): | 
					
						
							|  |  |  |             if isinstance(data, memoryview): | 
					
						
							|  |  |  |                 data = data.tobytes() | 
					
						
							|  |  |  |         if major == 2 and isinstance(data, buffer): | 
					
						
							| 
									
										
										
										
											2014-01-24 15:13:20 +01:00
										 |  |  |             data = ''.join([c for c in data]) | 
					
						
							|  |  |  |         return data | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-24 17:41:07 +01:00
										 |  |  |     def toString(self): | 
					
						
							|  |  |  |         data = self.toBytes() | 
					
						
							|  |  |  |         return data if sys.version_info[0] == 2 else data.decode("utf8") | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-24 15:13:20 +01:00
										 |  |  |     def extractByte(self, offset = 0): | 
					
						
							|  |  |  |         return struct.unpack_from("b", self.data, offset)[0] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def extractShort(self, offset = 0): | 
					
						
							|  |  |  |         return struct.unpack_from("h", self.data, offset)[0] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def extractUShort(self, offset = 0): | 
					
						
							|  |  |  |         return struct.unpack_from("H", self.data, offset)[0] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def extractInt(self, offset = 0): | 
					
						
							|  |  |  |         return struct.unpack_from("i", self.data, offset)[0] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def extractUInt(self, offset = 0): | 
					
						
							|  |  |  |         return struct.unpack_from("I", self.data, offset)[0] | 
					
						
							| 
									
										
										
										
											2013-09-11 21:35:39 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-24 15:13:20 +01:00
										 |  |  |     def extractLong(self, offset = 0): | 
					
						
							|  |  |  |         return struct.unpack_from("l", self.data, offset)[0] | 
					
						
							| 
									
										
										
										
											2013-09-11 21:35:39 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-24 15:13:20 +01:00
										 |  |  |     # FIXME: Note these should take target architecture into account. | 
					
						
							|  |  |  |     def extractULong(self, offset = 0): | 
					
						
							|  |  |  |         return struct.unpack_from("L", self.data, offset)[0] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def extractInt64(self, offset = 0): | 
					
						
							|  |  |  |         return struct.unpack_from("q", self.data, offset)[0] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def extractUInt64(self, offset = 0): | 
					
						
							|  |  |  |         return struct.unpack_from("Q", self.data, offset)[0] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def extractDouble(self, offset = 0): | 
					
						
							|  |  |  |         return struct.unpack_from("d", self.data, offset)[0] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def extractFloat(self, offset = 0): | 
					
						
							|  |  |  |         return struct.unpack_from("f", self.data, offset)[0] | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-09-11 21:35:39 +02:00
										 |  |  | def warn(message): | 
					
						
							| 
									
										
										
										
											2015-10-08 16:19:57 +02:00
										 |  |  |     print('bridgemessage={msg="%s"},' % message.replace('"', '$').encode("latin1")) | 
					
						
							| 
									
										
										
										
											2013-09-11 21:35:39 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def showException(msg, exType, exValue, exTraceback): | 
					
						
							|  |  |  |     warn("**** CAUGHT EXCEPTION: %s ****" % msg) | 
					
						
							|  |  |  |     try: | 
					
						
							|  |  |  |         import traceback | 
					
						
							|  |  |  |         for line in traceback.format_exception(exType, exValue, exTraceback): | 
					
						
							|  |  |  |             warn("%s" % line) | 
					
						
							|  |  |  |     except: | 
					
						
							|  |  |  |         pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class Children: | 
					
						
							|  |  |  |     def __init__(self, d, numChild = 1, childType = None, childNumChild = None, | 
					
						
							|  |  |  |             maxNumChild = None, addrBase = None, addrStep = None): | 
					
						
							|  |  |  |         self.d = d | 
					
						
							|  |  |  |         self.numChild = numChild | 
					
						
							|  |  |  |         self.childNumChild = childNumChild | 
					
						
							|  |  |  |         self.maxNumChild = maxNumChild | 
					
						
							|  |  |  |         self.addrBase = addrBase | 
					
						
							|  |  |  |         self.addrStep = addrStep | 
					
						
							|  |  |  |         self.printsAddress = True | 
					
						
							|  |  |  |         if childType is None: | 
					
						
							|  |  |  |             self.childType = None | 
					
						
							|  |  |  |         else: | 
					
						
							| 
									
										
										
										
											2014-09-12 13:31:12 +02:00
										 |  |  |             self.childType = d.stripClassTag(str(childType)) | 
					
						
							| 
									
										
											  
											
												Debugger: Make dumpers somewhat work in command line GDB
With
    python sys.path.insert(1, '/data/dev/creator/share/qtcreator/debugger/')
    python from gdbbridge import *
in .gdbinit there's a new "GDB command", called "pp".
With code like
    int main(int argc, char *argv[])
    {
        QString ss = "Hello";
        QApplication app(argc, argv);
        app.setObjectName(ss);
        // break here
    }
the 'pp' command can be used as follows:
(gdb) pp app
app =
   [
      <Myns::QGuiApplication> = {"Hello"}
      staticMetaObject = <Myns::QMetaObject> = {""}
      [parent] = <Myns::QObject *> = {"0x0"}
      [children] = <Myns::QObjectList> = {"<3 items>"}
      [properties] = "<>0 items>"
      [methods] = "<6 items>"
      [signals] = "<1 items>"
   ],<Myns::QApplication> = {"Hello"}
(gdb) pp app [properties],[children]
app =
   [
      <Myns::QGuiApplication> = {"Hello"}
      staticMetaObject = <Myns::QMetaObject> = {""}
      [parent] = <Myns::QObject *> = {"0x0"}
      [children] = [
         <Myns::QObject> = {""}
         <Myns::QObject> = {""}
         <Myns::QObject> = {"fusion"}
      ],<Myns::QObjectList> = {"<3 items>"}
      [properties] = [
         windowIcon = <Myns::QVariant (QIcon)> = {""}
         cursorFlashTime = <Myns::QVariant (int)> = {"1000"}
         doubleClickInterval = <Myns::QVariant (int)> = {"400"}
         keyboardInputInterval = <Myns::QVariant (int)> = {"400"}
         wheelScrollLines = <Myns::QVariant (int)> = {"3"}
         globalStrut = <Myns::QVariant (QSize)> = {"(0, 0)"}
         startDragTime = <Myns::QVariant (int)> = {"500"}
         startDragDistance = <Myns::QVariant (int)> = {"10"}
         styleSheet = <Myns::QVariant (QString)> = {""}
         autoSipEnabled = <Myns::QVariant (bool)> = {"true"}
      ],"<10 items>"
      [methods] = "<6 items>"
      [signals] = "<1 items>"
   ],<Myns::QApplication> = {"Hello"}
(gdb) pp ss
ss =
   <Myns::QString> = {"Hello"}
Change-Id: I6e4714a5cfe34c38917500d114ad9a70d20cff39
Reviewed-by: Christian Stenger <christian.stenger@digia.com>
Reviewed-by: hjk <hjk121@nokiamail.com>
											
										 
											2014-06-13 17:45:34 +02:00
										 |  |  |             if not self.d.isCli: | 
					
						
							|  |  |  |                 self.d.put('childtype="%s",' % self.childType) | 
					
						
							| 
									
										
										
										
											2013-09-11 21:35:39 +02:00
										 |  |  |             if childNumChild is None: | 
					
						
							|  |  |  |                 pass | 
					
						
							|  |  |  |                 #if self.d.isSimpleType(childType): | 
					
						
							|  |  |  |                 #    self.d.put('childnumchild="0",') | 
					
						
							|  |  |  |                 #    self.childNumChild = 0 | 
					
						
							|  |  |  |                 #elif childType.code == PointerCode: | 
					
						
							|  |  |  |                 #    self.d.put('childnumchild="1",') | 
					
						
							|  |  |  |                 #    self.childNumChild = 1 | 
					
						
							|  |  |  |             else: | 
					
						
							|  |  |  |                 self.d.put('childnumchild="%s",' % childNumChild) | 
					
						
							|  |  |  |                 self.childNumChild = childNumChild | 
					
						
							| 
									
										
											  
											
												Debugger: Make dumpers somewhat work in command line GDB
With
    python sys.path.insert(1, '/data/dev/creator/share/qtcreator/debugger/')
    python from gdbbridge import *
in .gdbinit there's a new "GDB command", called "pp".
With code like
    int main(int argc, char *argv[])
    {
        QString ss = "Hello";
        QApplication app(argc, argv);
        app.setObjectName(ss);
        // break here
    }
the 'pp' command can be used as follows:
(gdb) pp app
app =
   [
      <Myns::QGuiApplication> = {"Hello"}
      staticMetaObject = <Myns::QMetaObject> = {""}
      [parent] = <Myns::QObject *> = {"0x0"}
      [children] = <Myns::QObjectList> = {"<3 items>"}
      [properties] = "<>0 items>"
      [methods] = "<6 items>"
      [signals] = "<1 items>"
   ],<Myns::QApplication> = {"Hello"}
(gdb) pp app [properties],[children]
app =
   [
      <Myns::QGuiApplication> = {"Hello"}
      staticMetaObject = <Myns::QMetaObject> = {""}
      [parent] = <Myns::QObject *> = {"0x0"}
      [children] = [
         <Myns::QObject> = {""}
         <Myns::QObject> = {""}
         <Myns::QObject> = {"fusion"}
      ],<Myns::QObjectList> = {"<3 items>"}
      [properties] = [
         windowIcon = <Myns::QVariant (QIcon)> = {""}
         cursorFlashTime = <Myns::QVariant (int)> = {"1000"}
         doubleClickInterval = <Myns::QVariant (int)> = {"400"}
         keyboardInputInterval = <Myns::QVariant (int)> = {"400"}
         wheelScrollLines = <Myns::QVariant (int)> = {"3"}
         globalStrut = <Myns::QVariant (QSize)> = {"(0, 0)"}
         startDragTime = <Myns::QVariant (int)> = {"500"}
         startDragDistance = <Myns::QVariant (int)> = {"10"}
         styleSheet = <Myns::QVariant (QString)> = {""}
         autoSipEnabled = <Myns::QVariant (bool)> = {"true"}
      ],"<10 items>"
      [methods] = "<6 items>"
      [signals] = "<1 items>"
   ],<Myns::QApplication> = {"Hello"}
(gdb) pp ss
ss =
   <Myns::QString> = {"Hello"}
Change-Id: I6e4714a5cfe34c38917500d114ad9a70d20cff39
Reviewed-by: Christian Stenger <christian.stenger@digia.com>
Reviewed-by: hjk <hjk121@nokiamail.com>
											
										 
											2014-06-13 17:45:34 +02:00
										 |  |  |         self.printsAddress = not self.d.putAddressRange(addrBase, addrStep) | 
					
						
							| 
									
										
										
										
											2013-09-11 21:35:39 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def __enter__(self): | 
					
						
							|  |  |  |         self.savedChildType = self.d.currentChildType | 
					
						
							|  |  |  |         self.savedChildNumChild = self.d.currentChildNumChild | 
					
						
							|  |  |  |         self.savedNumChild = self.d.currentNumChild | 
					
						
							|  |  |  |         self.savedMaxNumChild = self.d.currentMaxNumChild | 
					
						
							|  |  |  |         self.savedPrintsAddress = self.d.currentPrintsAddress | 
					
						
							|  |  |  |         self.d.currentChildType = self.childType | 
					
						
							|  |  |  |         self.d.currentChildNumChild = self.childNumChild | 
					
						
							|  |  |  |         self.d.currentNumChild = self.numChild | 
					
						
							|  |  |  |         self.d.currentMaxNumChild = self.maxNumChild | 
					
						
							|  |  |  |         self.d.currentPrintsAddress = self.printsAddress | 
					
						
							| 
									
										
											  
											
												Debugger: Make dumpers somewhat work in command line GDB
With
    python sys.path.insert(1, '/data/dev/creator/share/qtcreator/debugger/')
    python from gdbbridge import *
in .gdbinit there's a new "GDB command", called "pp".
With code like
    int main(int argc, char *argv[])
    {
        QString ss = "Hello";
        QApplication app(argc, argv);
        app.setObjectName(ss);
        // break here
    }
the 'pp' command can be used as follows:
(gdb) pp app
app =
   [
      <Myns::QGuiApplication> = {"Hello"}
      staticMetaObject = <Myns::QMetaObject> = {""}
      [parent] = <Myns::QObject *> = {"0x0"}
      [children] = <Myns::QObjectList> = {"<3 items>"}
      [properties] = "<>0 items>"
      [methods] = "<6 items>"
      [signals] = "<1 items>"
   ],<Myns::QApplication> = {"Hello"}
(gdb) pp app [properties],[children]
app =
   [
      <Myns::QGuiApplication> = {"Hello"}
      staticMetaObject = <Myns::QMetaObject> = {""}
      [parent] = <Myns::QObject *> = {"0x0"}
      [children] = [
         <Myns::QObject> = {""}
         <Myns::QObject> = {""}
         <Myns::QObject> = {"fusion"}
      ],<Myns::QObjectList> = {"<3 items>"}
      [properties] = [
         windowIcon = <Myns::QVariant (QIcon)> = {""}
         cursorFlashTime = <Myns::QVariant (int)> = {"1000"}
         doubleClickInterval = <Myns::QVariant (int)> = {"400"}
         keyboardInputInterval = <Myns::QVariant (int)> = {"400"}
         wheelScrollLines = <Myns::QVariant (int)> = {"3"}
         globalStrut = <Myns::QVariant (QSize)> = {"(0, 0)"}
         startDragTime = <Myns::QVariant (int)> = {"500"}
         startDragDistance = <Myns::QVariant (int)> = {"10"}
         styleSheet = <Myns::QVariant (QString)> = {""}
         autoSipEnabled = <Myns::QVariant (bool)> = {"true"}
      ],"<10 items>"
      [methods] = "<6 items>"
      [signals] = "<1 items>"
   ],<Myns::QApplication> = {"Hello"}
(gdb) pp ss
ss =
   <Myns::QString> = {"Hello"}
Change-Id: I6e4714a5cfe34c38917500d114ad9a70d20cff39
Reviewed-by: Christian Stenger <christian.stenger@digia.com>
Reviewed-by: hjk <hjk121@nokiamail.com>
											
										 
											2014-06-13 17:45:34 +02:00
										 |  |  |         self.d.put(self.d.childrenPrefix) | 
					
						
							| 
									
										
										
										
											2013-09-11 21:35:39 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def __exit__(self, exType, exValue, exTraceBack): | 
					
						
							|  |  |  |         if not exType is None: | 
					
						
							|  |  |  |             if self.d.passExceptions: | 
					
						
							|  |  |  |                 showException("CHILDREN", exType, exValue, exTraceBack) | 
					
						
							|  |  |  |             self.d.putNumChild(0) | 
					
						
							| 
									
										
										
										
											2015-12-11 13:28:21 +01:00
										 |  |  |             self.d.putSpecialValue("notaccessible") | 
					
						
							| 
									
										
										
										
											2013-09-11 21:35:39 +02:00
										 |  |  |         if not self.d.currentMaxNumChild is None: | 
					
						
							|  |  |  |             if self.d.currentMaxNumChild < self.d.currentNumChild: | 
					
						
							|  |  |  |                 self.d.put('{name="<incomplete>",value="",type="",numchild="0"},') | 
					
						
							|  |  |  |         self.d.currentChildType = self.savedChildType | 
					
						
							|  |  |  |         self.d.currentChildNumChild = self.savedChildNumChild | 
					
						
							|  |  |  |         self.d.currentNumChild = self.savedNumChild | 
					
						
							|  |  |  |         self.d.currentMaxNumChild = self.savedMaxNumChild | 
					
						
							|  |  |  |         self.d.currentPrintsAddress = self.savedPrintsAddress | 
					
						
							| 
									
										
											  
											
												Debugger: Make dumpers somewhat work in command line GDB
With
    python sys.path.insert(1, '/data/dev/creator/share/qtcreator/debugger/')
    python from gdbbridge import *
in .gdbinit there's a new "GDB command", called "pp".
With code like
    int main(int argc, char *argv[])
    {
        QString ss = "Hello";
        QApplication app(argc, argv);
        app.setObjectName(ss);
        // break here
    }
the 'pp' command can be used as follows:
(gdb) pp app
app =
   [
      <Myns::QGuiApplication> = {"Hello"}
      staticMetaObject = <Myns::QMetaObject> = {""}
      [parent] = <Myns::QObject *> = {"0x0"}
      [children] = <Myns::QObjectList> = {"<3 items>"}
      [properties] = "<>0 items>"
      [methods] = "<6 items>"
      [signals] = "<1 items>"
   ],<Myns::QApplication> = {"Hello"}
(gdb) pp app [properties],[children]
app =
   [
      <Myns::QGuiApplication> = {"Hello"}
      staticMetaObject = <Myns::QMetaObject> = {""}
      [parent] = <Myns::QObject *> = {"0x0"}
      [children] = [
         <Myns::QObject> = {""}
         <Myns::QObject> = {""}
         <Myns::QObject> = {"fusion"}
      ],<Myns::QObjectList> = {"<3 items>"}
      [properties] = [
         windowIcon = <Myns::QVariant (QIcon)> = {""}
         cursorFlashTime = <Myns::QVariant (int)> = {"1000"}
         doubleClickInterval = <Myns::QVariant (int)> = {"400"}
         keyboardInputInterval = <Myns::QVariant (int)> = {"400"}
         wheelScrollLines = <Myns::QVariant (int)> = {"3"}
         globalStrut = <Myns::QVariant (QSize)> = {"(0, 0)"}
         startDragTime = <Myns::QVariant (int)> = {"500"}
         startDragDistance = <Myns::QVariant (int)> = {"10"}
         styleSheet = <Myns::QVariant (QString)> = {""}
         autoSipEnabled = <Myns::QVariant (bool)> = {"true"}
      ],"<10 items>"
      [methods] = "<6 items>"
      [signals] = "<1 items>"
   ],<Myns::QApplication> = {"Hello"}
(gdb) pp ss
ss =
   <Myns::QString> = {"Hello"}
Change-Id: I6e4714a5cfe34c38917500d114ad9a70d20cff39
Reviewed-by: Christian Stenger <christian.stenger@digia.com>
Reviewed-by: hjk <hjk121@nokiamail.com>
											
										 
											2014-06-13 17:45:34 +02:00
										 |  |  |         self.d.putNewline() | 
					
						
							|  |  |  |         self.d.put(self.d.childrenSuffix) | 
					
						
							| 
									
										
										
										
											2013-09-11 21:35:39 +02:00
										 |  |  |         return True | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-13 18:23:22 +01:00
										 |  |  | class PairedChildrenData: | 
					
						
							| 
									
										
										
										
											2014-01-15 15:45:48 +01:00
										 |  |  |     def __init__(self, d, pairType, keyType, valueType, useKeyAndValue): | 
					
						
							|  |  |  |         self.useKeyAndValue = useKeyAndValue | 
					
						
							| 
									
										
										
										
											2014-01-13 18:23:22 +01:00
										 |  |  |         self.pairType = pairType | 
					
						
							| 
									
										
										
										
											2014-01-15 14:56:27 +01:00
										 |  |  |         self.keyType = keyType | 
					
						
							|  |  |  |         self.valueType = valueType | 
					
						
							| 
									
										
										
										
											2014-01-13 18:23:22 +01:00
										 |  |  |         self.isCompact = d.isMapCompact(self.keyType, self.valueType) | 
					
						
							| 
									
										
										
										
											2014-01-15 14:56:27 +01:00
										 |  |  |         self.childType = valueType if self.isCompact else pairType | 
					
						
							| 
									
										
										
										
											2014-01-13 18:23:22 +01:00
										 |  |  |         ns = d.qtNamespace() | 
					
						
							| 
									
										
										
										
											2014-09-12 13:31:12 +02:00
										 |  |  |         keyTypeName = d.stripClassTag(str(self.keyType)) | 
					
						
							|  |  |  |         self.keyIsQString = keyTypeName == ns + "QString" | 
					
						
							|  |  |  |         self.keyIsQByteArray = keyTypeName == ns + "QByteArray" | 
					
						
							|  |  |  |         self.keyIsStdString = keyTypeName == "std::string" \ | 
					
						
							|  |  |  |             or keyTypeName.startswith("std::basic_string<char") | 
					
						
							| 
									
										
										
										
											2014-01-13 18:23:22 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-14 18:24:55 +01:00
										 |  |  | class PairedChildren(Children): | 
					
						
							| 
									
										
										
										
											2014-01-15 15:45:48 +01:00
										 |  |  |     def __init__(self, d, numChild, useKeyAndValue = False, | 
					
						
							|  |  |  |             pairType = None, keyType = None, valueType = None, maxNumChild = None): | 
					
						
							| 
									
										
										
										
											2014-01-13 18:23:22 +01:00
										 |  |  |         self.d = d | 
					
						
							| 
									
										
										
										
											2014-01-15 14:56:27 +01:00
										 |  |  |         if keyType is None: | 
					
						
							|  |  |  |             keyType = d.templateArgument(pairType, 0).unqualified() | 
					
						
							|  |  |  |         if valueType is None: | 
					
						
							|  |  |  |             valueType = d.templateArgument(pairType, 1) | 
					
						
							| 
									
										
										
										
											2014-01-15 15:45:48 +01:00
										 |  |  |         d.pairData = PairedChildrenData(d, pairType, keyType, valueType, useKeyAndValue) | 
					
						
							| 
									
										
										
										
											2014-01-15 14:56:27 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-13 18:23:22 +01:00
										 |  |  |         Children.__init__(self, d, numChild, | 
					
						
							| 
									
										
										
										
											2014-01-15 14:56:27 +01:00
										 |  |  |             d.pairData.childType, | 
					
						
							|  |  |  |             maxNumChild = maxNumChild, | 
					
						
							|  |  |  |             addrBase = None, addrStep = None) | 
					
						
							| 
									
										
										
										
											2014-01-13 18:23:22 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def __enter__(self): | 
					
						
							|  |  |  |         self.savedPairData = self.d.pairData if hasattr(self.d, "pairData") else None | 
					
						
							|  |  |  |         Children.__enter__(self) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def __exit__(self, exType, exValue, exTraceBack): | 
					
						
							|  |  |  |         Children.__exit__(self, exType, exValue, exTraceBack) | 
					
						
							|  |  |  |         self.d.pairData = self.savedPairData if self.savedPairData else None | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-09-11 21:35:39 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | class SubItem: | 
					
						
							|  |  |  |     def __init__(self, d, component): | 
					
						
							|  |  |  |         self.d = d | 
					
						
							|  |  |  |         self.name = component | 
					
						
							|  |  |  |         self.iname = None | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def __enter__(self): | 
					
						
							|  |  |  |         self.d.enterSubItem(self) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def __exit__(self, exType, exValue, exTraceBack): | 
					
						
							|  |  |  |         return self.d.exitSubItem(self, exType, exValue, exTraceBack) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class NoAddress: | 
					
						
							|  |  |  |     def __init__(self, d): | 
					
						
							|  |  |  |         self.d = d | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def __enter__(self): | 
					
						
							|  |  |  |         self.savedPrintsAddress = self.d.currentPrintsAddress | 
					
						
							|  |  |  |         self.d.currentPrintsAddress = False | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def __exit__(self, exType, exValue, exTraceBack): | 
					
						
							|  |  |  |         self.d.currentPrintsAddress = self.savedPrintsAddress | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class TopLevelItem(SubItem): | 
					
						
							|  |  |  |     def __init__(self, d, iname): | 
					
						
							|  |  |  |         self.d = d | 
					
						
							|  |  |  |         self.iname = iname | 
					
						
							|  |  |  |         self.name = None | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class UnnamedSubItem(SubItem): | 
					
						
							|  |  |  |     def __init__(self, d, component): | 
					
						
							|  |  |  |         self.d = d | 
					
						
							|  |  |  |         self.iname = "%s.%s" % (self.d.currentIName, component) | 
					
						
							|  |  |  |         self.name = None | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class DumperBase: | 
					
						
							|  |  |  |     def __init__(self): | 
					
						
							|  |  |  |         self.isCdb = False | 
					
						
							|  |  |  |         self.isGdb = False | 
					
						
							|  |  |  |         self.isLldb = False | 
					
						
							| 
									
										
											  
											
												Debugger: Make dumpers somewhat work in command line GDB
With
    python sys.path.insert(1, '/data/dev/creator/share/qtcreator/debugger/')
    python from gdbbridge import *
in .gdbinit there's a new "GDB command", called "pp".
With code like
    int main(int argc, char *argv[])
    {
        QString ss = "Hello";
        QApplication app(argc, argv);
        app.setObjectName(ss);
        // break here
    }
the 'pp' command can be used as follows:
(gdb) pp app
app =
   [
      <Myns::QGuiApplication> = {"Hello"}
      staticMetaObject = <Myns::QMetaObject> = {""}
      [parent] = <Myns::QObject *> = {"0x0"}
      [children] = <Myns::QObjectList> = {"<3 items>"}
      [properties] = "<>0 items>"
      [methods] = "<6 items>"
      [signals] = "<1 items>"
   ],<Myns::QApplication> = {"Hello"}
(gdb) pp app [properties],[children]
app =
   [
      <Myns::QGuiApplication> = {"Hello"}
      staticMetaObject = <Myns::QMetaObject> = {""}
      [parent] = <Myns::QObject *> = {"0x0"}
      [children] = [
         <Myns::QObject> = {""}
         <Myns::QObject> = {""}
         <Myns::QObject> = {"fusion"}
      ],<Myns::QObjectList> = {"<3 items>"}
      [properties] = [
         windowIcon = <Myns::QVariant (QIcon)> = {""}
         cursorFlashTime = <Myns::QVariant (int)> = {"1000"}
         doubleClickInterval = <Myns::QVariant (int)> = {"400"}
         keyboardInputInterval = <Myns::QVariant (int)> = {"400"}
         wheelScrollLines = <Myns::QVariant (int)> = {"3"}
         globalStrut = <Myns::QVariant (QSize)> = {"(0, 0)"}
         startDragTime = <Myns::QVariant (int)> = {"500"}
         startDragDistance = <Myns::QVariant (int)> = {"10"}
         styleSheet = <Myns::QVariant (QString)> = {""}
         autoSipEnabled = <Myns::QVariant (bool)> = {"true"}
      ],"<10 items>"
      [methods] = "<6 items>"
      [signals] = "<1 items>"
   ],<Myns::QApplication> = {"Hello"}
(gdb) pp ss
ss =
   <Myns::QString> = {"Hello"}
Change-Id: I6e4714a5cfe34c38917500d114ad9a70d20cff39
Reviewed-by: Christian Stenger <christian.stenger@digia.com>
Reviewed-by: hjk <hjk121@nokiamail.com>
											
										 
											2014-06-13 17:45:34 +02:00
										 |  |  |         self.isCli = False | 
					
						
							| 
									
										
										
										
											2013-09-11 21:35:39 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-30 15:07:54 +01:00
										 |  |  |         # Later set, or not set: | 
					
						
							|  |  |  |         self.stringCutOff = 10000 | 
					
						
							| 
									
										
										
										
											2014-05-16 00:18:17 +02:00
										 |  |  |         self.displayStringLimit = 100 | 
					
						
							| 
									
										
										
										
											2013-10-30 15:07:54 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-07-10 10:09:25 +02:00
										 |  |  |         self.resetCaches() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.childrenPrefix = 'children=[' | 
					
						
							|  |  |  |         self.childrenSuffix = '],' | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.dumpermodules = [ | 
					
						
							|  |  |  |             "qttypes", | 
					
						
							|  |  |  |             "stdtypes", | 
					
						
							|  |  |  |             "misctypes", | 
					
						
							|  |  |  |             "boosttypes", | 
					
						
							|  |  |  |             "creatortypes", | 
					
						
							|  |  |  |             "personaltypes", | 
					
						
							|  |  |  |         ] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def resetCaches(self): | 
					
						
							| 
									
										
										
										
											2013-10-30 15:07:54 +01:00
										 |  |  |         # This is a cache mapping from 'type name' to 'display alternatives'. | 
					
						
							| 
									
										
										
										
											2015-07-10 10:09:25 +02:00
										 |  |  |         self.qqFormats = { "QVariant (QVariantMap)" : mapForms() } | 
					
						
							| 
									
										
										
										
											2013-10-30 15:07:54 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # This is a cache of all known dumpers. | 
					
						
							|  |  |  |         self.qqDumpers = {} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # This is a cache of all dumpers that support writing. | 
					
						
							|  |  |  |         self.qqEditable = {} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # This keeps canonical forms of the typenames, without array indices etc. | 
					
						
							|  |  |  |         self.cachedFormats = {} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-28 23:23:01 +01:00
										 |  |  |         # Maps type names to static metaobjects. If a type is known | 
					
						
							|  |  |  |         # to not be QObject derived, it contains a 0 value. | 
					
						
							|  |  |  |         self.knownStaticMetaObjects = {} | 
					
						
							| 
									
										
										
										
											2014-01-20 15:03:27 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-30 09:22:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
											  
											
												Debugger: Make dumpers somewhat work in command line GDB
With
    python sys.path.insert(1, '/data/dev/creator/share/qtcreator/debugger/')
    python from gdbbridge import *
in .gdbinit there's a new "GDB command", called "pp".
With code like
    int main(int argc, char *argv[])
    {
        QString ss = "Hello";
        QApplication app(argc, argv);
        app.setObjectName(ss);
        // break here
    }
the 'pp' command can be used as follows:
(gdb) pp app
app =
   [
      <Myns::QGuiApplication> = {"Hello"}
      staticMetaObject = <Myns::QMetaObject> = {""}
      [parent] = <Myns::QObject *> = {"0x0"}
      [children] = <Myns::QObjectList> = {"<3 items>"}
      [properties] = "<>0 items>"
      [methods] = "<6 items>"
      [signals] = "<1 items>"
   ],<Myns::QApplication> = {"Hello"}
(gdb) pp app [properties],[children]
app =
   [
      <Myns::QGuiApplication> = {"Hello"}
      staticMetaObject = <Myns::QMetaObject> = {""}
      [parent] = <Myns::QObject *> = {"0x0"}
      [children] = [
         <Myns::QObject> = {""}
         <Myns::QObject> = {""}
         <Myns::QObject> = {"fusion"}
      ],<Myns::QObjectList> = {"<3 items>"}
      [properties] = [
         windowIcon = <Myns::QVariant (QIcon)> = {""}
         cursorFlashTime = <Myns::QVariant (int)> = {"1000"}
         doubleClickInterval = <Myns::QVariant (int)> = {"400"}
         keyboardInputInterval = <Myns::QVariant (int)> = {"400"}
         wheelScrollLines = <Myns::QVariant (int)> = {"3"}
         globalStrut = <Myns::QVariant (QSize)> = {"(0, 0)"}
         startDragTime = <Myns::QVariant (int)> = {"500"}
         startDragDistance = <Myns::QVariant (int)> = {"10"}
         styleSheet = <Myns::QVariant (QString)> = {""}
         autoSipEnabled = <Myns::QVariant (bool)> = {"true"}
      ],"<10 items>"
      [methods] = "<6 items>"
      [signals] = "<1 items>"
   ],<Myns::QApplication> = {"Hello"}
(gdb) pp ss
ss =
   <Myns::QString> = {"Hello"}
Change-Id: I6e4714a5cfe34c38917500d114ad9a70d20cff39
Reviewed-by: Christian Stenger <christian.stenger@digia.com>
Reviewed-by: hjk <hjk121@nokiamail.com>
											
										 
											2014-06-13 17:45:34 +02:00
										 |  |  |     def putNewline(self): | 
					
						
							|  |  |  |         pass | 
					
						
							| 
									
										
										
										
											2013-10-30 15:07:54 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-09-12 13:31:12 +02:00
										 |  |  |     def stripClassTag(self, typeName): | 
					
						
							|  |  |  |         if typeName.startswith("class "): | 
					
						
							|  |  |  |             return typeName[6:] | 
					
						
							|  |  |  |         if typeName.startswith("struct "): | 
					
						
							|  |  |  |             return typeName[7:] | 
					
						
							|  |  |  |         if typeName.startswith("const "): | 
					
						
							|  |  |  |             return typeName[6:] | 
					
						
							|  |  |  |         if typeName.startswith("volatile "): | 
					
						
							|  |  |  |             return typeName[9:] | 
					
						
							|  |  |  |         return typeName | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-30 15:07:54 +01:00
										 |  |  |     def stripForFormat(self, typeName): | 
					
						
							|  |  |  |         if typeName in self.cachedFormats: | 
					
						
							|  |  |  |             return self.cachedFormats[typeName] | 
					
						
							|  |  |  |         stripped = "" | 
					
						
							|  |  |  |         inArray = 0 | 
					
						
							| 
									
										
										
										
											2014-09-12 13:31:12 +02:00
										 |  |  |         for c in self.stripClassTag(typeName): | 
					
						
							| 
									
										
										
										
											2013-10-30 15:07:54 +01:00
										 |  |  |             if c == '<': | 
					
						
							|  |  |  |                 break | 
					
						
							|  |  |  |             if c == ' ': | 
					
						
							|  |  |  |                 continue | 
					
						
							|  |  |  |             if c == '[': | 
					
						
							|  |  |  |                 inArray += 1 | 
					
						
							|  |  |  |             elif c == ']': | 
					
						
							|  |  |  |                 inArray -= 1 | 
					
						
							|  |  |  |             if inArray and ord(c) >= 48 and ord(c) <= 57: | 
					
						
							|  |  |  |                 continue | 
					
						
							|  |  |  |             stripped +=  c | 
					
						
							|  |  |  |         self.cachedFormats[typeName] = stripped | 
					
						
							|  |  |  |         return stripped | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-24 15:13:20 +01:00
										 |  |  |     # Hex decoding operating on str, return str. | 
					
						
							| 
									
										
										
										
											2014-01-23 15:30:51 +01:00
										 |  |  |     def hexdecode(self, s): | 
					
						
							|  |  |  |         if sys.version_info[0] == 2: | 
					
						
							|  |  |  |             return s.decode("hex") | 
					
						
							|  |  |  |         return bytes.fromhex(s).decode("utf8") | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-07-07 17:20:02 +02:00
										 |  |  |     # Hex encoding operating on str or bytes, return str. | 
					
						
							| 
									
										
										
										
											2014-01-23 15:30:51 +01:00
										 |  |  |     def hexencode(self, s): | 
					
						
							|  |  |  |         if sys.version_info[0] == 2: | 
					
						
							|  |  |  |             return s.encode("hex") | 
					
						
							| 
									
										
										
										
											2014-01-24 15:13:20 +01:00
										 |  |  |         if isinstance(s, str): | 
					
						
							|  |  |  |             s = s.encode("utf8") | 
					
						
							|  |  |  |         return base64.b16encode(s).decode("utf8") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     #def toBlob(self, value): | 
					
						
							| 
									
										
										
										
											2014-01-24 17:02:23 +01:00
										 |  |  |     #    """Abstract""" | 
					
						
							| 
									
										
										
										
											2014-01-23 15:30:51 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-27 10:47:46 +01:00
										 |  |  |     def is32bit(self): | 
					
						
							|  |  |  |         return self.ptrSize() == 4 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-03-17 17:48:46 +01:00
										 |  |  |     def is64bit(self): | 
					
						
							|  |  |  |         return self.ptrSize() == 8 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-11-11 09:54:54 +01:00
										 |  |  |     def isQt3Support(self): | 
					
						
							|  |  |  |         # assume no Qt 3 support by default | 
					
						
							|  |  |  |         return False | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-12 08:19:06 +01:00
										 |  |  |     def lookupQtType(self, typeName): | 
					
						
							|  |  |  |         return self.lookupType(self.qtNamespace() + typeName) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-16 00:18:17 +02:00
										 |  |  |     # Clamps size to limit. | 
					
						
							| 
									
										
										
										
											2013-09-11 21:35:39 +02:00
										 |  |  |     def computeLimit(self, size, limit): | 
					
						
							| 
									
										
										
										
											2014-05-19 10:55:33 +02:00
										 |  |  |         if limit == 0: | 
					
						
							|  |  |  |             limit = self.displayStringLimit | 
					
						
							| 
									
										
										
										
											2014-05-16 00:18:17 +02:00
										 |  |  |         if limit is None or size <= limit: | 
					
						
							|  |  |  |             return 0, size | 
					
						
							|  |  |  |         return size, limit | 
					
						
							| 
									
										
										
										
											2013-09-11 21:35:39 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-03 22:08:35 +02:00
										 |  |  |     def vectorDataHelper(self, addr): | 
					
						
							|  |  |  |         if self.qtVersion() >= 0x050000: | 
					
						
							|  |  |  |             size = self.extractInt(addr + 4) | 
					
						
							|  |  |  |             alloc = self.extractInt(addr + 8) & 0x7ffffff | 
					
						
							|  |  |  |             data = addr + self.extractPointer(addr + 8 + self.ptrSize()) | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             alloc = self.extractInt(addr + 4) | 
					
						
							|  |  |  |             size = self.extractInt(addr + 8) | 
					
						
							|  |  |  |             data = addr + 16 | 
					
						
							|  |  |  |         return data, size, alloc | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-09-11 21:35:39 +02:00
										 |  |  |     def byteArrayDataHelper(self, addr): | 
					
						
							|  |  |  |         if self.qtVersion() >= 0x050000: | 
					
						
							|  |  |  |             # QTypedArray: | 
					
						
							|  |  |  |             # - QtPrivate::RefCount ref | 
					
						
							|  |  |  |             # - int size | 
					
						
							|  |  |  |             # - uint alloc : 31, capacityReserved : 1 | 
					
						
							|  |  |  |             # - qptrdiff offset | 
					
						
							|  |  |  |             size = self.extractInt(addr + 4) | 
					
						
							|  |  |  |             alloc = self.extractInt(addr + 8) & 0x7ffffff | 
					
						
							| 
									
										
										
										
											2014-01-28 13:20:05 +01:00
										 |  |  |             data = addr + self.extractPointer(addr + 8 + self.ptrSize()) | 
					
						
							| 
									
										
										
										
											2013-09-26 23:38:17 +02:00
										 |  |  |             if self.ptrSize() == 4: | 
					
						
							|  |  |  |                 data = data & 0xffffffff | 
					
						
							|  |  |  |             else: | 
					
						
							|  |  |  |                 data = data & 0xffffffffffffffff | 
					
						
							| 
									
										
										
										
											2014-10-10 12:05:47 +02:00
										 |  |  |         elif self.qtVersion() >= 0x040000: | 
					
						
							| 
									
										
										
										
											2013-09-11 21:35:39 +02:00
										 |  |  |             # Data: | 
					
						
							|  |  |  |             # - QBasicAtomicInt ref; | 
					
						
							|  |  |  |             # - int alloc, size; | 
					
						
							|  |  |  |             # - [padding] | 
					
						
							|  |  |  |             # - char *data; | 
					
						
							|  |  |  |             alloc = self.extractInt(addr + 4) | 
					
						
							|  |  |  |             size = self.extractInt(addr + 8) | 
					
						
							| 
									
										
										
										
											2014-01-28 13:20:05 +01:00
										 |  |  |             data = self.extractPointer(addr + 8 + self.ptrSize()) | 
					
						
							| 
									
										
										
										
											2014-10-10 12:05:47 +02:00
										 |  |  |         else: | 
					
						
							|  |  |  |             # Data: | 
					
						
							|  |  |  |             # - QShared count; | 
					
						
							|  |  |  |             # - QChar *unicode | 
					
						
							|  |  |  |             # - char *ascii | 
					
						
							|  |  |  |             # - uint len: 30 | 
					
						
							|  |  |  |             size = self.extractInt(addr + 3 * self.ptrSize()) & 0x3ffffff | 
					
						
							|  |  |  |             alloc = size  # pretend. | 
					
						
							|  |  |  |             data = self.extractPointer(addr + self.ptrSize()) | 
					
						
							| 
									
										
										
										
											2013-09-11 21:35:39 +02:00
										 |  |  |         return data, size, alloc | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # addr is the begin of a QByteArrayData structure | 
					
						
							| 
									
										
										
										
											2014-05-16 00:18:17 +02:00
										 |  |  |     def encodeStringHelper(self, addr, limit): | 
					
						
							| 
									
										
										
										
											2013-09-11 21:35:39 +02:00
										 |  |  |         # Should not happen, but we get it with LLDB as result | 
					
						
							|  |  |  |         # of inferior calls | 
					
						
							|  |  |  |         if addr == 0: | 
					
						
							| 
									
										
										
										
											2014-05-16 00:18:17 +02:00
										 |  |  |             return 0, "" | 
					
						
							| 
									
										
										
										
											2013-09-11 21:35:39 +02:00
										 |  |  |         data, size, alloc = self.byteArrayDataHelper(addr) | 
					
						
							|  |  |  |         if alloc != 0: | 
					
						
							|  |  |  |             self.check(0 <= size and size <= alloc and alloc <= 100*1000*1000) | 
					
						
							| 
									
										
										
										
											2014-05-16 00:18:17 +02:00
										 |  |  |         elided, shown = self.computeLimit(size, limit) | 
					
						
							|  |  |  |         return elided, self.readMemory(data, 2 * shown) | 
					
						
							| 
									
										
										
										
											2013-09-11 21:35:39 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-16 00:18:17 +02:00
										 |  |  |     def encodeByteArrayHelper(self, addr, limit): | 
					
						
							| 
									
										
										
										
											2013-09-11 21:35:39 +02:00
										 |  |  |         data, size, alloc = self.byteArrayDataHelper(addr) | 
					
						
							|  |  |  |         if alloc != 0: | 
					
						
							|  |  |  |             self.check(0 <= size and size <= alloc and alloc <= 100*1000*1000) | 
					
						
							| 
									
										
										
										
											2014-05-16 00:18:17 +02:00
										 |  |  |         elided, shown = self.computeLimit(size, limit) | 
					
						
							|  |  |  |         return elided, self.readMemory(data, shown) | 
					
						
							| 
									
										
										
										
											2013-09-11 21:35:39 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-05 15:10:20 +01:00
										 |  |  |     def putCharArrayHelper(self, data, size, charSize, | 
					
						
							|  |  |  |                            displayFormat = AutomaticFormat, | 
					
						
							|  |  |  |                            makeExpandable = True): | 
					
						
							| 
									
										
										
										
											2015-01-14 15:00:09 +01:00
										 |  |  |         bytelen = size * charSize | 
					
						
							|  |  |  |         elided, shown = self.computeLimit(bytelen, self.displayStringLimit) | 
					
						
							|  |  |  |         mem = self.readMemory(data, shown) | 
					
						
							|  |  |  |         if charSize == 1: | 
					
						
							| 
									
										
										
										
											2015-03-20 16:03:59 +01:00
										 |  |  |             if displayFormat == Latin1StringFormat \ | 
					
						
							|  |  |  |                     or displayFormat == SeparateLatin1StringFormat: | 
					
						
							| 
									
										
										
										
											2015-12-11 13:28:21 +01:00
										 |  |  |                 encodingType = "latin1" | 
					
						
							| 
									
										
										
										
											2015-03-18 10:09:44 +01:00
										 |  |  |             else: | 
					
						
							| 
									
										
										
										
											2015-12-11 13:28:21 +01:00
										 |  |  |                 encodingType = "utf8" | 
					
						
							|  |  |  |             childType = "char" | 
					
						
							| 
									
										
										
										
											2015-01-14 15:00:09 +01:00
										 |  |  |             displayType = DisplayLatin1String | 
					
						
							|  |  |  |         elif charSize == 2: | 
					
						
							| 
									
										
										
										
											2015-12-11 13:28:21 +01:00
										 |  |  |             encodingType = "utf16" | 
					
						
							|  |  |  |             childType = "short" | 
					
						
							| 
									
										
										
										
											2015-01-14 15:00:09 +01:00
										 |  |  |             displayType = DisplayUtf16String | 
					
						
							|  |  |  |         else: | 
					
						
							| 
									
										
										
										
											2015-12-11 13:28:21 +01:00
										 |  |  |             encodingType = "ucs4" | 
					
						
							|  |  |  |             childType = "int" | 
					
						
							| 
									
										
										
										
											2015-01-14 15:00:09 +01:00
										 |  |  |             displayType = DisplayUtf16String | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.putValue(mem, encodingType, elided=elided) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-04-01 17:19:43 +02:00
										 |  |  |         if displayFormat == SeparateLatin1StringFormat \ | 
					
						
							| 
									
										
										
										
											2015-03-20 16:03:59 +01:00
										 |  |  |                 or displayFormat == SeparateUtf8StringFormat: | 
					
						
							| 
									
										
										
										
											2015-01-14 15:00:09 +01:00
										 |  |  |             self.putField("editformat", displayType) | 
					
						
							|  |  |  |             elided, shown = self.computeLimit(bytelen, 100000) | 
					
						
							|  |  |  |             self.putField("editvalue", self.readMemory(data, shown)) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-05 15:10:20 +01:00
										 |  |  |         if makeExpandable: | 
					
						
							|  |  |  |             self.putNumChild(size) | 
					
						
							|  |  |  |             if self.isExpanded(): | 
					
						
							|  |  |  |                 with Children(self): | 
					
						
							|  |  |  |                     for i in range(size): | 
					
						
							|  |  |  |                         self.putSubItem(size, data[i]) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-23 15:30:51 +01:00
										 |  |  |     def readMemory(self, addr, size): | 
					
						
							| 
									
										
										
										
											2014-01-24 15:13:20 +01:00
										 |  |  |         data = self.extractBlob(addr, size).toBytes() | 
					
						
							|  |  |  |         return self.hexencode(data) | 
					
						
							| 
									
										
										
										
											2014-01-23 15:30:51 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-16 00:18:17 +02:00
										 |  |  |     def encodeByteArray(self, value, limit = 0): | 
					
						
							| 
									
										
										
										
											2014-05-16 00:18:17 +02:00
										 |  |  |         elided, data = self.encodeByteArrayHelper(self.extractPointer(value), limit) | 
					
						
							|  |  |  |         return data | 
					
						
							| 
									
										
										
										
											2013-09-11 21:35:39 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def byteArrayData(self, value): | 
					
						
							| 
									
										
										
										
											2014-01-28 13:20:05 +01:00
										 |  |  |         return self.byteArrayDataHelper(self.extractPointer(value)) | 
					
						
							| 
									
										
										
										
											2013-09-11 21:35:39 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-19 10:55:33 +02:00
										 |  |  |     def putByteArrayValue(self, value): | 
					
						
							|  |  |  |         elided, data = self.encodeByteArrayHelper(self.extractPointer(value), self.displayStringLimit) | 
					
						
							| 
									
										
										
										
											2015-12-11 13:28:21 +01:00
										 |  |  |         self.putValue(data, "latin1", elided=elided) | 
					
						
							| 
									
										
										
										
											2013-09-11 21:35:39 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-16 00:18:17 +02:00
										 |  |  |     def encodeString(self, value, limit = 0): | 
					
						
							| 
									
										
										
										
											2014-05-16 00:18:17 +02:00
										 |  |  |         elided, data = self.encodeStringHelper(self.extractPointer(value), limit) | 
					
						
							|  |  |  |         return data | 
					
						
							| 
									
										
										
										
											2013-09-11 21:35:39 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-12 08:19:06 +01:00
										 |  |  |     def encodedUtf16ToUtf8(self, s): | 
					
						
							|  |  |  |         return ''.join([chr(int(s[i:i+2], 16)) for i in range(0, len(s), 4)]) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def encodeStringUtf8(self, value, limit = 0): | 
					
						
							|  |  |  |         return self.encodedUtf16ToUtf8(self.encodeString(value, limit)) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-09-11 21:35:39 +02:00
										 |  |  |     def stringData(self, value): | 
					
						
							| 
									
										
										
										
											2014-01-28 13:20:05 +01:00
										 |  |  |         return self.byteArrayDataHelper(self.extractPointer(value)) | 
					
						
							| 
									
										
										
										
											2013-09-11 21:35:39 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-09-12 13:31:12 +02:00
										 |  |  |     def encodeStdString(self, value, limit = 0): | 
					
						
							|  |  |  |         data = value["_M_dataplus"]["_M_p"] | 
					
						
							|  |  |  |         sizePtr = data.cast(self.sizetType().pointer()) | 
					
						
							|  |  |  |         size = int(sizePtr[-3]) | 
					
						
							|  |  |  |         alloc = int(sizePtr[-2]) | 
					
						
							|  |  |  |         self.check(0 <= size and size <= alloc and alloc <= 100*1000*1000) | 
					
						
							|  |  |  |         elided, shown = self.computeLimit(size, limit) | 
					
						
							|  |  |  |         return self.readMemory(data, shown) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-28 11:35:45 +01:00
										 |  |  |     def extractTemplateArgument(self, typename, position): | 
					
						
							|  |  |  |         level = 0 | 
					
						
							|  |  |  |         skipSpace = False | 
					
						
							|  |  |  |         inner = '' | 
					
						
							|  |  |  |         for c in typename[typename.find('<') + 1 : -1]: | 
					
						
							|  |  |  |             if c == '<': | 
					
						
							|  |  |  |                 inner += c | 
					
						
							|  |  |  |                 level += 1 | 
					
						
							|  |  |  |             elif c == '>': | 
					
						
							|  |  |  |                 level -= 1 | 
					
						
							|  |  |  |                 inner += c | 
					
						
							|  |  |  |             elif c == ',': | 
					
						
							|  |  |  |                 if level == 0: | 
					
						
							|  |  |  |                     if position == 0: | 
					
						
							|  |  |  |                         return inner.strip() | 
					
						
							|  |  |  |                     position -= 1 | 
					
						
							|  |  |  |                     inner = '' | 
					
						
							|  |  |  |                 else: | 
					
						
							|  |  |  |                     inner += c | 
					
						
							|  |  |  |                     skipSpace = True | 
					
						
							|  |  |  |             else: | 
					
						
							|  |  |  |                 if skipSpace and c == ' ': | 
					
						
							|  |  |  |                     pass | 
					
						
							|  |  |  |                 else: | 
					
						
							|  |  |  |                     inner += c | 
					
						
							|  |  |  |                     skipSpace = False | 
					
						
							| 
									
										
										
										
											2015-12-08 14:27:42 +01:00
										 |  |  |         # Handle local struct definitions like QList<main(int, char**)::SomeStruct> | 
					
						
							|  |  |  |         inner = inner.strip() | 
					
						
							|  |  |  |         p = inner.find(')::') | 
					
						
							|  |  |  |         if p > -1: | 
					
						
							|  |  |  |             inner = inner[p+3:] | 
					
						
							|  |  |  |         return inner | 
					
						
							| 
									
										
										
										
											2013-10-28 11:35:45 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-19 10:55:33 +02:00
										 |  |  |     def putStringValueByAddress(self, addr): | 
					
						
							|  |  |  |         elided, data = self.encodeStringHelper(addr, self.displayStringLimit) | 
					
						
							| 
									
										
										
										
											2015-12-11 13:28:21 +01:00
										 |  |  |         self.putValue(data, "utf16", elided=elided) | 
					
						
							| 
									
										
										
										
											2014-05-19 10:55:33 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-09-11 21:35:39 +02:00
										 |  |  |     def putStringValue(self, value): | 
					
						
							| 
									
										
										
										
											2014-12-02 10:16:41 +01:00
										 |  |  |         elided, data = self.encodeStringHelper( | 
					
						
							|  |  |  |             self.extractPointer(value), | 
					
						
							|  |  |  |             self.displayStringLimit) | 
					
						
							| 
									
										
										
										
											2015-12-11 13:28:21 +01:00
										 |  |  |         self.putValue(data, "utf16", elided=elided) | 
					
						
							| 
									
										
										
										
											2013-09-11 21:35:39 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-11-01 12:49:14 +01:00
										 |  |  |     def putAddressItem(self, name, value, type = ""): | 
					
						
							|  |  |  |         with SubItem(self, name): | 
					
						
							|  |  |  |             self.putValue("0x%x" % value) | 
					
						
							|  |  |  |             self.putType(type) | 
					
						
							|  |  |  |             self.putNumChild(0) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def putIntItem(self, name, value): | 
					
						
							|  |  |  |         with SubItem(self, name): | 
					
						
							|  |  |  |             self.putValue(value) | 
					
						
							|  |  |  |             self.putType("int") | 
					
						
							|  |  |  |             self.putNumChild(0) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def putBoolItem(self, name, value): | 
					
						
							|  |  |  |         with SubItem(self, name): | 
					
						
							|  |  |  |             self.putValue(value) | 
					
						
							|  |  |  |             self.putType("bool") | 
					
						
							|  |  |  |             self.putNumChild(0) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def putGenericItem(self, name, type, value, encoding = None): | 
					
						
							|  |  |  |         with SubItem(self, name): | 
					
						
							|  |  |  |             self.putValue(value, encoding) | 
					
						
							|  |  |  |             self.putType(type) | 
					
						
							|  |  |  |             self.putNumChild(0) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-03 11:23:31 +02:00
										 |  |  |     def putCallItem(self, name, value, func, *args): | 
					
						
							|  |  |  |         try: | 
					
						
							|  |  |  |             result = self.callHelper(value, func, args) | 
					
						
							|  |  |  |             with SubItem(self, name): | 
					
						
							|  |  |  |                 self.putItem(result) | 
					
						
							|  |  |  |         except: | 
					
						
							|  |  |  |             with SubItem(self, name): | 
					
						
							| 
									
										
										
										
											2015-12-11 13:28:21 +01:00
										 |  |  |                 self.putSpecialValue("notcallable"); | 
					
						
							| 
									
										
										
										
											2014-04-03 11:23:31 +02:00
										 |  |  |                 self.putNumChild(0) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def call(self, value, func, *args): | 
					
						
							|  |  |  |         return self.callHelper(value, func, args) | 
					
						
							| 
									
										
										
										
											2013-11-01 12:49:14 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
											  
											
												Debugger: Make dumpers somewhat work in command line GDB
With
    python sys.path.insert(1, '/data/dev/creator/share/qtcreator/debugger/')
    python from gdbbridge import *
in .gdbinit there's a new "GDB command", called "pp".
With code like
    int main(int argc, char *argv[])
    {
        QString ss = "Hello";
        QApplication app(argc, argv);
        app.setObjectName(ss);
        // break here
    }
the 'pp' command can be used as follows:
(gdb) pp app
app =
   [
      <Myns::QGuiApplication> = {"Hello"}
      staticMetaObject = <Myns::QMetaObject> = {""}
      [parent] = <Myns::QObject *> = {"0x0"}
      [children] = <Myns::QObjectList> = {"<3 items>"}
      [properties] = "<>0 items>"
      [methods] = "<6 items>"
      [signals] = "<1 items>"
   ],<Myns::QApplication> = {"Hello"}
(gdb) pp app [properties],[children]
app =
   [
      <Myns::QGuiApplication> = {"Hello"}
      staticMetaObject = <Myns::QMetaObject> = {""}
      [parent] = <Myns::QObject *> = {"0x0"}
      [children] = [
         <Myns::QObject> = {""}
         <Myns::QObject> = {""}
         <Myns::QObject> = {"fusion"}
      ],<Myns::QObjectList> = {"<3 items>"}
      [properties] = [
         windowIcon = <Myns::QVariant (QIcon)> = {""}
         cursorFlashTime = <Myns::QVariant (int)> = {"1000"}
         doubleClickInterval = <Myns::QVariant (int)> = {"400"}
         keyboardInputInterval = <Myns::QVariant (int)> = {"400"}
         wheelScrollLines = <Myns::QVariant (int)> = {"3"}
         globalStrut = <Myns::QVariant (QSize)> = {"(0, 0)"}
         startDragTime = <Myns::QVariant (int)> = {"500"}
         startDragDistance = <Myns::QVariant (int)> = {"10"}
         styleSheet = <Myns::QVariant (QString)> = {""}
         autoSipEnabled = <Myns::QVariant (bool)> = {"true"}
      ],"<10 items>"
      [methods] = "<6 items>"
      [signals] = "<1 items>"
   ],<Myns::QApplication> = {"Hello"}
(gdb) pp ss
ss =
   <Myns::QString> = {"Hello"}
Change-Id: I6e4714a5cfe34c38917500d114ad9a70d20cff39
Reviewed-by: Christian Stenger <christian.stenger@digia.com>
Reviewed-by: hjk <hjk121@nokiamail.com>
											
										 
											2014-06-13 17:45:34 +02:00
										 |  |  |     def putAddressRange(self, base, step): | 
					
						
							|  |  |  |         try: | 
					
						
							|  |  |  |             if not addrBase is None and not step is None: | 
					
						
							|  |  |  |                 self.put('addrbase="0x%x",' % toInteger(base)) | 
					
						
							|  |  |  |                 self.put('addrstep="0x%x",' % toInteger(step)) | 
					
						
							|  |  |  |                 return True | 
					
						
							|  |  |  |         except: | 
					
						
							| 
									
										
										
										
											2014-06-16 17:34:06 +02:00
										 |  |  |             #warn("ADDRBASE: %s" % base) | 
					
						
							|  |  |  |             #warn("ADDRSTEP: %s" % step) | 
					
						
							| 
									
										
										
										
											2014-06-17 08:54:22 +02:00
										 |  |  |             pass | 
					
						
							| 
									
										
											  
											
												Debugger: Make dumpers somewhat work in command line GDB
With
    python sys.path.insert(1, '/data/dev/creator/share/qtcreator/debugger/')
    python from gdbbridge import *
in .gdbinit there's a new "GDB command", called "pp".
With code like
    int main(int argc, char *argv[])
    {
        QString ss = "Hello";
        QApplication app(argc, argv);
        app.setObjectName(ss);
        // break here
    }
the 'pp' command can be used as follows:
(gdb) pp app
app =
   [
      <Myns::QGuiApplication> = {"Hello"}
      staticMetaObject = <Myns::QMetaObject> = {""}
      [parent] = <Myns::QObject *> = {"0x0"}
      [children] = <Myns::QObjectList> = {"<3 items>"}
      [properties] = "<>0 items>"
      [methods] = "<6 items>"
      [signals] = "<1 items>"
   ],<Myns::QApplication> = {"Hello"}
(gdb) pp app [properties],[children]
app =
   [
      <Myns::QGuiApplication> = {"Hello"}
      staticMetaObject = <Myns::QMetaObject> = {""}
      [parent] = <Myns::QObject *> = {"0x0"}
      [children] = [
         <Myns::QObject> = {""}
         <Myns::QObject> = {""}
         <Myns::QObject> = {"fusion"}
      ],<Myns::QObjectList> = {"<3 items>"}
      [properties] = [
         windowIcon = <Myns::QVariant (QIcon)> = {""}
         cursorFlashTime = <Myns::QVariant (int)> = {"1000"}
         doubleClickInterval = <Myns::QVariant (int)> = {"400"}
         keyboardInputInterval = <Myns::QVariant (int)> = {"400"}
         wheelScrollLines = <Myns::QVariant (int)> = {"3"}
         globalStrut = <Myns::QVariant (QSize)> = {"(0, 0)"}
         startDragTime = <Myns::QVariant (int)> = {"500"}
         startDragDistance = <Myns::QVariant (int)> = {"10"}
         styleSheet = <Myns::QVariant (QString)> = {""}
         autoSipEnabled = <Myns::QVariant (bool)> = {"true"}
      ],"<10 items>"
      [methods] = "<6 items>"
      [signals] = "<1 items>"
   ],<Myns::QApplication> = {"Hello"}
(gdb) pp ss
ss =
   <Myns::QString> = {"Hello"}
Change-Id: I6e4714a5cfe34c38917500d114ad9a70d20cff39
Reviewed-by: Christian Stenger <christian.stenger@digia.com>
Reviewed-by: hjk <hjk121@nokiamail.com>
											
										 
											2014-06-13 17:45:34 +02:00
										 |  |  |         return False | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-09-12 13:31:12 +02:00
										 |  |  |     def putMapName(self, value, index = None): | 
					
						
							| 
									
										
										
										
											2013-10-30 15:07:54 +01:00
										 |  |  |         ns = self.qtNamespace() | 
					
						
							| 
									
										
										
										
											2014-09-12 13:31:12 +02:00
										 |  |  |         typeName = self.stripClassTag(str(value.type)) | 
					
						
							|  |  |  |         if typeName == ns + "QString": | 
					
						
							| 
									
										
										
										
											2015-12-11 13:28:21 +01:00
										 |  |  |             self.put('keyencoded="utf16:2:0",key="%s",' % self.encodeString(value)) | 
					
						
							| 
									
										
										
										
											2014-09-12 13:31:12 +02:00
										 |  |  |         elif typeName == ns + "QByteArray": | 
					
						
							| 
									
										
										
										
											2015-12-11 13:28:21 +01:00
										 |  |  |             self.put('keyencoded="latin1:1:0",key="%s",' % self.encodeByteArray(value)) | 
					
						
							| 
									
										
										
										
											2014-09-12 13:31:12 +02:00
										 |  |  |         elif typeName == "std::string": | 
					
						
							| 
									
										
										
										
											2015-12-11 13:28:21 +01:00
										 |  |  |             self.put('keyencoded="latin1:1:0",key="%s",' % self.encodeStdString(value)) | 
					
						
							| 
									
										
										
										
											2013-09-11 21:35:39 +02:00
										 |  |  |         else: | 
					
						
							| 
									
										
										
										
											2014-01-13 15:32:01 +01:00
										 |  |  |             val = str(value.GetValue()) if self.isLldb else str(value) | 
					
						
							| 
									
										
										
										
											2014-09-12 13:31:12 +02:00
										 |  |  |             if index is None: | 
					
						
							|  |  |  |                 key = '%s' % val | 
					
						
							| 
									
										
										
										
											2013-09-11 21:35:39 +02:00
										 |  |  |             else: | 
					
						
							| 
									
										
										
										
											2014-09-12 13:31:12 +02:00
										 |  |  |                 key = '[%s] %s' % (index, val) | 
					
						
							| 
									
										
										
										
											2015-12-11 13:28:21 +01:00
										 |  |  |             self.put('keyencoded="utf8:1:0",key="%s",' % self.hexencode(key)) | 
					
						
							| 
									
										
										
										
											2013-09-11 21:35:39 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-09-12 13:31:12 +02:00
										 |  |  |     def putPair(self, pair, index = None): | 
					
						
							| 
									
										
										
										
											2014-01-15 15:45:48 +01:00
										 |  |  |         if self.pairData.useKeyAndValue: | 
					
						
							| 
									
										
										
										
											2014-01-15 14:56:27 +01:00
										 |  |  |             key = pair["key"] | 
					
						
							|  |  |  |             value = pair["value"] | 
					
						
							| 
									
										
										
										
											2014-01-15 15:45:48 +01:00
										 |  |  |         else: | 
					
						
							|  |  |  |             key = pair["first"] | 
					
						
							|  |  |  |             value = pair["second"] | 
					
						
							| 
									
										
										
										
											2014-01-13 18:23:22 +01:00
										 |  |  |         if self.pairData.isCompact: | 
					
						
							|  |  |  |             if self.pairData.keyIsQString: | 
					
						
							| 
									
										
										
										
											2015-12-11 13:28:21 +01:00
										 |  |  |                 self.put('keyencoded="utf16",key="%s",' % self.encodeString(key)) | 
					
						
							| 
									
										
										
										
											2014-01-13 18:23:22 +01:00
										 |  |  |             elif self.pairData.keyIsQByteArray: | 
					
						
							| 
									
										
										
										
											2015-12-11 13:28:21 +01:00
										 |  |  |                 self.put('keyencoded="latin1",key="%s",' % self.encodeByteArray(key)) | 
					
						
							| 
									
										
										
										
											2014-09-12 13:31:12 +02:00
										 |  |  |             elif self.pairData.keyIsStdString: | 
					
						
							| 
									
										
										
										
											2015-12-11 13:28:21 +01:00
										 |  |  |                 self.put('keyencoded="latin1",key="%s",' % self.encodeStdString(key)) | 
					
						
							| 
									
										
										
										
											2014-01-13 18:23:22 +01:00
										 |  |  |             else: | 
					
						
							|  |  |  |                 name = str(key.GetValue()) if self.isLldb else str(key) | 
					
						
							|  |  |  |                 if index == -1: | 
					
						
							|  |  |  |                     self.put('name="%s",' % name) | 
					
						
							|  |  |  |                 else: | 
					
						
							| 
									
										
										
										
											2014-09-12 13:31:12 +02:00
										 |  |  |                     self.put('key="[%s] %s",' % (index, name)) | 
					
						
							| 
									
										
										
										
											2014-01-13 18:23:22 +01:00
										 |  |  |             self.putItem(value) | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             self.putEmptyValue() | 
					
						
							| 
									
										
										
										
											2014-01-15 14:56:27 +01:00
										 |  |  |             self.putNumChild(2) | 
					
						
							|  |  |  |             self.putField("iname", self.currentIName) | 
					
						
							| 
									
										
										
										
											2014-01-13 18:23:22 +01:00
										 |  |  |             if self.isExpanded(): | 
					
						
							| 
									
										
										
										
											2014-01-15 14:56:27 +01:00
										 |  |  |                 with Children(self): | 
					
						
							| 
									
										
										
										
											2014-01-15 15:45:48 +01:00
										 |  |  |                     if self.pairData.useKeyAndValue: | 
					
						
							|  |  |  |                         self.putSubItem("key", key) | 
					
						
							|  |  |  |                         self.putSubItem("value", value) | 
					
						
							|  |  |  |                     else: | 
					
						
							|  |  |  |                         self.putSubItem("first", key) | 
					
						
							|  |  |  |                         self.putSubItem("second", value) | 
					
						
							| 
									
										
										
										
											2014-01-13 18:23:22 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-03-20 15:16:56 +01:00
										 |  |  |     def putPlainChildren(self, value, dumpBase = True): | 
					
						
							|  |  |  |         self.putEmptyValue(-99) | 
					
						
							|  |  |  |         self.putNumChild(1) | 
					
						
							|  |  |  |         if self.isExpanded(): | 
					
						
							|  |  |  |             with Children(self): | 
					
						
							|  |  |  |                 self.putFields(value, dumpBase) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-09-11 21:35:39 +02:00
										 |  |  |     def isMapCompact(self, keyType, valueType): | 
					
						
							| 
									
										
										
										
											2015-03-20 16:03:59 +01:00
										 |  |  |         if self.currentItemFormat() == CompactMapFormat: | 
					
						
							|  |  |  |             return True | 
					
						
							| 
									
										
										
										
											2013-09-11 21:35:39 +02:00
										 |  |  |         return self.isSimpleType(keyType) and self.isSimpleType(valueType) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def check(self, exp): | 
					
						
							|  |  |  |         if not exp: | 
					
						
							|  |  |  |             raise RuntimeError("Check failed") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def checkRef(self, ref): | 
					
						
							| 
									
										
										
										
											2015-11-05 16:47:29 +01:00
										 |  |  |         count = self.extractInt(ref.address) | 
					
						
							| 
									
										
										
										
											2013-09-11 21:35:39 +02:00
										 |  |  |         # Assume there aren't a million references to any object. | 
					
						
							| 
									
										
										
										
											2015-11-05 16:47:29 +01:00
										 |  |  |         self.check(count >= -1) | 
					
						
							| 
									
										
										
										
											2013-09-11 21:35:39 +02:00
										 |  |  |         self.check(count < 1000000) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-10 01:33:35 +02:00
										 |  |  |     def readToFirstZero(self, p, tsize, maximum): | 
					
						
							|  |  |  |         code = (None, "b", "H", None, "I")[tsize] | 
					
						
							|  |  |  |         base = toInteger(p) | 
					
						
							|  |  |  |         blob = self.extractBlob(base, maximum).toBytes() | 
					
						
							| 
									
										
										
										
											2015-08-10 11:50:18 +02:00
										 |  |  |         for i in xrange(0, maximum, tsize): | 
					
						
							| 
									
										
										
										
											2014-10-10 01:33:35 +02:00
										 |  |  |             t = struct.unpack_from(code, blob, i)[0] | 
					
						
							|  |  |  |             if t == 0: | 
					
						
							|  |  |  |                 return 0, i, self.hexencode(blob[:i]) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-16 00:18:17 +02:00
										 |  |  |         # Real end is unknown. | 
					
						
							| 
									
										
										
										
											2014-10-10 01:33:35 +02:00
										 |  |  |         return -1, maximum, self.hexencode(blob[:maximum]) | 
					
						
							| 
									
										
										
										
											2013-10-16 18:39:01 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-10 01:33:35 +02:00
										 |  |  |     def encodeCArray(self, p, tsize, limit): | 
					
						
							|  |  |  |         elided, shown, blob = self.readToFirstZero(p, tsize, limit) | 
					
						
							|  |  |  |         return elided, blob | 
					
						
							| 
									
										
										
										
											2013-10-16 18:39:01 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-11-01 12:49:14 +01:00
										 |  |  |     def putItemCount(self, count, maximum = 1000000000): | 
					
						
							|  |  |  |         # This needs to override the default value, so don't use 'put' directly. | 
					
						
							|  |  |  |         if count > maximum: | 
					
						
							| 
									
										
										
										
											2015-12-11 13:28:21 +01:00
										 |  |  |             self.putSpecialValue("minimumitemcount", maximum) | 
					
						
							| 
									
										
										
										
											2013-11-01 12:49:14 +01:00
										 |  |  |         else: | 
					
						
							| 
									
										
										
										
											2015-12-11 13:28:21 +01:00
										 |  |  |             self.putSpecialValue("itemcount", count) | 
					
						
							| 
									
										
										
										
											2014-05-06 15:20:36 +02:00
										 |  |  |         self.putNumChild(count) | 
					
						
							| 
									
										
										
										
											2013-11-01 12:49:14 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-14 13:26:22 +02:00
										 |  |  |     def resultToMi(self, value): | 
					
						
							| 
									
										
										
										
											2015-10-08 16:19:57 +02:00
										 |  |  |         if type(value) is bool: | 
					
						
							|  |  |  |             return '"%d"' % int(value) | 
					
						
							|  |  |  |         if type(value) is dict: | 
					
						
							| 
									
										
										
										
											2015-10-14 13:26:22 +02:00
										 |  |  |             return '{' + ','.join(['%s=%s' % (k, self.resultToMi(v)) | 
					
						
							| 
									
										
										
										
											2015-10-08 16:19:57 +02:00
										 |  |  |                                 for (k, v) in list(value.items())]) + '}' | 
					
						
							| 
									
										
										
										
											2015-10-14 13:26:22 +02:00
										 |  |  |         if type(value) is list: | 
					
						
							|  |  |  |             return '[' + ','.join([self.resultToMi(k) | 
					
						
							|  |  |  |                                 for k in list(value.items())]) + ']' | 
					
						
							|  |  |  |         return '"%s"' % value | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def variablesToMi(self, value, prefix): | 
					
						
							|  |  |  |         if type(value) is bool: | 
					
						
							|  |  |  |             return '"%d"' % int(value) | 
					
						
							|  |  |  |         if type(value) is dict: | 
					
						
							|  |  |  |             pairs = [] | 
					
						
							|  |  |  |             for (k, v) in list(value.items()): | 
					
						
							|  |  |  |                 if k == 'iname': | 
					
						
							|  |  |  |                     if v.startswith('.'): | 
					
						
							|  |  |  |                         v = '"%s%s"' % (prefix, v) | 
					
						
							|  |  |  |                     else: | 
					
						
							|  |  |  |                         v = '"%s"' % v | 
					
						
							|  |  |  |                 else: | 
					
						
							|  |  |  |                     v = self.variablesToMi(v, prefix) | 
					
						
							|  |  |  |                 pairs.append('%s=%s' % (k, v)) | 
					
						
							|  |  |  |             return '{' + ','.join(pairs) + '}' | 
					
						
							| 
									
										
										
										
											2015-10-08 16:19:57 +02:00
										 |  |  |         if type(value) is list: | 
					
						
							| 
									
										
										
										
											2015-10-09 15:00:20 +02:00
										 |  |  |             index = 0 | 
					
						
							|  |  |  |             pairs = [] | 
					
						
							|  |  |  |             for item in value: | 
					
						
							| 
									
										
										
										
											2015-10-14 13:26:22 +02:00
										 |  |  |                 if item.get('type', '') == 'function': | 
					
						
							|  |  |  |                     continue | 
					
						
							| 
									
										
										
										
											2015-10-09 15:00:20 +02:00
										 |  |  |                 name = item.get('name', '') | 
					
						
							|  |  |  |                 if len(name) == 0: | 
					
						
							|  |  |  |                     name = str(index) | 
					
						
							|  |  |  |                     index += 1 | 
					
						
							| 
									
										
										
										
											2015-10-14 13:26:22 +02:00
										 |  |  |                 pairs.append((name, self.variablesToMi(item, prefix))) | 
					
						
							| 
									
										
										
										
											2015-10-09 15:00:20 +02:00
										 |  |  |             pairs.sort(key = lambda pair: pair[0]) | 
					
						
							|  |  |  |             return '[' + ','.join([pair[1] for pair in pairs]) + ']' | 
					
						
							| 
									
										
										
										
											2015-10-08 16:19:57 +02:00
										 |  |  |         return '"%s"' % value | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-14 13:26:22 +02:00
										 |  |  |     def filterPrefix(self, prefix, items): | 
					
						
							|  |  |  |         return [i[len(prefix):] for i in items if i.startswith(prefix)] | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-09 15:00:20 +02:00
										 |  |  |     def tryFetchInterpreterVariables(self, args): | 
					
						
							|  |  |  |         if not int(args.get('nativemixed', 0)): | 
					
						
							|  |  |  |             return (False, '') | 
					
						
							|  |  |  |         context = args.get('context', '') | 
					
						
							|  |  |  |         if not len(context): | 
					
						
							|  |  |  |             return (False, '') | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-14 13:26:22 +02:00
										 |  |  |         expanded = args.get('expanded') | 
					
						
							|  |  |  |         args['expanded'] = self.filterPrefix('local', expanded) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         res = self.sendInterpreterRequest('variables', args) | 
					
						
							|  |  |  |         if not res: | 
					
						
							|  |  |  |             return (False, '') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         reslist = [] | 
					
						
							|  |  |  |         for item in res.get('variables', {}): | 
					
						
							|  |  |  |             if not 'iname' in item: | 
					
						
							|  |  |  |                 item['iname'] = '.' + item.get('name') | 
					
						
							|  |  |  |             reslist.append(self.variablesToMi(item, 'local')) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         watchers = args.get('watchers', None) | 
					
						
							|  |  |  |         if watchers: | 
					
						
							|  |  |  |             toevaluate = [] | 
					
						
							|  |  |  |             name2expr = {} | 
					
						
							|  |  |  |             seq = 0 | 
					
						
							|  |  |  |             for watcher in watchers: | 
					
						
							|  |  |  |                 expr = self.hexdecode(watcher.get('exp')) | 
					
						
							|  |  |  |                 name = str(seq) | 
					
						
							|  |  |  |                 toevaluate.append({'name': name, 'expression': expr}) | 
					
						
							|  |  |  |                 name2expr[name] = expr | 
					
						
							|  |  |  |                 seq += 1 | 
					
						
							|  |  |  |             args['expressions'] = toevaluate | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             args['expanded'] = self.filterPrefix('watch', expanded) | 
					
						
							|  |  |  |             del args['watchers'] | 
					
						
							|  |  |  |             res = self.sendInterpreterRequest('expressions', args) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if res: | 
					
						
							|  |  |  |                 for item in res.get('expressions', {}): | 
					
						
							|  |  |  |                     name = item.get('name') | 
					
						
							|  |  |  |                     iname = 'watch.' + name | 
					
						
							|  |  |  |                     expr = name2expr.get(name) | 
					
						
							|  |  |  |                     item['iname'] = iname | 
					
						
							|  |  |  |                     item['wname'] = self.hexencode(expr) | 
					
						
							|  |  |  |                     item['exp'] = expr | 
					
						
							|  |  |  |                     reslist.append(self.variablesToMi(item, 'watch')) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return (True, 'data=[%s]' % ','.join(reslist)) | 
					
						
							| 
									
										
										
										
											2015-10-09 15:00:20 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-11-07 13:04:09 +01:00
										 |  |  |     def putField(self, name, value): | 
					
						
							|  |  |  |         self.put('%s="%s",' % (name, value)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def putType(self, type, priority = 0): | 
					
						
							|  |  |  |         # Higher priority values override lower ones. | 
					
						
							| 
									
										
										
										
											2014-05-16 00:18:17 +02:00
										 |  |  |         if priority >= self.currentType.priority: | 
					
						
							|  |  |  |             self.currentType.value = str(type) | 
					
						
							|  |  |  |             self.currentType.priority = priority | 
					
						
							| 
									
										
										
										
											2013-11-07 13:04:09 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-16 00:18:17 +02:00
										 |  |  |     def putValue(self, value, encoding = None, priority = 0, elided = None): | 
					
						
							| 
									
										
										
										
											2013-11-07 13:04:09 +01:00
										 |  |  |         # Higher priority values override lower ones. | 
					
						
							| 
									
										
										
										
											2014-05-16 00:18:17 +02:00
										 |  |  |         # elided = 0 indicates all data is available in value, | 
					
						
							|  |  |  |         # otherwise it's the true length. | 
					
						
							|  |  |  |         if priority >= self.currentValue.priority: | 
					
						
							| 
									
										
										
										
											2014-05-19 10:55:33 +02:00
										 |  |  |             self.currentValue = ReportItem(value, encoding, priority, elided) | 
					
						
							| 
									
										
										
										
											2013-11-07 13:04:09 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-07-20 14:23:54 +02:00
										 |  |  |     def putSpecialValue(self, encoding, value = ""): | 
					
						
							|  |  |  |         self.putValue(value, encoding) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-11-07 13:04:09 +01:00
										 |  |  |     def putEmptyValue(self, priority = -10): | 
					
						
							| 
									
										
										
										
											2014-05-16 00:18:17 +02:00
										 |  |  |         if priority >= self.currentValue.priority: | 
					
						
							| 
									
										
										
										
											2014-05-19 10:55:33 +02:00
										 |  |  |             self.currentValue = ReportItem("", None, priority, None) | 
					
						
							| 
									
										
										
										
											2013-11-07 13:04:09 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def putName(self, name): | 
					
						
							|  |  |  |         self.put('name="%s",' % name) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-16 00:18:17 +02:00
										 |  |  |     def putBetterType(self, type): | 
					
						
							| 
									
										
										
										
											2014-05-19 10:55:33 +02:00
										 |  |  |         if isinstance(type, ReportItem): | 
					
						
							|  |  |  |             self.currentType.value = str(type.value) | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             self.currentType.value = str(type) | 
					
						
							| 
									
										
										
										
											2014-05-16 00:18:17 +02:00
										 |  |  |         self.currentType.priority += 1 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-11-01 12:49:14 +01:00
										 |  |  |     def putNoType(self): | 
					
						
							|  |  |  |         # FIXME: replace with something that does not need special handling | 
					
						
							|  |  |  |         # in SubItem.__exit__(). | 
					
						
							|  |  |  |         self.putBetterType(" ") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def putInaccessible(self): | 
					
						
							|  |  |  |         #self.putBetterType(" ") | 
					
						
							|  |  |  |         self.putNumChild(0) | 
					
						
							| 
									
										
										
										
											2014-05-16 00:18:17 +02:00
										 |  |  |         self.currentValue.value = None | 
					
						
							| 
									
										
										
										
											2013-11-01 12:49:14 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-11-07 13:04:09 +01:00
										 |  |  |     def putNamedSubItem(self, component, value, name): | 
					
						
							|  |  |  |         with SubItem(self, component): | 
					
						
							|  |  |  |             self.putName(name) | 
					
						
							|  |  |  |             self.putItem(value) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def isExpanded(self): | 
					
						
							|  |  |  |         #warn("IS EXPANDED: %s in %s: %s" % (self.currentIName, | 
					
						
							|  |  |  |         #    self.expandedINames, self.currentIName in self.expandedINames)) | 
					
						
							|  |  |  |         return self.currentIName in self.expandedINames | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def putPlainChildren(self, value): | 
					
						
							|  |  |  |         self.putEmptyValue(-99) | 
					
						
							|  |  |  |         self.putNumChild(1) | 
					
						
							|  |  |  |         if self.currentIName in self.expandedINames: | 
					
						
							|  |  |  |             with Children(self): | 
					
						
							|  |  |  |                self.putFields(value) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-11-07 12:26:14 +01:00
										 |  |  |     def putCStyleArray(self, value): | 
					
						
							| 
									
										
										
										
											2015-03-05 17:39:32 +01:00
										 |  |  |         arrayType = value.type.unqualified() | 
					
						
							| 
									
										
										
										
											2014-05-05 18:28:34 +02:00
										 |  |  |         innerType = value[0].type | 
					
						
							| 
									
										
										
										
											2015-04-01 17:19:43 +02:00
										 |  |  |         innerTypeName = str(innerType.unqualified()) | 
					
						
							| 
									
										
										
										
											2015-03-05 17:39:32 +01:00
										 |  |  |         ts = innerType.sizeof | 
					
						
							| 
									
										
										
										
											2015-04-01 17:19:43 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-17 15:59:39 +01:00
										 |  |  |         try: | 
					
						
							|  |  |  |             self.putValue("@0x%x" % self.addressOf(value), priority = -1) | 
					
						
							|  |  |  |         except: | 
					
						
							|  |  |  |             self.putEmptyValue() | 
					
						
							| 
									
										
										
										
											2015-03-05 17:39:32 +01:00
										 |  |  |         self.putType(arrayType) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         try: | 
					
						
							|  |  |  |             p = self.addressOf(value) | 
					
						
							|  |  |  |         except: | 
					
						
							|  |  |  |             p = None | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-20 16:03:59 +01:00
										 |  |  |         displayFormat = self.currentItemFormat() | 
					
						
							| 
									
										
										
										
											2015-07-22 11:16:20 +02:00
										 |  |  |         arrayByteSize = arrayType.sizeof | 
					
						
							|  |  |  |         if arrayByteSize == 0: | 
					
						
							|  |  |  |             # This should not happen. But it does, see QTCREATORBUG-14755. | 
					
						
							|  |  |  |             # GDB/GCC produce sizeof == 0 for QProcess arr[3] | 
					
						
							|  |  |  |             s = str(value.type) | 
					
						
							| 
									
										
										
										
											2016-01-11 15:26:07 +02:00
										 |  |  |             itemCount = s[s.find('[')+1:s.find(']')] | 
					
						
							|  |  |  |             if not itemCount: | 
					
						
							|  |  |  |                 itemCount = '100' | 
					
						
							|  |  |  |             arrayByteSize = int(itemCount) * ts; | 
					
						
							| 
									
										
										
										
											2015-07-22 11:16:20 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         n = int(arrayByteSize / ts) | 
					
						
							| 
									
										
										
										
											2015-08-12 09:05:28 +02:00
										 |  |  |         if displayFormat != RawFormat and p: | 
					
						
							|  |  |  |             if innerTypeName == "char" or innerTypeName == "wchar_t": | 
					
						
							| 
									
										
										
										
											2015-11-05 15:10:20 +01:00
										 |  |  |                 self.putCharArrayHelper(p, n, ts, self.currentItemFormat(), | 
					
						
							|  |  |  |                                         makeExpandable = False) | 
					
						
							| 
									
										
										
										
											2015-08-12 09:05:28 +02:00
										 |  |  |             else: | 
					
						
							| 
									
										
										
										
											2015-07-22 11:16:20 +02:00
										 |  |  |                 self.tryPutSimpleFormattedPointer(p, arrayType, innerTypeName, | 
					
						
							|  |  |  |                     displayFormat, arrayByteSize) | 
					
						
							| 
									
										
										
										
											2015-04-01 17:19:43 +02:00
										 |  |  |         self.putNumChild(n) | 
					
						
							| 
									
										
										
										
											2013-11-07 12:26:14 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-04-01 08:32:50 +02:00
										 |  |  |         if self.isExpanded(): | 
					
						
							| 
									
										
										
										
											2015-12-10 11:36:44 +01:00
										 |  |  |             self.putArrayData(p, n, innerType) | 
					
						
							| 
									
										
										
										
											2013-11-07 12:26:14 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-04-01 17:19:43 +02:00
										 |  |  |         self.putPlotDataHelper(p, n, innerType) | 
					
						
							| 
									
										
										
										
											2015-04-01 08:32:50 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-21 18:13:02 +01:00
										 |  |  |     def cleanAddress(self, addr): | 
					
						
							|  |  |  |         if addr is None: | 
					
						
							|  |  |  |             return "<no address>" | 
					
						
							|  |  |  |         # We cannot use str(addr) as it yields rubbish for char pointers | 
					
						
							|  |  |  |         # that might trigger Unicode encoding errors. | 
					
						
							|  |  |  |         #return addr.cast(lookupType("void").pointer()) | 
					
						
							|  |  |  |         try: | 
					
						
							| 
									
										
										
										
											2015-11-11 11:29:38 +02:00
										 |  |  |             return "0x%x" % toInteger(hex(addr), 16) | 
					
						
							| 
									
										
										
										
											2014-01-21 18:13:02 +01:00
										 |  |  |         except: | 
					
						
							|  |  |  |             warn("CANNOT CONVERT TYPE: %s" % type(addr)) | 
					
						
							| 
									
										
										
										
											2014-10-21 00:32:07 +02:00
										 |  |  |             try: | 
					
						
							|  |  |  |                 warn("ADDR: %s" % addr) | 
					
						
							|  |  |  |             except: | 
					
						
							|  |  |  |                 pass | 
					
						
							|  |  |  |             try: | 
					
						
							|  |  |  |                 warn("TYPE: %s" % addr.type) | 
					
						
							|  |  |  |             except: | 
					
						
							|  |  |  |                 pass | 
					
						
							| 
									
										
										
										
											2014-01-21 18:13:02 +01:00
										 |  |  |             return str(addr) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-20 16:03:59 +01:00
										 |  |  |     def tryPutPrettyItem(self, typeName, value): | 
					
						
							|  |  |  |         if self.useFancy and self.currentItemFormat() != RawFormat: | 
					
						
							|  |  |  |             self.putType(typeName) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             nsStrippedType = self.stripNamespaceFromType(typeName)\ | 
					
						
							|  |  |  |                 .replace("::", "__") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             # The following block is only needed for D. | 
					
						
							|  |  |  |             if nsStrippedType.startswith("_A"): | 
					
						
							|  |  |  |                 # DMD v2.058 encodes string[] as _Array_uns long long. | 
					
						
							|  |  |  |                 # With spaces. | 
					
						
							|  |  |  |                 if nsStrippedType.startswith("_Array_"): | 
					
						
							|  |  |  |                     qdump_Array(self, value) | 
					
						
							|  |  |  |                     return True | 
					
						
							|  |  |  |                 if nsStrippedType.startswith("_AArray_"): | 
					
						
							|  |  |  |                     qdump_AArray(self, value) | 
					
						
							|  |  |  |                     return True | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             dumper = self.qqDumpers.get(nsStrippedType) | 
					
						
							|  |  |  |             if not dumper is None: | 
					
						
							|  |  |  |                 dumper(self, value) | 
					
						
							|  |  |  |                 return True | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return False | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-09-01 23:35:11 +02:00
										 |  |  |     def putSimpleCharArray(self, base, size = None): | 
					
						
							|  |  |  |         if size is None: | 
					
						
							| 
									
										
										
										
											2014-10-10 01:33:35 +02:00
										 |  |  |             elided, shown, data = self.readToFirstZero(base, 1, self.displayStringLimit) | 
					
						
							| 
									
										
										
										
											2014-09-01 23:35:11 +02:00
										 |  |  |         else: | 
					
						
							|  |  |  |             elided, shown = self.computeLimit(int(size), self.displayStringLimit) | 
					
						
							| 
									
										
										
										
											2014-10-14 16:27:11 +02:00
										 |  |  |             data = self.readMemory(base, shown) | 
					
						
							| 
									
										
										
										
											2015-12-11 13:28:21 +01:00
										 |  |  |         self.putValue(data, "latin1", elided=elided) | 
					
						
							| 
									
										
										
										
											2014-09-01 23:35:11 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-04-01 17:19:43 +02:00
										 |  |  |     def putDisplay(self, editFormat, value): | 
					
						
							| 
									
										
										
										
											2015-03-20 16:03:59 +01:00
										 |  |  |         self.put('editformat="%s",' % editFormat) | 
					
						
							| 
									
										
										
										
											2015-04-01 17:19:43 +02:00
										 |  |  |         self.put('editvalue="%s",' % value) | 
					
						
							| 
									
										
										
										
											2014-05-27 22:35:54 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-05 17:39:32 +01:00
										 |  |  |     # This is shared by pointer and array formatting. | 
					
						
							| 
									
										
										
										
											2015-04-01 17:19:43 +02:00
										 |  |  |     def tryPutSimpleFormattedPointer(self, value, typeName, innerTypeName, displayFormat, limit): | 
					
						
							|  |  |  |         if displayFormat == AutomaticFormat and innerTypeName == "char": | 
					
						
							| 
									
										
										
										
											2015-03-05 17:39:32 +01:00
										 |  |  |             # Use Latin1 as default for char *. | 
					
						
							|  |  |  |             self.putType(typeName) | 
					
						
							|  |  |  |             (elided, data) = self.encodeCArray(value, 1, limit) | 
					
						
							| 
									
										
										
										
											2015-12-11 13:28:21 +01:00
										 |  |  |             self.putValue(data, "latin1", elided=elided) | 
					
						
							| 
									
										
										
										
											2015-03-05 17:39:32 +01:00
										 |  |  |             return True | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-20 16:03:59 +01:00
										 |  |  |         if displayFormat == Latin1StringFormat: | 
					
						
							| 
									
										
										
										
											2015-03-05 17:39:32 +01:00
										 |  |  |             self.putType(typeName) | 
					
						
							|  |  |  |             (elided, data) = self.encodeCArray(value, 1, limit) | 
					
						
							| 
									
										
										
										
											2015-12-11 13:28:21 +01:00
										 |  |  |             self.putValue(data, "latin1", elided=elided) | 
					
						
							| 
									
										
										
										
											2015-03-05 17:39:32 +01:00
										 |  |  |             return True | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-20 16:03:59 +01:00
										 |  |  |         if displayFormat == SeparateLatin1StringFormat: | 
					
						
							| 
									
										
										
										
											2015-03-05 17:39:32 +01:00
										 |  |  |             self.putType(typeName) | 
					
						
							|  |  |  |             (elided, data) = self.encodeCArray(value, 1, limit) | 
					
						
							| 
									
										
										
										
											2015-12-11 13:28:21 +01:00
										 |  |  |             self.putValue(data, "latin1", elided=elided) | 
					
						
							| 
									
										
										
										
											2015-03-05 17:39:32 +01:00
										 |  |  |             self.putDisplay(DisplayLatin1String, data) | 
					
						
							|  |  |  |             return True | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-20 16:03:59 +01:00
										 |  |  |         if displayFormat == Utf8StringFormat: | 
					
						
							| 
									
										
										
										
											2015-03-05 17:39:32 +01:00
										 |  |  |             self.putType(typeName) | 
					
						
							|  |  |  |             (elided, data) = self.encodeCArray(value, 1, limit) | 
					
						
							| 
									
										
										
										
											2015-12-11 13:28:21 +01:00
										 |  |  |             self.putValue(data, "utf8", elided=elided) | 
					
						
							| 
									
										
										
										
											2015-03-05 17:39:32 +01:00
										 |  |  |             return True | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-20 16:03:59 +01:00
										 |  |  |         if displayFormat == SeparateUtf8StringFormat: | 
					
						
							| 
									
										
										
										
											2015-03-05 17:39:32 +01:00
										 |  |  |             self.putType(typeName) | 
					
						
							|  |  |  |             (elided, data) = self.encodeCArray(value, 1, limit) | 
					
						
							| 
									
										
										
										
											2015-12-11 13:28:21 +01:00
										 |  |  |             self.putValue(data, "utf8", elided=elided) | 
					
						
							| 
									
										
										
										
											2015-03-05 17:39:32 +01:00
										 |  |  |             self.putDisplay(DisplayUtf8String, data) | 
					
						
							|  |  |  |             return True | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-20 16:03:59 +01:00
										 |  |  |         if displayFormat == Local8BitStringFormat: | 
					
						
							| 
									
										
										
										
											2015-03-05 17:39:32 +01:00
										 |  |  |             self.putType(typeName) | 
					
						
							|  |  |  |             (elided, data) = self.encodeCArray(value, 1, limit) | 
					
						
							| 
									
										
										
										
											2015-12-11 13:28:21 +01:00
										 |  |  |             self.putValue(data, "local8bit", elided=elided) | 
					
						
							| 
									
										
										
										
											2015-03-05 17:39:32 +01:00
										 |  |  |             return True | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-20 16:03:59 +01:00
										 |  |  |         if displayFormat == Utf16StringFormat: | 
					
						
							| 
									
										
										
										
											2015-03-05 17:39:32 +01:00
										 |  |  |             self.putType(typeName) | 
					
						
							|  |  |  |             (elided, data) = self.encodeCArray(value, 2, limit) | 
					
						
							| 
									
										
										
										
											2015-12-11 13:28:21 +01:00
										 |  |  |             self.putValue(data, "utf16", elided=elided) | 
					
						
							| 
									
										
										
										
											2015-03-05 17:39:32 +01:00
										 |  |  |             return True | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-20 16:03:59 +01:00
										 |  |  |         if displayFormat == Ucs4StringFormat: | 
					
						
							| 
									
										
										
										
											2015-03-05 17:39:32 +01:00
										 |  |  |             self.putType(typeName) | 
					
						
							|  |  |  |             (elided, data) = self.encodeCArray(value, 4, limit) | 
					
						
							| 
									
										
										
										
											2015-12-11 13:28:21 +01:00
										 |  |  |             self.putValue(data, "ucs4", elided=elided) | 
					
						
							| 
									
										
										
										
											2015-03-05 17:39:32 +01:00
										 |  |  |             return True | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return False | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-11-06 17:57:12 +01:00
										 |  |  |     def putFormattedPointer(self, value): | 
					
						
							|  |  |  |         #warn("POINTER: %s" % value) | 
					
						
							|  |  |  |         if self.isNull(value): | 
					
						
							|  |  |  |             #warn("NULL POINTER") | 
					
						
							|  |  |  |             self.putType(value.type) | 
					
						
							|  |  |  |             self.putValue("0x0") | 
					
						
							|  |  |  |             self.putNumChild(0) | 
					
						
							| 
									
										
										
										
											2014-01-25 15:32:10 +01:00
										 |  |  |             return | 
					
						
							| 
									
										
										
										
											2013-11-06 17:57:12 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         typeName = str(value.type) | 
					
						
							| 
									
										
										
										
											2015-04-13 15:52:07 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-06 12:15:39 +01:00
										 |  |  |         (dereferencable, pointerValue) = self.pointerInfo(value) | 
					
						
							|  |  |  |         if not dereferencable: | 
					
						
							| 
									
										
										
										
											2013-11-06 17:57:12 +01:00
										 |  |  |             # Failure to dereference a pointer should at least | 
					
						
							|  |  |  |             # show the value of a pointer. | 
					
						
							| 
									
										
										
										
											2016-01-06 12:15:39 +01:00
										 |  |  |             self.putValue(self.cleanAddress(pointerValue)) | 
					
						
							| 
									
										
										
										
											2013-11-06 17:57:12 +01:00
										 |  |  |             self.putType(typeName) | 
					
						
							|  |  |  |             self.putNumChild(0) | 
					
						
							| 
									
										
										
										
											2014-01-25 15:32:10 +01:00
										 |  |  |             return | 
					
						
							| 
									
										
										
										
											2013-11-06 17:57:12 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-20 16:03:59 +01:00
										 |  |  |         displayFormat = self.currentItemFormat(value.type) | 
					
						
							| 
									
										
										
										
											2015-04-30 15:52:33 +02:00
										 |  |  |         innerType = value.type.target().unqualified() | 
					
						
							|  |  |  |         innerTypeName = str(innerType) | 
					
						
							| 
									
										
										
										
											2013-11-06 17:57:12 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         if innerTypeName == "void": | 
					
						
							| 
									
										
										
										
											2015-03-20 16:03:59 +01:00
										 |  |  |             #warn("VOID POINTER: %s" % displayFormat) | 
					
						
							| 
									
										
										
										
											2013-11-06 17:57:12 +01:00
										 |  |  |             self.putType(typeName) | 
					
						
							|  |  |  |             self.putValue(str(value)) | 
					
						
							|  |  |  |             self.putNumChild(0) | 
					
						
							| 
									
										
										
										
											2014-01-25 15:32:10 +01:00
										 |  |  |             return | 
					
						
							| 
									
										
										
										
											2013-11-06 17:57:12 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-20 16:03:59 +01:00
										 |  |  |         if displayFormat == RawFormat: | 
					
						
							| 
									
										
										
										
											2013-11-06 17:57:12 +01:00
										 |  |  |             # Explicitly requested bald pointer. | 
					
						
							|  |  |  |             self.putType(typeName) | 
					
						
							| 
									
										
										
										
											2015-12-11 13:28:21 +01:00
										 |  |  |             self.putValue(self.hexencode(str(value)), "utf8:1:0") | 
					
						
							| 
									
										
										
										
											2013-11-06 17:57:12 +01:00
										 |  |  |             self.putNumChild(1) | 
					
						
							|  |  |  |             if self.currentIName in self.expandedINames: | 
					
						
							|  |  |  |                 with Children(self): | 
					
						
							|  |  |  |                     with SubItem(self, '*'): | 
					
						
							|  |  |  |                         self.putItem(value.dereference()) | 
					
						
							| 
									
										
										
										
											2014-01-25 15:32:10 +01:00
										 |  |  |             return | 
					
						
							| 
									
										
										
										
											2013-11-06 17:57:12 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-05 17:39:32 +01:00
										 |  |  |         limit = self.displayStringLimit | 
					
						
							| 
									
										
										
										
											2015-03-20 16:03:59 +01:00
										 |  |  |         if displayFormat == SeparateLatin1StringFormat \ | 
					
						
							|  |  |  |                 or displayFormat == SeparateUtf8StringFormat: | 
					
						
							| 
									
										
										
										
											2015-03-05 17:39:32 +01:00
										 |  |  |             limit = 1000000 | 
					
						
							| 
									
										
										
										
											2015-04-01 17:19:43 +02:00
										 |  |  |         if self.tryPutSimpleFormattedPointer(value, typeName, innerTypeName, displayFormat, limit): | 
					
						
							| 
									
										
										
										
											2013-11-06 17:57:12 +01:00
										 |  |  |             self.putNumChild(0) | 
					
						
							| 
									
										
										
										
											2014-01-25 15:32:10 +01:00
										 |  |  |             return | 
					
						
							| 
									
										
										
										
											2013-11-06 17:57:12 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-20 16:03:59 +01:00
										 |  |  |         if Array10Format <= displayFormat and displayFormat <= Array1000Format: | 
					
						
							|  |  |  |             n = (10, 100, 1000, 10000)[displayFormat - Array10Format] | 
					
						
							| 
									
										
										
										
											2013-11-06 17:57:12 +01:00
										 |  |  |             self.putType(typeName) | 
					
						
							| 
									
										
										
										
											2013-11-22 01:21:57 +01:00
										 |  |  |             self.putItemCount(n) | 
					
						
							| 
									
										
										
										
											2014-05-05 18:28:34 +02:00
										 |  |  |             self.putArrayData(value, n, innerType) | 
					
						
							| 
									
										
										
										
											2014-01-25 15:32:10 +01:00
										 |  |  |             return | 
					
						
							| 
									
										
										
										
											2013-11-06 17:57:12 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         if self.isFunctionType(innerType): | 
					
						
							|  |  |  |             # A function pointer. | 
					
						
							|  |  |  |             val = str(value) | 
					
						
							|  |  |  |             pos = val.find(" = ") # LLDB only, but... | 
					
						
							|  |  |  |             if pos > 0: | 
					
						
							|  |  |  |                 val = val[pos + 3:] | 
					
						
							|  |  |  |             self.putValue(val) | 
					
						
							|  |  |  |             self.putType(innerTypeName) | 
					
						
							|  |  |  |             self.putNumChild(0) | 
					
						
							|  |  |  |             return | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         #warn("AUTODEREF: %s" % self.autoDerefPointers) | 
					
						
							|  |  |  |         #warn("INAME: %s" % self.currentIName) | 
					
						
							|  |  |  |         if self.autoDerefPointers or self.currentIName.endswith('.this'): | 
					
						
							| 
									
										
										
										
											2015-03-20 16:03:59 +01:00
										 |  |  |             # Generic pointer type with AutomaticFormat. | 
					
						
							| 
									
										
										
										
											2013-11-06 17:57:12 +01:00
										 |  |  |             # Never dereference char types. | 
					
						
							|  |  |  |             if innerTypeName != "char" \ | 
					
						
							|  |  |  |                     and innerTypeName != "signed char" \ | 
					
						
							|  |  |  |                     and innerTypeName != "unsigned char"  \ | 
					
						
							|  |  |  |                     and innerTypeName != "wchar_t": | 
					
						
							|  |  |  |                 self.putType(innerTypeName) | 
					
						
							|  |  |  |                 savedCurrentChildType = self.currentChildType | 
					
						
							| 
									
										
										
										
											2014-09-12 13:31:12 +02:00
										 |  |  |                 self.currentChildType = self.stripClassTag(innerTypeName) | 
					
						
							| 
									
										
										
										
											2013-11-06 17:57:12 +01:00
										 |  |  |                 self.putItem(value.dereference()) | 
					
						
							|  |  |  |                 self.currentChildType = savedCurrentChildType | 
					
						
							| 
									
										
											  
											
												Debugger: Make dumpers somewhat work in command line GDB
With
    python sys.path.insert(1, '/data/dev/creator/share/qtcreator/debugger/')
    python from gdbbridge import *
in .gdbinit there's a new "GDB command", called "pp".
With code like
    int main(int argc, char *argv[])
    {
        QString ss = "Hello";
        QApplication app(argc, argv);
        app.setObjectName(ss);
        // break here
    }
the 'pp' command can be used as follows:
(gdb) pp app
app =
   [
      <Myns::QGuiApplication> = {"Hello"}
      staticMetaObject = <Myns::QMetaObject> = {""}
      [parent] = <Myns::QObject *> = {"0x0"}
      [children] = <Myns::QObjectList> = {"<3 items>"}
      [properties] = "<>0 items>"
      [methods] = "<6 items>"
      [signals] = "<1 items>"
   ],<Myns::QApplication> = {"Hello"}
(gdb) pp app [properties],[children]
app =
   [
      <Myns::QGuiApplication> = {"Hello"}
      staticMetaObject = <Myns::QMetaObject> = {""}
      [parent] = <Myns::QObject *> = {"0x0"}
      [children] = [
         <Myns::QObject> = {""}
         <Myns::QObject> = {""}
         <Myns::QObject> = {"fusion"}
      ],<Myns::QObjectList> = {"<3 items>"}
      [properties] = [
         windowIcon = <Myns::QVariant (QIcon)> = {""}
         cursorFlashTime = <Myns::QVariant (int)> = {"1000"}
         doubleClickInterval = <Myns::QVariant (int)> = {"400"}
         keyboardInputInterval = <Myns::QVariant (int)> = {"400"}
         wheelScrollLines = <Myns::QVariant (int)> = {"3"}
         globalStrut = <Myns::QVariant (QSize)> = {"(0, 0)"}
         startDragTime = <Myns::QVariant (int)> = {"500"}
         startDragDistance = <Myns::QVariant (int)> = {"10"}
         styleSheet = <Myns::QVariant (QString)> = {""}
         autoSipEnabled = <Myns::QVariant (bool)> = {"true"}
      ],"<10 items>"
      [methods] = "<6 items>"
      [signals] = "<1 items>"
   ],<Myns::QApplication> = {"Hello"}
(gdb) pp ss
ss =
   <Myns::QString> = {"Hello"}
Change-Id: I6e4714a5cfe34c38917500d114ad9a70d20cff39
Reviewed-by: Christian Stenger <christian.stenger@digia.com>
Reviewed-by: hjk <hjk121@nokiamail.com>
											
										 
											2014-06-13 17:45:34 +02:00
										 |  |  |                 self.putOriginalAddress(value) | 
					
						
							| 
									
										
										
										
											2014-01-25 15:32:10 +01:00
										 |  |  |                 return | 
					
						
							| 
									
										
										
										
											2013-11-06 17:57:12 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         #warn("GENERIC PLAIN POINTER: %s" % value.type) | 
					
						
							| 
									
										
										
										
											2014-01-22 12:10:49 +01:00
										 |  |  |         #warn("ADDR PLAIN POINTER: 0x%x" % value.address) | 
					
						
							| 
									
										
										
										
											2013-11-06 17:57:12 +01:00
										 |  |  |         self.putType(typeName) | 
					
						
							|  |  |  |         self.putValue("0x%x" % self.pointerValue(value)) | 
					
						
							|  |  |  |         self.putNumChild(1) | 
					
						
							|  |  |  |         if self.currentIName in self.expandedINames: | 
					
						
							|  |  |  |             with Children(self): | 
					
						
							|  |  |  |                 with SubItem(self, "*"): | 
					
						
							|  |  |  |                     self.putItem(value.dereference()) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
											  
											
												Debugger: Make dumpers somewhat work in command line GDB
With
    python sys.path.insert(1, '/data/dev/creator/share/qtcreator/debugger/')
    python from gdbbridge import *
in .gdbinit there's a new "GDB command", called "pp".
With code like
    int main(int argc, char *argv[])
    {
        QString ss = "Hello";
        QApplication app(argc, argv);
        app.setObjectName(ss);
        // break here
    }
the 'pp' command can be used as follows:
(gdb) pp app
app =
   [
      <Myns::QGuiApplication> = {"Hello"}
      staticMetaObject = <Myns::QMetaObject> = {""}
      [parent] = <Myns::QObject *> = {"0x0"}
      [children] = <Myns::QObjectList> = {"<3 items>"}
      [properties] = "<>0 items>"
      [methods] = "<6 items>"
      [signals] = "<1 items>"
   ],<Myns::QApplication> = {"Hello"}
(gdb) pp app [properties],[children]
app =
   [
      <Myns::QGuiApplication> = {"Hello"}
      staticMetaObject = <Myns::QMetaObject> = {""}
      [parent] = <Myns::QObject *> = {"0x0"}
      [children] = [
         <Myns::QObject> = {""}
         <Myns::QObject> = {""}
         <Myns::QObject> = {"fusion"}
      ],<Myns::QObjectList> = {"<3 items>"}
      [properties] = [
         windowIcon = <Myns::QVariant (QIcon)> = {""}
         cursorFlashTime = <Myns::QVariant (int)> = {"1000"}
         doubleClickInterval = <Myns::QVariant (int)> = {"400"}
         keyboardInputInterval = <Myns::QVariant (int)> = {"400"}
         wheelScrollLines = <Myns::QVariant (int)> = {"3"}
         globalStrut = <Myns::QVariant (QSize)> = {"(0, 0)"}
         startDragTime = <Myns::QVariant (int)> = {"500"}
         startDragDistance = <Myns::QVariant (int)> = {"10"}
         styleSheet = <Myns::QVariant (QString)> = {""}
         autoSipEnabled = <Myns::QVariant (bool)> = {"true"}
      ],"<10 items>"
      [methods] = "<6 items>"
      [signals] = "<1 items>"
   ],<Myns::QApplication> = {"Hello"}
(gdb) pp ss
ss =
   <Myns::QString> = {"Hello"}
Change-Id: I6e4714a5cfe34c38917500d114ad9a70d20cff39
Reviewed-by: Christian Stenger <christian.stenger@digia.com>
Reviewed-by: hjk <hjk121@nokiamail.com>
											
										 
											2014-06-13 17:45:34 +02:00
										 |  |  |     def putOriginalAddress(self, value): | 
					
						
							|  |  |  |         if not value.address is None: | 
					
						
							|  |  |  |             self.put('origaddr="0x%x",' % toInteger(value.address)) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-09-11 21:35:39 +02:00
										 |  |  |     def putQObjectNameValue(self, value): | 
					
						
							|  |  |  |         try: | 
					
						
							|  |  |  |             intSize = self.intSize() | 
					
						
							|  |  |  |             ptrSize = self.ptrSize() | 
					
						
							|  |  |  |             # dd = value["d_ptr"]["d"] is just behind the vtable. | 
					
						
							| 
									
										
										
										
											2014-01-28 13:20:05 +01:00
										 |  |  |             dd = self.extractPointer(value, offset=ptrSize) | 
					
						
							| 
									
										
										
										
											2013-09-11 21:35:39 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |             if self.qtVersion() < 0x050000: | 
					
						
							|  |  |  |                 # Size of QObjectData: 5 pointer + 2 int | 
					
						
							|  |  |  |                 #  - vtable | 
					
						
							|  |  |  |                 #   - QObject *q_ptr; | 
					
						
							|  |  |  |                 #   - QObject *parent; | 
					
						
							|  |  |  |                 #   - QObjectList children; | 
					
						
							|  |  |  |                 #   - uint isWidget : 1; etc.. | 
					
						
							|  |  |  |                 #   - int postedEvents; | 
					
						
							|  |  |  |                 #   - QMetaObject *metaObject; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 # Offset of objectName in QObjectPrivate: 5 pointer + 2 int | 
					
						
							|  |  |  |                 #   - [QObjectData base] | 
					
						
							|  |  |  |                 #   - QString objectName | 
					
						
							| 
									
										
										
										
											2014-01-30 16:15:22 +01:00
										 |  |  |                 objectName = self.extractPointer(dd + 5 * ptrSize + 2 * intSize) | 
					
						
							| 
									
										
										
										
											2013-09-11 21:35:39 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |             else: | 
					
						
							|  |  |  |                 # Size of QObjectData: 5 pointer + 2 int | 
					
						
							|  |  |  |                 #   - vtable | 
					
						
							|  |  |  |                 #   - QObject *q_ptr; | 
					
						
							|  |  |  |                 #   - QObject *parent; | 
					
						
							|  |  |  |                 #   - QObjectList children; | 
					
						
							|  |  |  |                 #   - uint isWidget : 1; etc... | 
					
						
							|  |  |  |                 #   - int postedEvents; | 
					
						
							|  |  |  |                 #   - QDynamicMetaObjectData *metaObject; | 
					
						
							| 
									
										
										
										
											2014-01-30 16:15:22 +01:00
										 |  |  |                 extra = self.extractPointer(dd + 5 * ptrSize + 2 * intSize) | 
					
						
							| 
									
										
										
										
											2013-09-11 21:35:39 +02:00
										 |  |  |                 if extra == 0: | 
					
						
							|  |  |  |                     return False | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 # Offset of objectName in ExtraData: 6 pointer | 
					
						
							|  |  |  |                 #   - QVector<QObjectUserData *> userData; only #ifndef QT_NO_USERDATA | 
					
						
							|  |  |  |                 #   - QList<QByteArray> propertyNames; | 
					
						
							|  |  |  |                 #   - QList<QVariant> propertyValues; | 
					
						
							|  |  |  |                 #   - QVector<int> runningTimers; | 
					
						
							|  |  |  |                 #   - QList<QPointer<QObject> > eventFilters; | 
					
						
							|  |  |  |                 #   - QString objectName | 
					
						
							| 
									
										
										
										
											2014-01-30 16:15:22 +01:00
										 |  |  |                 objectName = self.extractPointer(extra + 5 * ptrSize) | 
					
						
							| 
									
										
										
										
											2013-09-11 21:35:39 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |             data, size, alloc = self.byteArrayDataHelper(objectName) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-30 10:11:10 +02:00
										 |  |  |             # Object names are short, and GDB can crash on to big chunks. | 
					
						
							|  |  |  |             # Since this here is a convenience feature only, limit it. | 
					
						
							|  |  |  |             if size <= 0 or size > 80: | 
					
						
							| 
									
										
										
										
											2013-09-11 21:35:39 +02:00
										 |  |  |                 return False | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-20 15:03:27 +01:00
										 |  |  |             raw = self.readMemory(data, 2 * size) | 
					
						
							| 
									
										
										
										
											2015-12-11 13:28:21 +01:00
										 |  |  |             self.putValue(raw, "utf16", 1) | 
					
						
							| 
									
										
										
										
											2013-09-11 21:35:39 +02:00
										 |  |  |             return True | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         except: | 
					
						
							| 
									
										
											  
											
												Debugger: Make dumpers somewhat work in command line GDB
With
    python sys.path.insert(1, '/data/dev/creator/share/qtcreator/debugger/')
    python from gdbbridge import *
in .gdbinit there's a new "GDB command", called "pp".
With code like
    int main(int argc, char *argv[])
    {
        QString ss = "Hello";
        QApplication app(argc, argv);
        app.setObjectName(ss);
        // break here
    }
the 'pp' command can be used as follows:
(gdb) pp app
app =
   [
      <Myns::QGuiApplication> = {"Hello"}
      staticMetaObject = <Myns::QMetaObject> = {""}
      [parent] = <Myns::QObject *> = {"0x0"}
      [children] = <Myns::QObjectList> = {"<3 items>"}
      [properties] = "<>0 items>"
      [methods] = "<6 items>"
      [signals] = "<1 items>"
   ],<Myns::QApplication> = {"Hello"}
(gdb) pp app [properties],[children]
app =
   [
      <Myns::QGuiApplication> = {"Hello"}
      staticMetaObject = <Myns::QMetaObject> = {""}
      [parent] = <Myns::QObject *> = {"0x0"}
      [children] = [
         <Myns::QObject> = {""}
         <Myns::QObject> = {""}
         <Myns::QObject> = {"fusion"}
      ],<Myns::QObjectList> = {"<3 items>"}
      [properties] = [
         windowIcon = <Myns::QVariant (QIcon)> = {""}
         cursorFlashTime = <Myns::QVariant (int)> = {"1000"}
         doubleClickInterval = <Myns::QVariant (int)> = {"400"}
         keyboardInputInterval = <Myns::QVariant (int)> = {"400"}
         wheelScrollLines = <Myns::QVariant (int)> = {"3"}
         globalStrut = <Myns::QVariant (QSize)> = {"(0, 0)"}
         startDragTime = <Myns::QVariant (int)> = {"500"}
         startDragDistance = <Myns::QVariant (int)> = {"10"}
         styleSheet = <Myns::QVariant (QString)> = {""}
         autoSipEnabled = <Myns::QVariant (bool)> = {"true"}
      ],"<10 items>"
      [methods] = "<6 items>"
      [signals] = "<1 items>"
   ],<Myns::QApplication> = {"Hello"}
(gdb) pp ss
ss =
   <Myns::QString> = {"Hello"}
Change-Id: I6e4714a5cfe34c38917500d114ad9a70d20cff39
Reviewed-by: Christian Stenger <christian.stenger@digia.com>
Reviewed-by: hjk <hjk121@nokiamail.com>
											
										 
											2014-06-13 17:45:34 +02:00
										 |  |  |         #    warn("NO QOBJECT: %s" % value.type) | 
					
						
							| 
									
										
										
										
											2013-09-11 21:35:39 +02:00
										 |  |  |             pass | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-23 16:28:02 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-03-19 16:08:45 +01:00
										 |  |  |     def extractStaticMetaObjectHelper(self, typeobj): | 
					
						
							| 
									
										
										
										
											2014-03-12 13:20:21 +01:00
										 |  |  |         """
 | 
					
						
							|  |  |  |         Checks whether type has a Q_OBJECT macro. | 
					
						
							|  |  |  |         Returns the staticMetaObject, or 0. | 
					
						
							|  |  |  |         """
 | 
					
						
							| 
									
										
										
										
											2014-03-19 16:08:45 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         if self.isSimpleType(typeobj): | 
					
						
							| 
									
										
										
										
											2014-03-12 13:20:21 +01:00
										 |  |  |             return 0 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-03-19 16:08:45 +01:00
										 |  |  |         typeName = str(typeobj) | 
					
						
							|  |  |  |         isQObjectProper = typeName == self.qtNamespace() + "QObject" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if not isQObjectProper: | 
					
						
							|  |  |  |             if self.directBaseClass(typeobj, 0) is None: | 
					
						
							|  |  |  |                 return 0 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             # No templates for now. | 
					
						
							|  |  |  |             if typeName.find('<') >= 0: | 
					
						
							|  |  |  |                 return 0 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-11 13:20:59 +02:00
										 |  |  |         result = self.findStaticMetaObject(typeName) | 
					
						
							| 
									
										
										
										
											2014-03-12 13:20:21 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # We need to distinguish Q_OBJECT from Q_GADGET: | 
					
						
							|  |  |  |         # a Q_OBJECT SMO has a non-null superdata (unless it's QObject itself), | 
					
						
							|  |  |  |         # a Q_GADGET SMO has a null superdata (hopefully) | 
					
						
							| 
									
										
										
										
											2014-03-19 16:08:45 +01:00
										 |  |  |         if result and not isQObjectProper: | 
					
						
							|  |  |  |             superdata = self.extractPointer(result) | 
					
						
							|  |  |  |             if toInteger(superdata) == 0: | 
					
						
							| 
									
										
										
										
											2014-03-12 13:20:21 +01:00
										 |  |  |                 # This looks like a Q_GADGET | 
					
						
							| 
									
										
										
										
											2014-03-27 17:41:16 +01:00
										 |  |  |                 return 0 | 
					
						
							| 
									
										
										
										
											2014-03-12 13:20:21 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         return result | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def extractStaticMetaObject(self, typeobj): | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  |         Checks recursively whether a type derives from QObject. | 
					
						
							|  |  |  |         """
 | 
					
						
							| 
									
										
										
										
											2014-03-19 16:08:45 +01:00
										 |  |  |         if not self.useFancy: | 
					
						
							|  |  |  |             return 0 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-03-12 13:20:21 +01:00
										 |  |  |         typeName = str(typeobj) | 
					
						
							|  |  |  |         result = self.knownStaticMetaObjects.get(typeName, None) | 
					
						
							|  |  |  |         if result is not None: # Is 0 or the static metaobject. | 
					
						
							|  |  |  |             return result | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-03-27 17:41:16 +01:00
										 |  |  |         try: | 
					
						
							|  |  |  |             result = self.extractStaticMetaObjectHelper(typeobj) | 
					
						
							|  |  |  |         except RuntimeError as error: | 
					
						
							|  |  |  |             warn("METAOBJECT EXTRACTION FAILED: %s" % error) | 
					
						
							|  |  |  |             result = 0 | 
					
						
							|  |  |  |         except: | 
					
						
							|  |  |  |             warn("METAOBJECT EXTRACTION FAILED FOR UNKNOWN REASON") | 
					
						
							|  |  |  |             result = 0 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-03-12 13:20:21 +01:00
										 |  |  |         if not result: | 
					
						
							|  |  |  |             base = self.directBaseClass(typeobj, 0) | 
					
						
							|  |  |  |             if base: | 
					
						
							|  |  |  |                 result = self.extractStaticMetaObject(base) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.knownStaticMetaObjects[typeName] = result | 
					
						
							|  |  |  |         return result | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-03 22:08:35 +02:00
										 |  |  |     def staticQObjectMetaData(self, metaobject, offset1, offset2, step): | 
					
						
							|  |  |  |         items = [] | 
					
						
							| 
									
										
										
										
											2014-01-20 15:03:27 +01:00
										 |  |  |         dd = metaobject["d"] | 
					
						
							| 
									
										
										
										
											2014-01-28 13:20:05 +01:00
										 |  |  |         data = self.extractPointer(dd["data"]) | 
					
						
							|  |  |  |         sd = self.extractPointer(dd["stringdata"]) | 
					
						
							| 
									
										
										
										
											2014-01-20 15:03:27 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-29 13:40:09 +01:00
										 |  |  |         metaObjectVersion = self.extractInt(data) | 
					
						
							| 
									
										
										
										
											2014-04-03 22:08:35 +02:00
										 |  |  |         itemCount = self.extractInt(data + offset1) | 
					
						
							|  |  |  |         itemData = -offset2 if offset2 < 0 else self.extractInt(data + offset2) | 
					
						
							| 
									
										
										
										
											2014-01-20 15:03:27 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-29 13:40:09 +01:00
										 |  |  |         if metaObjectVersion >= 7: # Qt 5. | 
					
						
							|  |  |  |             byteArrayDataType = self.lookupType(self.qtNamespace() + "QByteArrayData") | 
					
						
							|  |  |  |             byteArrayDataSize = byteArrayDataType.sizeof | 
					
						
							| 
									
										
										
										
											2014-04-03 22:08:35 +02:00
										 |  |  |             for i in range(itemCount): | 
					
						
							|  |  |  |                 x = data + (itemData + step * i) * 4 | 
					
						
							| 
									
										
										
										
											2014-01-29 13:40:09 +01:00
										 |  |  |                 literal = sd + self.extractInt(x) * byteArrayDataSize | 
					
						
							|  |  |  |                 ldata, lsize, lalloc = self.byteArrayDataHelper(literal) | 
					
						
							| 
									
										
										
										
											2014-04-03 22:08:35 +02:00
										 |  |  |                 items.append(self.extractBlob(ldata, lsize).toString()) | 
					
						
							| 
									
										
										
										
											2014-01-29 13:40:09 +01:00
										 |  |  |         else: # Qt 4. | 
					
						
							| 
									
										
										
										
											2014-04-03 22:08:35 +02:00
										 |  |  |             for i in range(itemCount): | 
					
						
							|  |  |  |                 x = data + (itemData + step * i) * 4 | 
					
						
							| 
									
										
										
										
											2014-01-29 13:40:09 +01:00
										 |  |  |                 ldata = sd + self.extractInt(x) | 
					
						
							| 
									
										
										
										
											2014-04-03 22:08:35 +02:00
										 |  |  |                 items.append(self.extractCString(ldata).decode("utf8")) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return items | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-10 12:10:15 +02:00
										 |  |  |     def staticQObjectPropertyCount(self, metaobject): | 
					
						
							|  |  |  |         return self.extractInt(self.extractPointer(metaobject["d"]["data"]) + 24) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-03 22:08:35 +02:00
										 |  |  |     def staticQObjectPropertyNames(self, metaobject): | 
					
						
							|  |  |  |         return self.staticQObjectMetaData(metaobject, 24, 28, 3) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-10 12:10:15 +02:00
										 |  |  |     def staticQObjectMethodCount(self, metaobject): | 
					
						
							|  |  |  |         return self.extractInt(self.extractPointer(metaobject["d"]["data"]) + 16) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-03 22:08:35 +02:00
										 |  |  |     def staticQObjectMethodNames(self, metaobject): | 
					
						
							|  |  |  |         return self.staticQObjectMetaData(metaobject, 16, 20, 5) | 
					
						
							| 
									
										
										
										
											2014-01-29 13:40:09 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-10 12:10:15 +02:00
										 |  |  |     def staticQObjectSignalCount(self, metaobject): | 
					
						
							|  |  |  |         return self.extractInt(self.extractPointer(metaobject["d"]["data"]) + 52) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-03 22:08:35 +02:00
										 |  |  |     def staticQObjectSignalNames(self, metaobject): | 
					
						
							|  |  |  |         return self.staticQObjectMetaData(metaobject, 52, -14, 5) | 
					
						
							| 
									
										
										
										
											2014-01-20 15:03:27 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-29 13:40:09 +01:00
										 |  |  |     def extractCString(self, addr): | 
					
						
							|  |  |  |         result = bytearray() | 
					
						
							|  |  |  |         while True: | 
					
						
							|  |  |  |             d = self.extractByte(addr) | 
					
						
							|  |  |  |             if d == 0: | 
					
						
							|  |  |  |                 break | 
					
						
							|  |  |  |             result.append(d) | 
					
						
							|  |  |  |             addr += 1 | 
					
						
							|  |  |  |         return result | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-09 13:23:20 +01:00
										 |  |  |     def listChildrenGenerator(self, addr, innerType): | 
					
						
							| 
									
										
										
										
											2014-04-03 17:44:48 +02:00
										 |  |  |         base = self.extractPointer(addr) | 
					
						
							| 
									
										
										
										
											2014-03-20 12:38:56 +01:00
										 |  |  |         begin = self.extractInt(base + 8) | 
					
						
							|  |  |  |         end = self.extractInt(base + 12) | 
					
						
							|  |  |  |         array = base + 16 | 
					
						
							|  |  |  |         if self.qtVersion() < 0x50000: | 
					
						
							|  |  |  |             array += self.ptrSize() | 
					
						
							| 
									
										
										
										
											2014-02-07 23:00:26 +01:00
										 |  |  |         size = end - begin | 
					
						
							|  |  |  |         innerSize = innerType.sizeof | 
					
						
							| 
									
										
										
										
											2014-03-20 12:38:56 +01:00
										 |  |  |         stepSize = self.ptrSize() | 
					
						
							|  |  |  |         addr = array + begin * stepSize | 
					
						
							| 
									
										
										
										
											2014-02-07 23:00:26 +01:00
										 |  |  |         isInternal = innerSize <= stepSize and self.isMovableType(innerType) | 
					
						
							| 
									
										
										
										
											2014-03-20 12:38:56 +01:00
										 |  |  |         for i in range(size): | 
					
						
							|  |  |  |             if isInternal: | 
					
						
							| 
									
										
										
										
											2014-02-07 23:00:26 +01:00
										 |  |  |                 yield self.createValue(addr + i * stepSize, innerType) | 
					
						
							| 
									
										
										
										
											2014-03-20 12:38:56 +01:00
										 |  |  |             else: | 
					
						
							|  |  |  |                 p = self.extractPointer(addr + i * stepSize) | 
					
						
							|  |  |  |                 yield self.createValue(p, innerType) | 
					
						
							| 
									
										
										
										
											2014-02-07 23:00:26 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-09 13:23:20 +01:00
										 |  |  |     def vectorChildrenGenerator(self, addr, innerType): | 
					
						
							|  |  |  |         base = self.extractPointer(addr) | 
					
						
							|  |  |  |         size = self.extractInt(base + 4) | 
					
						
							|  |  |  |         data = base + self.extractPointer(base + 8 + self.ptrSize()) | 
					
						
							|  |  |  |         innerSize = innerType.sizeof | 
					
						
							|  |  |  |         for i in range(size): | 
					
						
							|  |  |  |             yield self.createValue(data + i * innerSize, innerType) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-20 15:03:27 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     # This is called is when a QObject derived class is expanded | 
					
						
							| 
									
										
										
										
											2014-01-24 17:02:23 +01:00
										 |  |  |     def putQObjectGuts(self, qobject, smo): | 
					
						
							| 
									
										
										
										
											2014-02-07 23:00:26 +01:00
										 |  |  |         intSize = self.intSize() | 
					
						
							|  |  |  |         ptrSize = self.ptrSize() | 
					
						
							|  |  |  |         # dd = value["d_ptr"]["d"] is just behind the vtable. | 
					
						
							|  |  |  |         dd = self.extractPointer(qobject, offset=ptrSize) | 
					
						
							| 
									
										
										
										
											2014-03-20 12:38:56 +01:00
										 |  |  |         isQt5 = self.qtVersion() >= 0x50000 | 
					
						
							| 
									
										
										
										
											2014-02-07 23:00:26 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-03-20 12:38:56 +01:00
										 |  |  |         extraDataOffset = 5 * ptrSize + 8 if isQt5 else 6 * ptrSize + 8 | 
					
						
							|  |  |  |         extraData = self.extractPointer(dd + extraDataOffset) | 
					
						
							| 
									
										
										
										
											2014-02-07 23:00:26 +01:00
										 |  |  |         #with SubItem(self, "[extradata]"): | 
					
						
							|  |  |  |         #    self.putValue("0x%x" % toInteger(extraData)) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-03 22:08:35 +02:00
										 |  |  |         # Parent and children. | 
					
						
							|  |  |  |         try: | 
					
						
							|  |  |  |             d_ptr = qobject["d_ptr"]["d"] | 
					
						
							|  |  |  |             self.putSubItem("[parent]", d_ptr["parent"]) | 
					
						
							|  |  |  |             self.putSubItem("[children]", d_ptr["children"]) | 
					
						
							|  |  |  |         except: | 
					
						
							|  |  |  |             pass | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-20 15:03:27 +01:00
										 |  |  |         with SubItem(self, "[properties]"): | 
					
						
							| 
									
										
										
										
											2014-02-07 23:00:26 +01:00
										 |  |  |             propertyCount = 0 | 
					
						
							| 
									
										
										
										
											2015-11-09 13:23:20 +01:00
										 |  |  |             usesVector = self.qtVersion() >= 0x50700 | 
					
						
							| 
									
										
										
										
											2014-01-24 17:41:07 +01:00
										 |  |  |             if self.isExpanded(): | 
					
						
							| 
									
										
										
										
											2014-02-07 23:00:26 +01:00
										 |  |  |                 propertyNames = self.staticQObjectPropertyNames(smo) | 
					
						
							|  |  |  |                 propertyCount = len(propertyNames) # Doesn't include dynamic properties. | 
					
						
							| 
									
										
										
										
											2014-01-24 17:41:07 +01:00
										 |  |  |                 with Children(self): | 
					
						
							| 
									
										
										
										
											2014-02-07 23:00:26 +01:00
										 |  |  |                     # Static properties. | 
					
						
							| 
									
										
										
										
											2014-01-24 17:41:07 +01:00
										 |  |  |                     for i in range(propertyCount): | 
					
						
							|  |  |  |                         name = propertyNames[i] | 
					
						
							| 
									
										
										
										
											2014-03-20 16:00:04 +01:00
										 |  |  |                         self.putCallItem(str(name), qobject, "property", '"' + name + '"') | 
					
						
							| 
									
										
										
										
											2014-01-20 15:03:27 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-07 23:00:26 +01:00
										 |  |  |                     # Dynamic properties. | 
					
						
							| 
									
										
										
										
											2014-02-28 14:09:44 +01:00
										 |  |  |                     if extraData: | 
					
						
							| 
									
										
										
										
											2015-11-09 13:23:20 +01:00
										 |  |  |                         byteArrayType = self.lookupQtType("QByteArray") | 
					
						
							|  |  |  |                         variantType = self.lookupQtType("QVariant") | 
					
						
							|  |  |  |                         names = self.listChildrenGenerator(extraData + ptrSize, byteArrayType) | 
					
						
							|  |  |  |                         if usesVector: | 
					
						
							|  |  |  |                             values = self.vectorChildrenGenerator(extraData + 2 * ptrSize, variantType) | 
					
						
							|  |  |  |                         else: | 
					
						
							|  |  |  |                             values = self.listChildrenGenerator(extraData + 2 * ptrSize, variantType) | 
					
						
							| 
									
										
										
										
											2014-04-03 17:44:48 +02:00
										 |  |  |                         for (k, v) in zip(names, values): | 
					
						
							| 
									
										
										
										
											2014-02-07 23:00:26 +01:00
										 |  |  |                             with SubItem(self, propertyCount): | 
					
						
							|  |  |  |                                 self.put('key="%s",' % self.encodeByteArray(k)) | 
					
						
							| 
									
										
										
										
											2015-12-11 13:28:21 +01:00
										 |  |  |                                 self.put('keyencoded="latin1",') | 
					
						
							| 
									
										
										
										
											2014-02-07 23:00:26 +01:00
										 |  |  |                                 self.putItem(v) | 
					
						
							|  |  |  |                                 propertyCount += 1 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-19 10:55:33 +02:00
										 |  |  |             self.putValue(str('<%s items>' % propertyCount if propertyCount else '<>0 items>')) | 
					
						
							| 
									
										
										
										
											2014-02-07 23:00:26 +01:00
										 |  |  |             self.putNumChild(1) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-03 22:08:35 +02:00
										 |  |  |         with SubItem(self, "[methods]"): | 
					
						
							| 
									
										
										
										
											2014-04-10 12:10:15 +02:00
										 |  |  |             methodCount = self.staticQObjectMethodCount(smo) | 
					
						
							|  |  |  |             self.putItemCount(methodCount) | 
					
						
							| 
									
										
										
										
											2014-04-03 22:08:35 +02:00
										 |  |  |             if self.isExpanded(): | 
					
						
							|  |  |  |                 methodNames = self.staticQObjectMethodNames(smo) | 
					
						
							|  |  |  |                 with Children(self): | 
					
						
							|  |  |  |                     for i in range(methodCount): | 
					
						
							|  |  |  |                         k = methodNames[i] | 
					
						
							|  |  |  |                         with SubItem(self, k): | 
					
						
							|  |  |  |                             self.putEmptyValue() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         with SubItem(self, "[signals]"): | 
					
						
							| 
									
										
										
										
											2014-04-10 12:10:15 +02:00
										 |  |  |             signalCount = self.staticQObjectSignalCount(smo) | 
					
						
							|  |  |  |             self.putItemCount(signalCount) | 
					
						
							| 
									
										
										
										
											2014-04-03 22:08:35 +02:00
										 |  |  |             if self.isExpanded(): | 
					
						
							|  |  |  |                 signalNames = self.staticQObjectSignalNames(smo) | 
					
						
							|  |  |  |                 signalCount = len(signalNames) | 
					
						
							|  |  |  |                 with Children(self): | 
					
						
							|  |  |  |                     for i in range(signalCount): | 
					
						
							|  |  |  |                         k = signalNames[i] | 
					
						
							|  |  |  |                         with SubItem(self, k): | 
					
						
							|  |  |  |                             self.putEmptyValue() | 
					
						
							| 
									
										
										
										
											2014-04-10 15:02:29 +02:00
										 |  |  |                     self.putQObjectConnections(qobject) | 
					
						
							| 
									
										
										
										
											2014-04-03 22:08:35 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-10 15:02:29 +02:00
										 |  |  |     def putQObjectConnections(self, qobject): | 
					
						
							| 
									
										
										
										
											2014-04-03 22:08:35 +02:00
										 |  |  |         with SubItem(self, "[connections]"): | 
					
						
							| 
									
										
										
										
											2014-04-10 15:02:29 +02:00
										 |  |  |             ptrSize = self.ptrSize() | 
					
						
							| 
									
										
										
										
											2014-04-03 22:08:35 +02:00
										 |  |  |             self.putNoType() | 
					
						
							|  |  |  |             ns = self.qtNamespace() | 
					
						
							|  |  |  |             privateTypeName = ns + "QObjectPrivate" | 
					
						
							|  |  |  |             privateType = self.lookupType(privateTypeName) | 
					
						
							|  |  |  |             dd = qobject["d_ptr"]["d"] | 
					
						
							|  |  |  |             d_ptr = dd.cast(privateType.pointer()).dereference() | 
					
						
							|  |  |  |             connections = d_ptr["connectionLists"] | 
					
						
							| 
									
										
										
										
											2014-04-10 15:02:29 +02:00
										 |  |  |             if self.isNull(connections): | 
					
						
							|  |  |  |                 self.putItemCount(0) | 
					
						
							|  |  |  |             else: | 
					
						
							|  |  |  |                 connections = connections.dereference() | 
					
						
							|  |  |  |                 connections = connections.cast(self.directBaseClass(connections.type)) | 
					
						
							| 
									
										
										
										
											2015-12-11 13:28:21 +01:00
										 |  |  |                 self.putSpecialValue("minimumitemcount", 0) | 
					
						
							| 
									
										
										
										
											2014-04-10 15:02:29 +02:00
										 |  |  |                 self.putNumChild(1) | 
					
						
							| 
									
										
										
										
											2014-04-03 22:08:35 +02:00
										 |  |  |             if self.isExpanded(): | 
					
						
							|  |  |  |                 pp = 0 | 
					
						
							|  |  |  |                 with Children(self): | 
					
						
							| 
									
										
										
										
											2014-04-10 15:02:29 +02:00
										 |  |  |                     innerType = self.templateArgument(connections.type, 0) | 
					
						
							| 
									
										
										
										
											2014-04-03 22:08:35 +02:00
										 |  |  |                     # Should check:  innerType == ns::QObjectPrivate::ConnectionList | 
					
						
							| 
									
										
										
										
											2014-04-10 15:02:29 +02:00
										 |  |  |                     base = self.extractPointer(connections) | 
					
						
							| 
									
										
										
										
											2014-04-03 22:08:35 +02:00
										 |  |  |                     data, size, alloc = self.vectorDataHelper(base) | 
					
						
							|  |  |  |                     connectionType = self.lookupType(ns + "QObjectPrivate::Connection") | 
					
						
							|  |  |  |                     for i in xrange(size): | 
					
						
							|  |  |  |                         first = self.extractPointer(data + i * 2 * ptrSize) | 
					
						
							| 
									
										
										
										
											2014-04-10 15:02:29 +02:00
										 |  |  |                         while first: | 
					
						
							|  |  |  |                             self.putSubItem("%s" % pp, | 
					
						
							|  |  |  |                                 self.createPointerValue(first, connectionType)) | 
					
						
							| 
									
										
										
										
											2014-04-03 22:08:35 +02:00
										 |  |  |                             first = self.extractPointer(first + 3 * ptrSize) | 
					
						
							|  |  |  |                             # We need to enforce some upper limit. | 
					
						
							|  |  |  |                             pp += 1 | 
					
						
							|  |  |  |                             if pp > 1000: | 
					
						
							|  |  |  |                                 break | 
					
						
							| 
									
										
										
										
											2014-01-20 15:03:27 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-05 18:28:34 +02:00
										 |  |  |     def isKnownMovableType(self, typeName): | 
					
						
							|  |  |  |         if typeName in ( | 
					
						
							| 
									
										
										
										
											2013-10-23 16:28:02 +02:00
										 |  |  |                 "QBrush", "QBitArray", "QByteArray", "QCustomTypeInfo", "QChar", "QDate", | 
					
						
							|  |  |  |                 "QDateTime", "QFileInfo", "QFixed", "QFixedPoint", "QFixedSize", | 
					
						
							|  |  |  |                 "QHashDummyValue", "QIcon", "QImage", "QLine", "QLineF", "QLatin1Char", | 
					
						
							|  |  |  |                 "QLocale", "QMatrix", "QModelIndex", "QPoint", "QPointF", "QPen", | 
					
						
							|  |  |  |                 "QPersistentModelIndex", "QResourceRoot", "QRect", "QRectF", "QRegExp", | 
					
						
							|  |  |  |                 "QSize", "QSizeF", "QString", "QTime", "QTextBlock", "QUrl", "QVariant", | 
					
						
							|  |  |  |                 "QXmlStreamAttribute", "QXmlStreamNamespaceDeclaration", | 
					
						
							|  |  |  |                 "QXmlStreamNotationDeclaration", "QXmlStreamEntityDeclaration" | 
					
						
							|  |  |  |                 ): | 
					
						
							|  |  |  |             return True | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-05 18:28:34 +02:00
										 |  |  |         return typeName == "QStringList" and self.qtVersion() >= 0x050000 | 
					
						
							| 
									
										
										
										
											2013-10-23 16:28:02 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-30 15:07:54 +01:00
										 |  |  |     def currentItemFormat(self, type = None): | 
					
						
							| 
									
										
										
										
											2015-03-20 16:03:59 +01:00
										 |  |  |         displayFormat = self.formats.get(self.currentIName, AutomaticFormat) | 
					
						
							|  |  |  |         if displayFormat == AutomaticFormat: | 
					
						
							| 
									
										
										
										
											2013-10-30 15:07:54 +01:00
										 |  |  |             if type is None: | 
					
						
							| 
									
										
										
										
											2014-05-16 00:18:17 +02:00
										 |  |  |                 type = self.currentType.value | 
					
						
							| 
									
										
										
										
											2013-10-30 15:07:54 +01:00
										 |  |  |             needle = self.stripForFormat(str(type)) | 
					
						
							| 
									
										
										
										
											2015-03-20 16:03:59 +01:00
										 |  |  |             displayFormat = self.typeformats.get(needle, AutomaticFormat) | 
					
						
							|  |  |  |         return displayFormat | 
					
						
							| 
									
										
										
										
											2013-10-23 16:28:02 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-04-14 11:24:07 +02:00
										 |  |  |     def putArrayData(self, base, n, innerType, | 
					
						
							| 
									
										
										
										
											2014-05-05 18:28:34 +02:00
										 |  |  |             childNumChild = None, maxNumChild = 10000): | 
					
						
							| 
									
										
										
										
											2015-04-14 11:24:07 +02:00
										 |  |  |         addrBase = toInteger(base) | 
					
						
							|  |  |  |         innerSize = innerType.sizeof | 
					
						
							|  |  |  |         enc = self.simpleEncoding(innerType) | 
					
						
							|  |  |  |         if enc: | 
					
						
							|  |  |  |             self.put('childtype="%s",' % innerType) | 
					
						
							|  |  |  |             self.put('addrbase="0x%x",' % addrBase) | 
					
						
							|  |  |  |             self.put('addrstep="0x%x",' % innerSize) | 
					
						
							|  |  |  |             self.put('arrayencoding="%s",' % enc) | 
					
						
							|  |  |  |             self.put('arraydata="') | 
					
						
							|  |  |  |             self.put(self.readMemory(addrBase, n * innerSize)) | 
					
						
							|  |  |  |             self.put('",') | 
					
						
							|  |  |  |         else: | 
					
						
							| 
									
										
										
										
											2014-05-05 18:28:34 +02:00
										 |  |  |             with Children(self, n, innerType, childNumChild, maxNumChild, | 
					
						
							| 
									
										
										
										
											2015-04-14 11:24:07 +02:00
										 |  |  |                     addrBase=addrBase, addrStep=innerSize): | 
					
						
							| 
									
										
										
										
											2014-05-05 18:28:34 +02:00
										 |  |  |                 for i in self.childRange(): | 
					
						
							| 
									
										
										
										
											2015-04-14 11:24:07 +02:00
										 |  |  |                     self.putSubItem(i, self.createValue(addrBase + i * innerSize, innerType)) | 
					
						
							| 
									
										
										
										
											2014-05-05 18:28:34 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-20 16:03:59 +01:00
										 |  |  |     def putArrayItem(self, name, addr, n, typeName): | 
					
						
							| 
									
										
										
										
											2014-05-05 18:28:34 +02:00
										 |  |  |         with SubItem(self, name): | 
					
						
							|  |  |  |             self.putEmptyValue() | 
					
						
							|  |  |  |             self.putType("%s [%d]" % (typeName, n)) | 
					
						
							|  |  |  |             self.putArrayData(addr, n, self.lookupType(typeName)) | 
					
						
							|  |  |  |             self.putAddress(addr) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-04-01 17:19:43 +02:00
										 |  |  |     def putPlotDataHelper(self, base, n, innerType): | 
					
						
							|  |  |  |         if self.currentItemFormat() == ArrayPlotFormat and self.isSimpleType(innerType): | 
					
						
							|  |  |  |             enc = self.simpleEncoding(innerType) | 
					
						
							|  |  |  |             if enc: | 
					
						
							|  |  |  |                 self.putField("editencoding", enc) | 
					
						
							|  |  |  |                 self.putField("editvalue", self.readMemory(base, n * innerType.sizeof)) | 
					
						
							|  |  |  |                 self.putField("editformat", DisplayPlotData) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def putPlotData(self, base, n, innerType): | 
					
						
							|  |  |  |         self.putPlotDataHelper(base, n, innerType) | 
					
						
							| 
									
										
										
										
											2014-01-04 00:39:23 +01:00
										 |  |  |         if self.isExpanded(): | 
					
						
							| 
									
										
										
										
											2015-04-01 17:19:43 +02:00
										 |  |  |             self.putArrayData(base, n, innerType) | 
					
						
							| 
									
										
										
										
											2014-01-04 00:39:23 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-04 14:48:40 +01:00
										 |  |  |     def putSpecialArgv(self, value): | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  |         Special handling for char** argv. | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  |         n = 0 | 
					
						
							|  |  |  |         p = value | 
					
						
							|  |  |  |         # p is 0 for "optimized out" cases. Or contains rubbish. | 
					
						
							|  |  |  |         try: | 
					
						
							|  |  |  |             if not self.isNull(p): | 
					
						
							|  |  |  |                 while not self.isNull(p.dereference()) and n <= 100: | 
					
						
							|  |  |  |                     p += 1 | 
					
						
							|  |  |  |                     n += 1 | 
					
						
							|  |  |  |         except: | 
					
						
							|  |  |  |             pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         with TopLevelItem(self, 'local.argv'): | 
					
						
							|  |  |  |             self.put('iname="local.argv",name="argv",') | 
					
						
							|  |  |  |             self.putItemCount(n, 100) | 
					
						
							|  |  |  |             self.putType('char **') | 
					
						
							|  |  |  |             if self.currentIName in self.expandedINames: | 
					
						
							|  |  |  |                 p = value | 
					
						
							|  |  |  |                 with Children(self, n): | 
					
						
							|  |  |  |                     for i in xrange(n): | 
					
						
							|  |  |  |                         self.putSubItem(i, p.dereference()) | 
					
						
							|  |  |  |                         p += 1 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-28 13:20:05 +01:00
										 |  |  |     def extractPointer(self, thing, offset = 0): | 
					
						
							|  |  |  |         if isinstance(thing, int): | 
					
						
							| 
									
										
										
										
											2015-04-02 12:41:26 +02:00
										 |  |  |             rawBytes = self.extractBlob(thing, self.ptrSize()).toBytes() | 
					
						
							| 
									
										
										
										
											2014-01-28 13:20:05 +01:00
										 |  |  |         elif sys.version_info[0] == 2 and isinstance(thing, long): | 
					
						
							| 
									
										
										
										
											2015-04-02 12:41:26 +02:00
										 |  |  |             rawBytes = self.extractBlob(thing, self.ptrSize()).toBytes() | 
					
						
							| 
									
										
										
										
											2014-01-28 13:20:05 +01:00
										 |  |  |         elif isinstance(thing, Blob): | 
					
						
							| 
									
										
										
										
											2015-04-02 12:41:26 +02:00
										 |  |  |             rawBytes = thing.toBytes() | 
					
						
							| 
									
										
										
										
											2014-01-28 13:20:05 +01:00
										 |  |  |         else: | 
					
						
							|  |  |  |             # Assume it's a (backend specific) Value. | 
					
						
							| 
									
										
										
										
											2015-04-02 12:41:26 +02:00
										 |  |  |             rawBytes = self.toBlob(thing).toBytes() | 
					
						
							| 
									
										
										
										
											2014-01-28 13:20:05 +01:00
										 |  |  |         code = "I" if self.ptrSize() == 4 else "Q" | 
					
						
							| 
									
										
										
										
											2015-04-02 12:41:26 +02:00
										 |  |  |         return struct.unpack_from(code, rawBytes, offset)[0] | 
					
						
							| 
									
										
										
										
											2013-09-11 21:35:39 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-12 13:09:02 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     # Parses a..b and  a.(s).b | 
					
						
							|  |  |  |     def parseRange(self, exp): | 
					
						
							| 
									
										
										
										
											2014-05-14 00:57:31 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # Search for the first unbalanced delimiter in s | 
					
						
							|  |  |  |         def searchUnbalanced(s, upwards): | 
					
						
							|  |  |  |             paran = 0 | 
					
						
							|  |  |  |             bracket = 0 | 
					
						
							|  |  |  |             if upwards: | 
					
						
							|  |  |  |                 open_p, close_p, open_b, close_b = '(', ')', '[', ']' | 
					
						
							|  |  |  |             else: | 
					
						
							|  |  |  |                 open_p, close_p, open_b, close_b = ')', '(', ']', '[' | 
					
						
							|  |  |  |             for i in range(len(s)): | 
					
						
							|  |  |  |                 c = s[i] | 
					
						
							|  |  |  |                 if c == open_p: | 
					
						
							|  |  |  |                     paran += 1 | 
					
						
							|  |  |  |                 elif c == open_b: | 
					
						
							|  |  |  |                     bracket += 1 | 
					
						
							|  |  |  |                 elif c == close_p: | 
					
						
							|  |  |  |                     paran -= 1 | 
					
						
							|  |  |  |                     if paran < 0: | 
					
						
							|  |  |  |                         return i | 
					
						
							|  |  |  |                 elif c == close_b: | 
					
						
							|  |  |  |                     bracket -= 1 | 
					
						
							|  |  |  |                     if bracket < 0: | 
					
						
							|  |  |  |                         return i | 
					
						
							|  |  |  |             return len(s) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         match = re.search("(\.)(\(.+?\))?(\.)", exp) | 
					
						
							| 
									
										
										
										
											2014-05-12 13:09:02 +02:00
										 |  |  |         if match: | 
					
						
							|  |  |  |             s = match.group(2) | 
					
						
							| 
									
										
										
										
											2014-05-14 00:57:31 +02:00
										 |  |  |             left_e = match.start(1) | 
					
						
							|  |  |  |             left_s =  1 + left_e - searchUnbalanced(exp[left_e::-1], False) | 
					
						
							|  |  |  |             right_s = match.end(3) | 
					
						
							|  |  |  |             right_e = right_s + searchUnbalanced(exp[right_s:], True) | 
					
						
							|  |  |  |             template = exp[:left_s] + '%s' +  exp[right_e:] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             a = exp[left_s:left_e] | 
					
						
							|  |  |  |             b = exp[right_s:right_e] | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-12 13:09:02 +02:00
										 |  |  |             try: | 
					
						
							| 
									
										
										
										
											2014-05-14 00:57:31 +02:00
										 |  |  |                 # Allow integral expressions. | 
					
						
							|  |  |  |                 ss = toInteger(self.parseAndEvaluate(s[1:len(s)-1]) if s else 1) | 
					
						
							|  |  |  |                 aa = toInteger(self.parseAndEvaluate(a)) | 
					
						
							|  |  |  |                 bb = toInteger(self.parseAndEvaluate(b)) | 
					
						
							|  |  |  |                 if aa < bb and ss > 0: | 
					
						
							|  |  |  |                     return True, aa, ss, bb + 1, template | 
					
						
							| 
									
										
										
										
											2014-05-12 13:09:02 +02:00
										 |  |  |             except: | 
					
						
							|  |  |  |                 pass | 
					
						
							|  |  |  |         return False, 0, 1, 1, exp | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-26 13:03:38 +01:00
										 |  |  |     def putNumChild(self, numchild): | 
					
						
							|  |  |  |         if numchild != self.currentChildNumChild: | 
					
						
							|  |  |  |             self.put('numchild="%s",' % numchild) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def handleWatches(self, args): | 
					
						
							|  |  |  |         for watcher in args.get("watchers", []): | 
					
						
							|  |  |  |             iname = watcher['iname'] | 
					
						
							|  |  |  |             exp = self.hexdecode(watcher['exp']) | 
					
						
							|  |  |  |             self.handleWatch(exp, exp, iname) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-12 13:09:02 +02:00
										 |  |  |     def handleWatch(self, origexp, exp, iname): | 
					
						
							|  |  |  |         exp = str(exp).strip() | 
					
						
							|  |  |  |         escapedExp = self.hexencode(exp) | 
					
						
							|  |  |  |         #warn("HANDLING WATCH %s -> %s, INAME: '%s'" % (origexp, exp, iname)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # Grouped items separated by semicolon | 
					
						
							|  |  |  |         if exp.find(";") >= 0: | 
					
						
							|  |  |  |             exps = exp.split(';') | 
					
						
							|  |  |  |             n = len(exps) | 
					
						
							|  |  |  |             with TopLevelItem(self, iname): | 
					
						
							|  |  |  |                 self.put('iname="%s",' % iname) | 
					
						
							|  |  |  |                 #self.put('wname="%s",' % escapedExp) | 
					
						
							|  |  |  |                 self.put('name="%s",' % exp) | 
					
						
							|  |  |  |                 self.put('exp="%s",' % exp) | 
					
						
							|  |  |  |                 self.putItemCount(n) | 
					
						
							|  |  |  |                 self.putNoType() | 
					
						
							|  |  |  |             for i in xrange(n): | 
					
						
							|  |  |  |                 self.handleWatch(exps[i], exps[i], "%s.%d" % (iname, i)) | 
					
						
							|  |  |  |             return | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # Special array index: e.g a[1..199] or a[1.(3).199] for stride 3. | 
					
						
							|  |  |  |         isRange, begin, step, end, template = self.parseRange(exp) | 
					
						
							|  |  |  |         if isRange: | 
					
						
							|  |  |  |             #warn("RANGE: %s %s %s in %s" % (begin, step, end, template)) | 
					
						
							|  |  |  |             r = range(begin, end, step) | 
					
						
							|  |  |  |             n = len(r) | 
					
						
							|  |  |  |             with TopLevelItem(self, iname): | 
					
						
							|  |  |  |                 self.put('iname="%s",' % iname) | 
					
						
							|  |  |  |                 #self.put('wname="%s",' % escapedExp) | 
					
						
							|  |  |  |                 self.put('name="%s",' % exp) | 
					
						
							|  |  |  |                 self.put('exp="%s",' % exp) | 
					
						
							|  |  |  |                 self.putItemCount(n) | 
					
						
							|  |  |  |                 self.putNoType() | 
					
						
							|  |  |  |                 with Children(self, n): | 
					
						
							|  |  |  |                     for i in r: | 
					
						
							|  |  |  |                         e = template % i | 
					
						
							|  |  |  |                         self.handleWatch(e, e, "%s.%s" % (iname, i)) | 
					
						
							|  |  |  |             return | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             # Fall back to less special syntax | 
					
						
							|  |  |  |             #return self.handleWatch(origexp, exp, iname) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         with TopLevelItem(self, iname): | 
					
						
							|  |  |  |             self.put('iname="%s",' % iname) | 
					
						
							|  |  |  |             self.put('wname="%s",' % escapedExp) | 
					
						
							| 
									
										
										
										
											2014-07-07 10:33:38 +02:00
										 |  |  |             try: | 
					
						
							|  |  |  |                 value = self.parseAndEvaluate(exp) | 
					
						
							|  |  |  |                 self.putItem(value) | 
					
						
							|  |  |  |             except RuntimeError: | 
					
						
							|  |  |  |                 self.currentType.value = " " | 
					
						
							|  |  |  |                 self.currentValue.value = "<no such value>" | 
					
						
							|  |  |  |                 self.currentChildNumChild = -1 | 
					
						
							|  |  |  |                 self.currentNumChild = 0 | 
					
						
							| 
									
										
										
										
											2014-05-12 13:09:02 +02:00
										 |  |  |                 self.putNumChild(0) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-23 19:09:08 +01:00
										 |  |  |     def registerDumper(self, funcname, function): | 
					
						
							|  |  |  |         try: | 
					
						
							|  |  |  |             #warn("FUNCTION: %s " % funcname) | 
					
						
							|  |  |  |             #funcname = function.func_name | 
					
						
							|  |  |  |             if funcname.startswith("qdump__"): | 
					
						
							|  |  |  |                 typename = funcname[7:] | 
					
						
							|  |  |  |                 self.qqDumpers[typename] = function | 
					
						
							| 
									
										
										
										
											2015-03-20 16:03:59 +01:00
										 |  |  |                 self.qqFormats[typename] = self.qqFormats.get(typename, []) | 
					
						
							| 
									
										
										
										
											2015-01-23 19:09:08 +01:00
										 |  |  |             elif funcname.startswith("qform__"): | 
					
						
							|  |  |  |                 typename = funcname[7:] | 
					
						
							|  |  |  |                 try: | 
					
						
							| 
									
										
										
										
											2015-03-20 16:03:59 +01:00
										 |  |  |                     self.qqFormats[typename] = function() | 
					
						
							| 
									
										
										
										
											2015-01-23 19:09:08 +01:00
										 |  |  |                 except: | 
					
						
							| 
									
										
										
										
											2015-03-20 16:03:59 +01:00
										 |  |  |                     self.qqFormats[typename] = [] | 
					
						
							| 
									
										
										
										
											2015-01-23 19:09:08 +01:00
										 |  |  |             elif funcname.startswith("qedit__"): | 
					
						
							|  |  |  |                 typename = funcname[7:] | 
					
						
							|  |  |  |                 try: | 
					
						
							|  |  |  |                     self.qqEditable[typename] = function | 
					
						
							|  |  |  |                 except: | 
					
						
							|  |  |  |                     pass | 
					
						
							|  |  |  |         except: | 
					
						
							|  |  |  |             pass | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-18 16:48:57 +01:00
										 |  |  |     def setupDumpers(self, _ = {}): | 
					
						
							| 
									
										
										
										
											2015-07-10 10:09:25 +02:00
										 |  |  |         self.resetCaches() | 
					
						
							| 
									
										
										
										
											2015-01-23 19:09:08 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-30 09:22:52 +01:00
										 |  |  |         for mod in self.dumpermodules: | 
					
						
							| 
									
										
										
										
											2015-09-17 11:57:30 +02:00
										 |  |  |             m = __import__(mod) | 
					
						
							| 
									
										
										
										
											2015-01-23 19:09:08 +01:00
										 |  |  |             dic = m.__dict__ | 
					
						
							|  |  |  |             for name in dic.keys(): | 
					
						
							|  |  |  |                 item = dic[name] | 
					
						
							|  |  |  |                 self.registerDumper(name, item) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-18 16:48:57 +01:00
										 |  |  |         msg = "dumpers=[" | 
					
						
							| 
									
										
										
										
											2015-01-23 19:09:08 +01:00
										 |  |  |         for key, value in self.qqFormats.items(): | 
					
						
							| 
									
										
										
										
											2015-03-20 16:03:59 +01:00
										 |  |  |             editable = ',editable="true"' if key in self.qqEditable else '' | 
					
						
							|  |  |  |             formats = (',formats=\"%s\"' % str(value)[1:-1]) if len(value) else '' | 
					
						
							|  |  |  |             msg += '{type="%s"%s%s},' % (key, editable, formats) | 
					
						
							| 
									
										
										
										
											2015-09-17 09:47:36 +02:00
										 |  |  |         msg += '],' | 
					
						
							|  |  |  |         v = 10000 * sys.version_info[0] + 100 * sys.version_info[1] + sys.version_info[2] | 
					
						
							|  |  |  |         msg += 'python="%d"' % v | 
					
						
							| 
									
										
										
										
											2015-09-09 16:34:09 +02:00
										 |  |  |         return msg | 
					
						
							| 
									
										
										
										
											2015-03-18 16:48:57 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def reloadDumpers(self, args): | 
					
						
							| 
									
										
										
										
											2015-01-30 09:22:52 +01:00
										 |  |  |         for mod in self.dumpermodules: | 
					
						
							| 
									
										
										
										
											2015-01-23 19:09:08 +01:00
										 |  |  |             m = sys.modules[mod] | 
					
						
							|  |  |  |             if sys.version_info[0] >= 3: | 
					
						
							| 
									
										
										
										
											2015-09-17 11:57:30 +02:00
										 |  |  |                 import importlib | 
					
						
							| 
									
										
										
										
											2015-01-23 19:09:08 +01:00
										 |  |  |                 importlib.reload(m) | 
					
						
							|  |  |  |             else: | 
					
						
							|  |  |  |                 reload(m) | 
					
						
							| 
									
										
										
										
											2015-03-18 16:48:57 +01:00
										 |  |  |         self.setupDumpers(args) | 
					
						
							| 
									
										
										
										
											2014-05-12 13:09:02 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-11 12:20:21 +01:00
										 |  |  |     def addDumperModule(self, args): | 
					
						
							|  |  |  |         path = args['path'] | 
					
						
							| 
									
										
										
										
											2015-01-30 09:22:52 +01:00
										 |  |  |         (head, tail) = os.path.split(path) | 
					
						
							|  |  |  |         sys.path.insert(1, head) | 
					
						
							|  |  |  |         self.dumpermodules.append(os.path.splitext(tail)[0]) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-08 16:19:57 +02:00
										 |  |  |     def extractQStringFromQDataStream(self, buf, offset): | 
					
						
							|  |  |  |         """ Read a QString from the stream """ | 
					
						
							|  |  |  |         size = struct.unpack_from("!I", buf, offset)[0] | 
					
						
							|  |  |  |         offset += 4 | 
					
						
							|  |  |  |         string = buf[offset:offset + size].decode('utf-16be') | 
					
						
							|  |  |  |         return (string, offset + size) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def extractQByteArrayFromQDataStream(self, buf, offset): | 
					
						
							|  |  |  |         """ Read a QByteArray from the stream """ | 
					
						
							|  |  |  |         size = struct.unpack_from("!I", buf, offset)[0] | 
					
						
							|  |  |  |         offset += 4 | 
					
						
							|  |  |  |         string = buf[offset:offset + size].decode('latin1') | 
					
						
							|  |  |  |         return (string, offset + size) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def extractIntFromQDataStream(self, buf, offset): | 
					
						
							|  |  |  |         """ Read an int from the stream """ | 
					
						
							|  |  |  |         value = struct.unpack_from("!I", buf, offset)[0] | 
					
						
							|  |  |  |         return (value, offset + 4) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-14 13:26:22 +02:00
										 |  |  |     def handleInterpreterMessage(self): | 
					
						
							| 
									
										
										
										
											2015-10-08 16:19:57 +02:00
										 |  |  |         """ Return True if inferior stopped """ | 
					
						
							| 
									
										
										
										
											2015-10-14 13:26:22 +02:00
										 |  |  |         resdict = self.fetchInterpreterResult() | 
					
						
							| 
									
										
										
										
											2015-10-08 16:19:57 +02:00
										 |  |  |         return resdict.get('event') == 'break' | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-14 13:26:22 +02:00
										 |  |  |     def reportInterpreterResult(self, resdict, args): | 
					
						
							|  |  |  |         print('interpreterresult=%s,token="%s"' | 
					
						
							|  |  |  |             % (self.resultToMi(resdict), args.get('token', -1))) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def reportInterpreterAsync(self, resdict, asyncclass): | 
					
						
							|  |  |  |         print('interpreterasync=%s,asyncclass="%s"' | 
					
						
							|  |  |  |             % (self.resultToMi(resdict), asyncclass)) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-08 16:19:57 +02:00
										 |  |  |     def removeInterpreterBreakpoint(self, args): | 
					
						
							|  |  |  |         res = self.sendInterpreterRequest('removebreakpoint', { 'id' : args['id'] }) | 
					
						
							|  |  |  |         return res | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def insertInterpreterBreakpoint(self, args): | 
					
						
							|  |  |  |         args['condition'] = self.hexdecode(args.get('condition', '')) | 
					
						
							| 
									
										
										
										
											2015-10-14 13:26:22 +02:00
										 |  |  |         # Will fail if the service is not yet up and running. | 
					
						
							|  |  |  |         response = self.sendInterpreterRequest('setbreakpoint', args) | 
					
						
							|  |  |  |         resdict = args.copy() | 
					
						
							|  |  |  |         bp = None if response is None else response.get("breakpoint", None) | 
					
						
							|  |  |  |         if bp: | 
					
						
							|  |  |  |             resdict['number'] = bp | 
					
						
							|  |  |  |             resdict['pending'] = 0 | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             self.createResolvePendingBreakpointsHookBreakpoint(args) | 
					
						
							|  |  |  |             resdict['number'] = -1 | 
					
						
							|  |  |  |             resdict['pending'] = 1 | 
					
						
							|  |  |  |             resdict['warning'] = 'Direct interpreter breakpoint insertion failed.' | 
					
						
							|  |  |  |         self.reportInterpreterResult(resdict, args) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def resolvePendingInterpreterBreakpoint(self, args): | 
					
						
							|  |  |  |         self.parseAndEvaluate('qt_qmlDebugEnableService("NativeQmlDebugger")') | 
					
						
							|  |  |  |         response = self.sendInterpreterRequest('setbreakpoint', args) | 
					
						
							|  |  |  |         bp = None if response is None else response.get("breakpoint", None) | 
					
						
							|  |  |  |         resdict = args.copy() | 
					
						
							|  |  |  |         if bp: | 
					
						
							|  |  |  |             resdict['number'] = bp | 
					
						
							|  |  |  |             resdict['pending'] = 0 | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             resdict['number'] = -1 | 
					
						
							|  |  |  |             resdict['pending'] = 0 | 
					
						
							|  |  |  |             resdict['error'] = 'Pending interpreter breakpoint insertion failed.' | 
					
						
							|  |  |  |         self.reportInterpreterAsync(resdict, 'breakpointmodified') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def fetchInterpreterResult(self): | 
					
						
							|  |  |  |         buf = self.parseAndEvaluate("qt_qmlDebugMessageBuffer") | 
					
						
							|  |  |  |         size = self.parseAndEvaluate("qt_qmlDebugMessageLength") | 
					
						
							|  |  |  |         msg = self.hexdecode(self.readMemory(buf, size)) | 
					
						
							|  |  |  |         # msg is a sequence of 'servicename<space>msglen<space>msg' items. | 
					
						
							|  |  |  |         resdict = {}  # Native payload. | 
					
						
							|  |  |  |         while len(msg): | 
					
						
							|  |  |  |             pos0 = msg.index(' ') # End of service name | 
					
						
							|  |  |  |             pos1 = msg.index(' ', pos0 + 1) # End of message length | 
					
						
							|  |  |  |             service = msg[0:pos0] | 
					
						
							|  |  |  |             msglen = int(msg[pos0+1:pos1]) | 
					
						
							|  |  |  |             msgend = pos1+1+msglen | 
					
						
							|  |  |  |             payload = msg[pos1+1:msgend] | 
					
						
							|  |  |  |             msg = msg[msgend:] | 
					
						
							|  |  |  |             if service == 'NativeQmlDebugger': | 
					
						
							|  |  |  |                 try: | 
					
						
							|  |  |  |                     resdict = json.loads(payload) | 
					
						
							|  |  |  |                     continue | 
					
						
							|  |  |  |                 except: | 
					
						
							|  |  |  |                     warn("Cannot parse native payload: %s" % payload) | 
					
						
							|  |  |  |             else: | 
					
						
							|  |  |  |                 print('interpreteralien=%s' | 
					
						
							|  |  |  |                     % {'service': service, 'payload': self.hexencode(payload)}) | 
					
						
							|  |  |  |         try: | 
					
						
							|  |  |  |             expr = 'qt_qmlDebugClearBuffer()' | 
					
						
							|  |  |  |             res = self.parseAndEvaluate(expr) | 
					
						
							|  |  |  |         except RuntimeError as error: | 
					
						
							|  |  |  |             warn("Cleaning buffer failed: %s: %s" % (expr, error)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return resdict | 
					
						
							| 
									
										
										
										
											2015-10-08 16:19:57 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def sendInterpreterRequest(self, command, args = {}): | 
					
						
							| 
									
										
										
										
											2015-10-14 13:26:22 +02:00
										 |  |  |         encoded = json.dumps({ 'command': command, 'arguments': args }) | 
					
						
							| 
									
										
										
										
											2015-10-08 16:19:57 +02:00
										 |  |  |         hexdata = self.hexencode(encoded) | 
					
						
							|  |  |  |         expr = 'qt_qmlDebugSendDataToService("NativeQmlDebugger","%s")' % hexdata | 
					
						
							| 
									
										
										
										
											2015-02-04 10:48:33 +01:00
										 |  |  |         try: | 
					
						
							|  |  |  |             res = self.parseAndEvaluate(expr) | 
					
						
							|  |  |  |         except RuntimeError as error: | 
					
						
							| 
									
										
										
										
											2015-10-08 16:19:57 +02:00
										 |  |  |             warn("Interpreter command failed: %s: %s" % (encoded, error)) | 
					
						
							|  |  |  |             return {} | 
					
						
							| 
									
										
										
										
											2015-02-04 13:29:42 +01:00
										 |  |  |         except AttributeError as error: | 
					
						
							|  |  |  |             # Happens with LLDB and 'None' current thread. | 
					
						
							| 
									
										
										
										
											2015-10-08 16:19:57 +02:00
										 |  |  |             warn("Interpreter command failed: %s: %s" % (encoded, error)) | 
					
						
							|  |  |  |             return {} | 
					
						
							|  |  |  |         if not res: | 
					
						
							|  |  |  |             warn("Interpreter command failed: %s " % encoded) | 
					
						
							|  |  |  |             return {} | 
					
						
							| 
									
										
										
										
											2015-10-14 13:26:22 +02:00
										 |  |  |         return self.fetchInterpreterResult() | 
					
						
							| 
									
										
										
										
											2015-10-08 16:19:57 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def executeStep(self, args): | 
					
						
							|  |  |  |         if self.nativeMixed: | 
					
						
							|  |  |  |             response = self.sendInterpreterRequest('stepin', args) | 
					
						
							|  |  |  |         self.doContinue() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def executeStepOut(self, args): | 
					
						
							|  |  |  |         if self.nativeMixed: | 
					
						
							|  |  |  |             response = self.sendInterpreterRequest('stepout', args) | 
					
						
							|  |  |  |         self.doContinue() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def executeNext(self, args): | 
					
						
							|  |  |  |         if self.nativeMixed: | 
					
						
							|  |  |  |             response = self.sendInterpreterRequest('stepover', args) | 
					
						
							|  |  |  |         self.doContinue() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def executeContinue(self, args): | 
					
						
							|  |  |  |         if self.nativeMixed: | 
					
						
							|  |  |  |             response = self.sendInterpreterRequest('continue', args) | 
					
						
							|  |  |  |         self.doContinue() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def doInsertInterpreterBreakpoint(self, args, wasPending): | 
					
						
							| 
									
										
										
										
											2015-10-14 13:26:22 +02:00
										 |  |  |         #warn("DO INSERT INTERPRETER BREAKPOINT, WAS PENDING: %s" % wasPending) | 
					
						
							| 
									
										
										
										
											2015-10-08 16:19:57 +02:00
										 |  |  |         # Will fail if the service is not yet up and running. | 
					
						
							|  |  |  |         response = self.sendInterpreterRequest('setbreakpoint', args) | 
					
						
							|  |  |  |         bp = None if response is None else response.get("breakpoint", None) | 
					
						
							|  |  |  |         if wasPending: | 
					
						
							|  |  |  |             if not bp: | 
					
						
							| 
									
										
										
										
											2015-10-14 13:26:22 +02:00
										 |  |  |                 self.reportInterpreterResult({'bpnr': -1, 'pending': 1, | 
					
						
							|  |  |  |                     'error': 'Pending interpreter breakpoint insertion failed.'}, args) | 
					
						
							|  |  |  |                 return | 
					
						
							| 
									
										
										
										
											2015-10-08 16:19:57 +02:00
										 |  |  |         else: | 
					
						
							|  |  |  |             if not bp: | 
					
						
							| 
									
										
										
										
											2015-10-14 13:26:22 +02:00
										 |  |  |                 self.reportInterpreterResult({'bpnr': -1, 'pending': 1, | 
					
						
							|  |  |  |                     'warning': 'Direct interpreter breakpoint insertion failed.'}, args) | 
					
						
							| 
									
										
										
										
											2015-10-08 16:19:57 +02:00
										 |  |  |                 self.createResolvePendingBreakpointsHookBreakpoint(args) | 
					
						
							| 
									
										
										
										
											2015-10-14 13:26:22 +02:00
										 |  |  |                 return | 
					
						
							|  |  |  |         self.reportInterpreterResult({'bpnr': bp, 'pending': 0}, args) | 
					
						
							| 
									
										
										
										
											2015-02-04 10:48:33 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-08 16:19:57 +02:00
										 |  |  |     def isInternalInterpreterFrame(self, functionName): | 
					
						
							| 
									
										
										
										
											2015-02-04 13:29:42 +01:00
										 |  |  |         if functionName is None: | 
					
						
							|  |  |  |             return False | 
					
						
							|  |  |  |         if functionName.startswith("qt_v4"): | 
					
						
							|  |  |  |             return True | 
					
						
							|  |  |  |         return functionName.startswith(self.qtNamespace() + "QV4::") | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-04-15 12:38:11 +02:00
										 |  |  |     # Hack to avoid QDate* dumper timeouts with GDB 7.4 on 32 bit | 
					
						
							|  |  |  |     # due to misaligned %ebx in SSE calls (qstring.cpp:findChar) | 
					
						
							|  |  |  |     def canCallLocale(self): | 
					
						
							|  |  |  |         return True | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-08 16:19:57 +02:00
										 |  |  |     def isReportableInterpreterFrame(self, functionName): | 
					
						
							| 
									
										
										
										
											2015-02-04 13:29:42 +01:00
										 |  |  |         return functionName and functionName.find("QV4::Moth::VME::exec") >= 0 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-04 17:21:55 +01:00
										 |  |  |     def extractQmlData(self, value): | 
					
						
							|  |  |  |         if value.type.code == PointerCode: | 
					
						
							|  |  |  |             value = value.dereference() | 
					
						
							|  |  |  |         data = value["data"] | 
					
						
							|  |  |  |         return data.cast(self.lookupType(str(value.type).replace("QV4::", "QV4::Heap::"))) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-05 12:51:25 +01:00
										 |  |  |     # Contains iname, name, and value. | 
					
						
							|  |  |  |     class LocalItem: | 
					
						
							|  |  |  |         pass | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-08 16:19:57 +02:00
										 |  |  |     def extractInterpreterStack(self): | 
					
						
							|  |  |  |         return self.sendInterpreterRequest('backtrace', {'limit': 10 }) | 
					
						
							| 
									
										
										
										
											2015-02-05 12:51:25 +01:00
										 |  |  | 
 |