]> git.saurik.com Git - wxWidgets.git/blobdiff - wxPython/samples/ide/activegrid/tool/PHPDebugger.py
move wxPython to new trunk
[wxWidgets.git] / wxPython / samples / ide / activegrid / tool / PHPDebugger.py
diff --git a/wxPython/samples/ide/activegrid/tool/PHPDebugger.py b/wxPython/samples/ide/activegrid/tool/PHPDebugger.py
deleted file mode 100644 (file)
index 8dd0d17..0000000
+++ /dev/null
@@ -1,2105 +0,0 @@
-#---------------------------------------------------------------------------
-# Name:         PHPDebugger.py
-# Purpose:      php dbg client and supporting code
-# Author:       Matt Fryer, Kevin Wang
-# Created:      2/1/06
-# Copyright:    (c) 2006 ActiveGrid, Inc.
-# License:      wxWindows License
-#---------------------------------------------------------------------------
-
-
-import os
-import socket
-import sys
-import threading
-import traceback
-import wx
-import DebuggerService
-import activegrid.util.sysutils as sysutils
-
-
-DBGC_REPLY                              = 0x0               # reply to previous DBGA_REQUEST request
-DBGC_STARTUP                            = 0x0001            # script startup
-DBGC_END                                = 0x0002            # script done
-DBGC_BREAKPOINT                         = 0x0003            # user definded breakpoint occured
-DBGC_STEPINTO_DONE                      = 0x0004            # step to the next statement is completed
-DBGC_STEPOVER_DONE                      = 0x0005            # step to the next statement is completed
-DBGC_STEPOUT_DONE                       = 0x0006            # step to the next statement is completed
-DBGC_EMBEDDED_BREAK                     = 0x0007            # breakpoint caused by DebugBreak() function
-DBGC_ERROR                              = 0x0010            # error occured
-DBGC_LOG                                = 0x0011            # logging support
-DBGC_SID                                = 0x0012            # send SID
-DBGC_PAUSE                              = 0x0013            # pause current session as soon as possible
-DBGC_AG_SHUTDOWN_REQ                    = 0x0201            # special ActiveGrid UI shutdown listening thread command
-
-
-FRAME_STACK                             = 100000            # "call:stack" - e.g. backtrace
-FRAME_SOURCE                            = 100100            # source text
-FRAME_SRC_TREE                          = 100200            # tree of source files
-FRAME_RAWDATA                           = 100300            # raw data or string
-FRAME_ERROR                             = 100400            # error notification
-FRAME_EVAL                              = 100500            # evaluating/watching
-FRAME_BPS                               = 100600            # set/remove breakpoint
-FRAME_BPL                               = 100700            # breakpoint(s) request = get the list
-FRAME_VER                               = 100800            # version request
-FRAME_SID                               = 100900            # session id info
-FRAME_SRCLINESINFO                      = 101000            # source lines info
-FRAME_SRCCTXINFO                        = 101100            # source contexts info
-FRAME_LOG                               = 101200            # logging
-FRAME_PROF                              = 101300            # profiler
-FRAME_PROF_C                            = 101400            # profiler counter/accuracy
-FRAME_SET_OPT                           = 101500            # set/update options
-
-
-DBGF_STARTED                            = 0x0001            # debugger has been started
-DBGF_FINISHED                           = 0x0002            # DBGC_END notification has been sent
-DBGF_WAITACK                            = 0x0004            # awaiting replay|request
-DBGF_UNSYNC                             = 0x0008            # protocol has been unsynchronized
-DBGF_REQUESTPENDING                     = 0x0010            # Debug session request pending
-DBGF_REQUESTFOUND                       = 0x0020            # Debug session request found
-DBGF_REJECTIONFOUND                     = 0x0040            # DBGSESSID=-1 found - session rejection
-
-
-E_ERROR                                 = 1 << 0
-E_WARNING                               = 1 << 1
-E_PARSE                                 = 1 << 2
-E_NOTICE                                = 1 << 3
-E_CORE_ERROR                            = 1 << 4
-E_CORE_WARNING                          = 1 << 5
-E_COMPILE_ERROR                         = 1 << 6
-E_COMPILE_WARNING                       = 1 << 7
-E_USER_ERROR                            = 1 << 8
-E_USER_WARNING                          = 1 << 9
-E_USER_NOTICE                           = 1 << 10
-
-
-BPS_DELETED                             = 0
-BPS_DISABLED                            = 1
-BPS_ENABLED                             = 2
-BPS_UNRESOLVED                          = 0x100
-
-
-DBG_SYNC                                = 0x5953
-DBG_SYNC2_STR                           = chr(0) + chr(0) + chr(89) + chr(83)
-RESPONSE_HEADER_SIZE                    = 16
-
-
-_VERBOSE = False
-def myprint(format, vlist=None):
-    if _VERBOSE:
-        if vlist:
-            print format % vlist
-        else:
-            print format
-
-
-#
-# 4 Char's to an Integer
-#
-def C4ToInt(ch, startPos):
-    retval = 0
-    pos    = startPos
-
-    retval = retval + (CharToInt(ch[pos]) << 24)
-    pos    = pos + 1
-    retval = retval + (CharToInt(ch[pos]) << 16)
-    pos    = pos + 1
-    retval = retval + (CharToInt(ch[pos]) << 8)
-    pos    = pos + 1
-    retval = retval + (CharToInt(ch[pos]) << 0)
-
-    return retval
-
-
-def CharToInt(ch):
-    return int((ord(ch) & 0x00FF));
-
-
-#
-# An Integer to 4 Char's
-#
-def IntToC4(num):
-    retval  = chr((num >> 24) & 0x00FF)
-    retval += chr((num >> 16) & 0x00FF)
-    retval += chr((num >> 8 ) & 0x00FF)
-    retval += chr((num >> 0 ) & 0x00FF)
-
-    return retval
-
-
-DBGA_CONTINUE                           = IntToC4(0x8001)
-DBGA_STOP                               = IntToC4(0x8002)
-DBGA_STEPINTO                           = IntToC4(0x8003)
-DBGA_STEPOVER                           = IntToC4(0x8004)
-DBGA_STEPOUT                            = IntToC4(0x8005)
-DBGA_IGNORE                             = IntToC4(0x8006)
-DBGA_REQUEST                            = IntToC4(0x8010)
-
-
-def getCommandString(code):
-    if code == DBGC_REPLY:
-        return "REPLY"
-    elif code == DBGC_STARTUP:
-        return "STARTUP"
-    elif code == DBGC_END:
-        return "END"
-    elif code == DBGC_BREAKPOINT:
-        return "BREAKPOINT"
-    elif code == DBGC_STEPINTO_DONE:
-        return "STEPINTO DONE"
-    elif code == DBGC_STEPOVER_DONE:
-        return "STEPOVER DONE"
-    elif code == DBGC_STEPOUT_DONE:
-        return "STEPOUT DONE"
-    elif code == DBGC_EMBEDDED_BREAK:
-        return "EMBEDDED BREAK"
-    elif code == DBGC_PAUSE:
-        return "PAUSE"
-    elif code == DBGC_ERROR:
-        return "ERROR"
-    elif code == DBGC_LOG:
-        return "LOG"
-    elif code == DBGC_SID:
-        return "SEND SID"
-    elif code == DBGC_AG_SHUTDOWN_REQ:
-        return "AG SHUTDOWN REQ"
-
-
-def reportFlags(flagsValue):
-    flagsRetVal = ""
-    if flagsValue & DBGF_STARTED:                  # debugger has been started
-        flagsRetVal += "started+"
-    if flagsValue & DBGF_FINISHED:                 # DBGC_END notification has been sent
-        flagsRetVal += "finished+"
-    if flagsValue & DBGF_WAITACK:                  # awaiting replay|request
-        flagsRetVal += "awaiting ack+"
-    if flagsValue & DBGF_UNSYNC:                   # protocol has been unsynchronized
-        flagsRetVal += "protocol unsynchronized+"
-    if flagsValue & DBGF_REQUESTPENDING:           # Debug session request pending
-        flagsRetVal += "request pending+"
-    if flagsValue & DBGF_REQUESTFOUND:             # Debug session request found
-        flagsRetVal += "request found+"
-    if flagsValue & DBGF_REJECTIONFOUND :          # DBGSESSID=-1 found - session rejection
-        flagsRetVal += "session rejection+"
-    return flagsRetVal
-
-
-def getErrorTypeString(code):
-    if code == E_ERROR:
-        return "[Error]"
-    elif code == E_WARNING:
-        return "[Warning]"
-    elif code == E_PARSE:
-         return "[Parse Error]"
-    elif code == E_NOTICE:
-        return "[Notice]"
-    elif code == E_CORE_ERROR:
-        return "[Core Error]"
-    elif code == E_CORE_WARNING:
-        return "[Core Warning]"
-    elif code == E_COMPILE_ERROR:
-        return  "[Compile Error]"
-    elif code == E_COMPILE_WARNING:
-        return  "[Compile Warning]"
-    elif code == E_USER_ERROR:
-        return  "[User Error]"
-    elif code == E_USER_WARNING:
-        return  "[User Warning]"
-    elif code == E_USER_NOTICE:
-        return  "[User Notice]"
-    else:
-        return "[Unexpected Error]"
-
-
-class ResponseHeader(object):
-    def __init__(self, conn, blocking = False):
-        self.isValid = False
-        receivedData = conn.recv(RESPONSE_HEADER_SIZE, blocking)
-
-        if not receivedData:
-            myprint("Tried to get %d bytes of PHP DBG header, got None\n" % RESPONSE_HEADER_SIZE)
-            return
-        elif len(receivedData) != RESPONSE_HEADER_SIZE:
-            myprint("Tried to get %d bytes of PHP DBG header, got %d\n" % (RESPONSE_HEADER_SIZE, len(receivedData)))
-            return
-
-        self.sync    = C4ToInt(receivedData, 0)
-        self.command = C4ToInt(receivedData, 4)
-        self.flags   = C4ToInt(receivedData, 8)
-        self.toRead  = C4ToInt(receivedData, 12)
-
-        myprint("ResponseHeader: sync=%x, command=%s, flags=(%s), toRead=%s\n", (self.sync, getCommandString(self.command), reportFlags(self.flags), self.toRead))
-        if self.sync != DBG_SYNC:
-            myprint("Sync wrong for header! Expected %x, got %s\n" % (DBG_SYNC, self.sync))
-            return
-
-        self.isValid = True
-
-
-class ResponsePacketFrame(object):
-    def __init__(self, conn, size, data, blocking = False):
-        self.isValid      = False
-        self.conn         = conn
-        self.data         = ''
-
-        if data:
-            self.data     = data
-            newlyReceived = False
-        elif conn:
-            newlyReceived = True
-
-            sizeToReceive = size
-            while True:
-                oneChunk  = conn.recv(sizeToReceive, blocking)
-                sizeReceived = len(oneChunk)
-                if sizeReceived > 0:
-                    self.data = self.data + oneChunk
-
-                if sizeReceived < sizeToReceive:
-                    sizeToReceive = sizeToReceive - sizeReceived
-                    continue
-                else:
-                    break
-
-            if len(self.data) != size:
-                myprint("Expected to get %d bytes of a PHP DBG packet, got %d\n" % (size, len(self.data)))
-                return
-        else:
-            return
-
-        self.frameName = C4ToInt(self.data, 0)
-        self.frameSize = C4ToInt(self.data, 4)
-        if newlyReceived:
-            myprint("Newly received ResponsePacketFrame: frameName=%d, frameSize=%d", (self.frameName, self.frameSize))
-        else:
-            myprint("Created from existing ResponsePacketFrame: frameName=%d, frameSize=%d", (self.frameName, self.frameSize))
-
-        if self.frameSize == 0:
-            return
-
-        self.currPos      = 8
-        self.totalDataLen = len(self.data)
-        self.length       = 8 + self.frameSize
-        self.isValid      = True
-        myprint("new ResponsePacketFrame: currPos=%s, totalDataLen=%s, length=%s", (repr(self.currPos), repr(self.totalDataLen), repr(self.length)))
-        return
-
-    def getNextInt(self):
-        myprint("getNextInt(): currPos=%s, totalDataLen=%s, length=%s", (repr(self.currPos), repr(self.totalDataLen), repr(self.length)))
-        if self.isValid and self.currPos + 4 <= self.length:
-            val = C4ToInt(self.data, self.currPos)
-            self.currPos = self.currPos + 4
-            myprint("getNextInt(): got an integar: %s", repr(val))
-            return val
-        else:
-            return self._errorReturn("getNextInt(): no more integar available with current frame: ")
-
-    def getNextString(self, strLen):
-        endPos = self.currPos + strLen
-        if self.isValid and endPos <= self.length:
-            #
-            # Trim the ending '\0'.  TODO: confirm this applies to all raw string data.
-            #
-            str          = self.data[self.currPos:endPos - 1]
-            self.currPos = endPos
-            myprint("getNextString(): got a string: %s", str)
-            return str
-        else:
-            return self._errorReturn("getNextString(): no more string available with current frame: ")
-
-    def getNextFrame(self, useAbsolutePos = False):
-        if useAbsolutePos:
-            #
-            # Skip this frame's header (8 bytes for frameSize and frameSize) and frame data (frameSize).
-            #
-            self.currPos = self.length
-
-        if self.isValid and self.currPos < self.totalDataLen:
-            return ResponsePacketFrame(None, None, self.data[self.currPos:])
-        else:
-            return self._errorReturn("getNextFrame(): no more frame available with current frame: ")
-
-    def _errorReturn(self, preMsg = ''):
-        myprint(preMsg + "frameName=%s, frameSize=%s, totalDataLen=%s, length=%s, currPos:%s", (repr(self.frameName), repr(self.frameSize), repr(self.totalDataLen), repr(self.length), repr(self.currPos)))
-        self.isValid = False
-        return None
-
-
-class PHPDBGFrame(object):
-    FRAME_HEADER_SIZE = 8
-    def __init__(self, frameType):
-        self.frameType = IntToC4(frameType)
-        self.frameData = ""
-
-    def addInt(self, intVal):
-        self.frameData = self.frameData + IntToC4(intVal)
-
-    def addChar(self, charVal):
-        self.frameData = self.frameData + charVal
-
-    def addStr(self, string):
-        #
-        # Add the trailing '\0'.
-        #
-        self.frameData = self.frameData + string + '\0'
-
-    def getSize(self):
-        return len(self.frameData) + PHPDBGFrame.FRAME_HEADER_SIZE
-
-    def writeFrame(self, conn):
-        header = self.frameType + IntToC4(len(self.frameData))
-        conn.sendall(header)
-        conn.sendall(self.frameData)
-
-
-class PHPDBGPacket(object):
-    def __init__(self, packetType):
-        self.header     = DBG_SYNC2_STR + packetType
-        self.frames     = []
-        self.packetSize = 0
-
-    def addFrame(self, frame):
-        self.frames.append(frame)
-        self.packetSize += frame.getSize()
-
-    def sendPacket(self, conn, flags = 0):
-        self.header += IntToC4(flags)
-        self.header += IntToC4(self.packetSize)
-        conn.sendall(self.header)
-        for frame in self.frames:
-            frame.writeFrame(conn)
-
-
-class PHPDBGException(Exception):
-    def __init__(self, msg = None, cause = None):
-        if (msg == None):
-            Exception.__init__(self)
-        elif (cause == None):
-            Exception.__init__(self, msg)
-        else:
-            Exception.__init__(self, "PHPDBGException: message:%s\n, cause:%s" % (msg, cause))
-
-
-class PHPDBGConnException(PHPDBGException):
-    pass
-
-
-class PHPDebuggerCallback(object):
-    ACTION_NONE              = 0
-    ACTION_STOP              = 1
-    ACTION_LISTEN            = 2
-
-    def __init__(self, ui, service, lsnrHosti, lsnrPorti):
-        self.ui              = ui
-        self.service         = service
-        self.lsnrHost        = lsnrHosti
-        self.lsnrPort        = lsnrPorti
-        self.lsnrThr         = None
-        self.lsnrAction      = PHPDebuggerCallback.ACTION_NONE
-        self.clearInternals()
-        self.initLsnrThr()
-
-
-    ############################################################################
-    #                      Public callback functions begin
-    #
-    def Start(self):
-        self.lsnrThr.start()
-
-    def ShutdownServer(self, stopLsnr = True):
-        #
-        # First to tell php debugger to stop execution of the current PHP
-        # program.  Disconnect with php dbg module too.
-        #
-        self.stopPhpDbg()
-
-        #
-        # Stop debug listener.
-        #
-        if stopLsnr:
-            self.stopLsnr()
-
-    def BreakExecution(self):
-        reqPacket = PHPDBGPacket(IntToC4(DBGC_PAUSE))
-
-        try:
-            reqPacket.sendPacket(self.lsnrThr)
-            self.awaitAndHandleResponse()
-        except PHPDBGConnException:
-            self.currConnFinished()
-            return
-
-        self.ui.LoadPHPFramesList(self.stackList)
-        return
-
-    def SingleStep(self):
-        reqPacket = PHPDBGPacket(DBGA_STEPINTO)
-
-        try:
-            reqPacket.sendPacket(self.lsnrThr)
-            self.lastCommand = DBGA_STEPINTO
-            self.awaitAndHandleResponse(blocking = True)
-        except PHPDBGConnException:
-            self.currConnFinished()
-            return
-
-        self.ui.LoadPHPFramesList(self.stackList)
-        return
-
-    def Next(self):
-        reqPacket = PHPDBGPacket(DBGA_STEPOVER)
-
-        try:
-            reqPacket.sendPacket(self.lsnrThr)
-            self.lastCommand = DBGA_STEPOVER
-            self.awaitAndHandleResponse(blocking = True)
-        except PHPDBGConnException:
-            self.currConnFinished()
-            return
-
-        self.ui.LoadPHPFramesList(self.stackList)
-        return
-
-    def Continue(self):
-        reqPacket = PHPDBGPacket(DBGA_CONTINUE)
-
-        try:
-            reqPacket.sendPacket(self.lsnrThr)
-            self.lastCommand = DBGA_CONTINUE
-            self.awaitAndHandleResponse(blocking = True)
-        except PHPDBGConnException:
-            self.currConnFinished()
-            return
-
-        self.ui.LoadPHPFramesList(self.stackList)
-        return
-
-    def Return(self):
-        reqPacket = PHPDBGPacket(DBGA_STEPOUT)
-
-        try:
-            reqPacket.sendPacket(self.lsnrThr)
-            self.lastCommand = DBGA_STEPOUT
-            self.awaitAndHandleResponse(blocking = True)
-        except PHPDBGConnException:
-            self.currConnFinished()
-            return
-
-        self.ui.LoadPHPFramesList(self.stackList)
-        return
-
-    def PushBreakpoints(self, noRemove = False):
-        tmpList = []
-        bps     = self.service.GetMasterBreakpointDict()
-        for fileName in bps.keys():
-            if fileName.endswith('.php'):
-                lines = bps[fileName]
-                if lines:
-                    for lineNo in lines:
-                        if lineNo:
-                            #
-                            # A tuple (fileName, lineNo) is an item which is
-                            # used as a key in self.bpDict.
-                            #
-                            tmpList.append(self.createBpKey(fileName, lineNo))
-                            myprint("PushBreakpoints(): global breakpoint \'%s:%i\'", (fileName, lineNo))
-
-        #
-        # Check to see if we have any new breakpoints added.
-        #
-        for oneKey in tmpList:
-            if not self.bpDict.has_key(oneKey):
-                #
-                # A new breakpoint.
-                #
-                newBp = BreakPoint(self, oneKey[0], oneKey[1])
-                newBp.addSelf()
-                self.bpDict[oneKey] = newBp
-                myprint("PushBreakpoints(): newly added global breakpoint \'%s:%i\'", (oneKey[0], oneKey[1]))
-
-        if noRemove:
-            return
-
-        #
-        # Check to see if any bp that is in our list, but not in the latest
-        # global list.  If so, it must have been removed recently in the
-        # global one.  Remove it from our list and tell php debugger to do
-        # so as well.
-        #
-        toRemoveList = []
-        for oneKey in self.bpDict.keys():
-            if tmpList.count(oneKey) == 0:
-                toRemoveList.append((oneKey, self.bpDict[oneKey]))
-                myprint("PushBreakpoints(): recently removed global breakpoint \'%s:%i\'", (oneKey[0], oneKey[1]))
-
-        for bp in toRemoveList:
-            bp[1].removeSelf()
-            del self.bpDict[bp[0]]
-            myprint("PushBreakpoints(): successfully removed breakpoint \'%s:%i\' from both our local list and php debugger", (bp[0][0], bp[0][1]))
-
-        return
-    #
-    #                      Public callback functions end
-    ############################################################################
-
-
-    def newConnEventHandler(self):
-        #
-        # Ok, we've got a connection from the php debugger, and some initial
-        # frame data from it.  Everything is ready and let's make some initial
-        # actions.
-        #
-        self.clearInternals()
-
-        try:
-            self.awaitAndHandleResponse(self.lsnrThr.getConnHeader())
-        except PHPDBGConnException:
-            self.currConnFinished()
-            return
-
-        self.PushBreakpoints(True)
-        self.ui.LoadPHPFramesList(self.stackList)
-
-    #
-    # This could be called when this object is constructed or when self is
-    # re-initialized after getting a new dbg module connection as a new
-    # session.
-    #
-    def clearInternals(self):
-        self.stackList       = []
-        self.errStackList    = []
-        self.stackFrameIndex = 0
-        self.isErrStack      = False
-        self.errStr          = ''
-        self.modList         = []
-        self.stopOnError     = True
-        self.lastCommand     = None
-        self.evalRet         = ''
-        self.modDict         = {}
-        self.bpDict          = {}
-        self.rawDataDict     = {}
-        self.sessID          = 0
-        self.sessType        = 0
-        self.sessEnded       = False
-        self.frameCounter    = 1000
-        self.variableList    = []
-        self.verMajor        = 0
-        self.verMinor        = 0
-        self.verDesc         = None
-
-    def initLsnrThr(self):
-        self.actionEvent = threading.Event()
-        self.lsnrThr     = PHPDBGLsnrThr(self, self.lsnrHost, self.lsnrPort, self.actionEvent, self.ui)
-
-    def awaitAndHandleResponse(self, header = None, blocking = False, disable = True, stopping = False):
-        if disable:
-            self.ui.DisableWhileDebuggerRunning()
-
-        while self.readResponse(header, blocking) != 0:
-            myprint("Waiting for response")
-
-        if stopping:
-            self.ui.DisableAfterStop()
-        else:
-            self.ui.EnableWhileDebuggerStopped()
-
-    def requestDBGVersion(self):
-        #TODO: necessary?
-        pass
-
-    def getSourceTree(self):
-        #TODO: necessary?
-        pass
-
-    def addDBGModName(self):
-        #TODO: necessary?
-        pass
-
-    def getNextFrameCounter(self):
-        self.frameCounter = self.frameCounter + 1
-        return self.frameCounter
-
-    def getVariables(self, stack):
-        self.variableList = []
-
-        reqPacket = PHPDBGPacket(DBGA_REQUEST)
-        reqFrame  = PHPDBGFrame(FRAME_EVAL)
-
-        reqFrame.addInt(0)
-        reqFrame.addInt(stack.getFrameScopeId())
-        reqPacket.addFrame(reqFrame)
-        myprint("PHPDebuggerCallback::getVariables(): about to send eval request")
-
-        try:
-            reqPacket.sendPacket(self.lsnrThr)
-            self.awaitAndHandleResponse(disable = False)
-        except PHPDBGConnException:
-            self.currConnFinished()
-            return self.variableList
-
-        myprint("PHPDebuggerCallback::getVariables(): evalRet=%s", self.evalRet)
-        evalStr = PHPDBGEvalString(stack, self.evalRet)
-        if evalStr:
-            self.variableList = evalStr.getVars()
-        myprint("PHPDebuggerCallback::getVariables(): about to return")
-
-        return self.variableList
-
-    def evalBlock(self, stack, evalStr):
-        reqPacket = PHPDBGPacket(DBGA_REQUEST)
-        reqFrame1 = PHPDBGFrame(FRAME_EVAL)
-        reqFrame2 = PHPDBGFrame(FRAME_RAWDATA)
-
-        frameID = self.getNextFrameCounter()
-        reqFrame1.addInt(frameID)
-        reqFrame1.addInt(1)
-
-        reqFrame2.addInt(frameID)
-        reqFrame2.addInt(len(evalStr) + 1)
-        reqFrame2.addStr(evalString)
-
-        reqPacket.addFrame(reqFrame2)
-        reqPacket.addFrame(reqFrame1)
-
-        try:
-            reqPacket.sendPacket(self.lsnrThr)
-            self.awaitAndHandleResponse(disable = False)
-        except PHPDBGConnException:
-            self.currConnFinished()
-            return None
-
-        evalStr = PHPDBGEvalString(stack, self.evalRet)
-
-        return evalStr.getVars()
-
-    def getBPUnderHit(self):
-        for bp in self.bpDict.values():
-            if bp.isUnderHit():
-                return bp
-
-        return None
-
-    def getRawFrameData(self, frameNo):
-        if self.rawDataDict.has_key(frameNo):
-            #
-            # Once the frameData is consumed, remove it from rawDataDict.
-            #
-            return self.rawDataDict.pop(frameNo)
-        else:
-            #
-            # TODO: do we need to handle the case when the raw frame data hasn't
-            # been received before?
-            #
-            return None
-
-    def getModByNum(self, modNum):
-        if self.modDict.has_key(modNum):
-            return self.modDict[modNum]
-        else:
-            return None
-
-    def getModByFileName(self, fileName):
-        for mn, fn in self.modDict.iteritems():
-            if fn == fileName:
-                return mn
-
-        return 0
-
-    def setMod(self, modNum, fileName):
-        if modNum != 0 and fileName:
-            self.modDict[modNum] = fileName
-
-        return
-
-    def readResponse(self, headeri = None, blockingi = False):
-        inHeader        = headeri
-        header          = None
-        cmdReceived     = 0
-        isFirstPacket   = True
-        blocking        = blockingi
-        self.isErrStack = False
-        self.rawDataDict.clear()
-
-        while True:
-            #
-            # If we have already received the first packet, we can't block any
-            # more.
-            #
-            if not isFirstPacket:
-                blocking = False
-
-            #
-            # If this is the first loop and we have a non-empty header passed in, use it.  Otherwise,
-            # read in a new header.  For subsequent loops, inHeader is None so we always read a new
-            # header from the wire.
-            #
-            if inHeader:
-                header   = inHeader
-                inHeader = None
-            else:
-                header   = ResponseHeader(self.lsnrThr, blocking)
-
-            if not header.isValid:
-                return 0
-
-            cmdReceived = header.command
-            frame       = ResponsePacketFrame(self.lsnrThr, header.toRead, None, blocking)
-            if not frame.isValid:
-                return 0
-
-            isFirstPacket     = False
-            isFirstStackFrame = True
-            while frame and frame.isValid:
-                frameName = frame.frameName
-                if frameName == FRAME_STACK:
-                    if self.isErrStack:
-                        self.errStackList = self.handleRespFrameStack(self.errStackList, frame, isFirstStackFrame)
-                    else:
-                        self.stackList = self.handleRespFrameStack(self.stackList, frame, isFirstStackFrame)
-
-                    if isFirstStackFrame:
-                        isFirstStackFrame = False
-                elif frameName == FRAME_SOURCE:
-                    self.handleRespFrameSource(frame)
-                elif frameName == FRAME_SRC_TREE:
-                    self.handleRespFrameSrcTree(frame)
-                elif frameName == FRAME_RAWDATA:
-                    self.handleRespFrameRawdata(frame)
-                elif frameName == FRAME_ERROR:
-                    self.handleRespFrameError(frame)
-                elif frameName == FRAME_EVAL:
-                    self.handleRespFrameEval(frame)
-                elif frameName == FRAME_BPS:
-                    self.handleRespFrameBps(frame)
-                elif frameName == FRAME_BPL:
-                    self.handleRespFrameBpl(frame)
-                elif frameName == FRAME_VER:
-                    self.handleRespFrameVer(frame)
-                elif frameName == FRAME_SID:
-                    self.handleRespFrameSid(frame)
-                elif frameName == FRAME_SRCLINESINFO:
-                    self.handleRespFrameSrclinesinfo(frame)
-                elif frameName == FRAME_SRCCTXINFO:
-                    self.handleRespFrameSrcctxinfo(frame)
-                elif frameName == FRAME_LOG:
-                    self.handleRespFrameLog(frame)
-                elif frameName == FRAME_PROF:
-                    self.handleRespFrameProf(frame)
-                elif frameName == FRAME_PROF_C:
-                    self.handleRespFrameProfC(frame)
-                elif frameName == FRAME_SET_OPT:
-                    self.handleRespFrameSetOpt(frame)
-                else:
-                    self.handleRespFrameUnknown(frame)
-                    return 0
-
-                #
-                # After handling of this frame, force frame to point to the
-                # next one based on current frame's absolute size.
-                #
-                frame = frame.getNextFrame(True)
-
-            if cmdReceived == DBGC_REPLY:
-                self.handleRespCmdReply()
-            elif cmdReceived == DBGC_STARTUP:
-                self.handleRespCmdStartup()
-            elif cmdReceived == DBGC_END:
-                self.handleRespCmdEnd()
-            elif cmdReceived == DBGC_BREAKPOINT:
-                self.handleRespCmdBreakpoint()
-                cmdReceived = 0
-            elif cmdReceived == DBGC_STEPINTO_DONE:
-                self.handleRespCmdStepintoDone()
-            elif cmdReceived == DBGC_STEPOVER_DONE:
-                self.handleRespCmdStepoverDone()
-            elif cmdReceived == DBGC_STEPOUT_DONE:
-                self.handleRespCmdStepoutDone()
-            elif cmdReceived == DBGC_EMBEDDED_BREAK:
-                self.handleRespCmdEmbeddedBreak()
-            elif cmdReceived == DBGC_PAUSE:
-                self.handleRespCmdPause()
-            elif cmdReceived == DBGC_ERROR:
-                self.handleRespCmdError()
-            elif cmdReceived == DBGC_LOG:
-                self.handleRespCmdLog()
-            elif cmdReceived == DBGC_SID:
-                self.handleRespCmdSid()
-            else:
-                self.handleRespCmdUnknown()
-
-        return cmdReceived
-
-    def handleRespFrameStack(self, stackList, frame, isFirst):
-        if isFirst:
-            stackList            = []
-            self.stackFrameIndex = 0
-
-        lineNo  = frame.getNextInt()
-        modNo   = frame.getNextInt()
-        scopeId = frame.getNextInt()
-        frameId = frame.getNextInt()
-        if modNo != 0:
-            newStackFrame = PHPStackFrame(self, self.getModByNum(modNo), lineNo, self.stackFrameIndex, scopeId, self.getRawFrameData(frameId), modNo)
-            stackList.append(newStackFrame)
-            self.stackFrameIndex = self.stackFrameIndex + 1
-
-        return stackList
-
-    def handleRespFrameSource(self, frame):
-        modNo           = frame.getNextInt()
-        fromFilePos     = frame.getNextInt()
-        error           = frame.getNextInt()
-        fullSize        = frame.getNextInt()
-        fileNameFrameId = frame.getNextInt()
-        textFrameId     = frame.getNextInt()
-
-        fileName = self.getModByNum(modNo)
-        if not fileName:
-            self.setFileMod(modNo, fileNameFrameId)
-
-        #
-        # TODO: fullSize string and textFrameId are not handled here.
-        #
-        return
-
-    def handleRespFrameSrcTree(self, frame):
-        parentModNo     = frame.getNextInt()
-        parentLineNo    = frame.getNextInt()
-        modNo           = frame.getNextInt()
-        fileNameFrameId = frame.getNextInt()
-
-        fileName = self.getModByNum(modNo)
-        if not fileName:
-            self.setFileMod(modNo, fileNameFrameId)
-
-        return
-
-    def handleRespFrameRawdata(self, frame):
-        frameNo = frame.getNextInt()
-        if frameNo > 0:
-            toRead = frame.getNextInt()
-            if toRead > 0:
-                str = frame.getNextString(toRead)
-                self.rawDataDict[frameNo] = str
-                myprint("handleRespFrameRawdata(): added \'%d\'=\'%s\' to rawDataDict.", (frameNo, str))
-
-        return
-
-    def handleRespFrameError(self, frame):
-        self.isErrStack = True
-
-        #
-        # Type of the error.
-        #
-        errInt0         = frame.getNextInt()
-        #
-        # ID of error message.
-        #
-        errInt1         = frame.getNextInt()
-
-        if errInt0 == E_ERROR:
-            errIdStr = "[Error]"
-        elif errInt0 == E_WARNING:
-            errIdStr = "[Warning]"
-        elif errInt0 == E_PARSE:
-            errIdStr = "[Parse Error]"
-        elif errInt0 == E_NOTICE:
-            errIdStr = "[Notice]"
-        elif errInt0 == E_CORE_ERROR:
-            errIdStr = "[Core Error]"
-        elif errInt0 == E_CORE_WARNING:
-            errIdStr = "[Core Warning]"
-        elif errInt0 == E_COMPILE_ERROR:
-            errIdStr = "[Compile Error]"
-        elif errInt0 == E_COMPILE_WARNING:
-            errIdStr = "[Compile Warning]"
-        elif errInt0 == E_USER_ERROR:
-            errIdStr = "[User Error]"
-        elif errInt0 == E_USER_WARNING:
-            errIdStr = "[User Warning]"
-        elif errInt0 == E_USER_NOTICE:
-            errIdStr = "[User Notice]"
-        else:
-            errIdStr = "[Unexpected Error]"
-
-        errMsg = self.getRawFrameData(errInt1)
-        if errMsg and len(errMsg) > 0:
-            self.errStr = errIdStr + ": " + errMsg + "\n"
-        else:
-            self.errStr = errIdStr + ": <Invalid Error Message>\n"
-
-        if not self.stopOnError:
-            if self.lastCommand == DBGA_CONTINUE:
-                self.Continue()
-            elif self.lastCommand == DBGA_STEPINTO:
-                self.SingleStep()
-            elif self.lastCommand == DBGA_STEPOUT:
-                self.Return()
-            elif self.lastCommand == DBGA_STEPOVER:
-                self.Next()
-
-        return
-
-    def handleRespFrameEval(self, frame):
-        evalInt0        = frame.getNextInt()
-        evalInt1        = frame.getNextInt()
-        evalInt2        = frame.getNextInt()
-        self.evalRet    = self.getRawFrameData(evalInt1)
-        #TODO: is the following necessary?
-        evalStr         = self.getRawFrameData(evalInt0)
-
-        return
-
-    def handleRespFrameBps(self, frame):
-        return
-
-    def handleRespFrameBpl(self, frame):
-        #
-        # Get this breakpoint.
-        #
-        dbgBp = []
-        for i in range(10):
-            dbgBp.append(frame.getNextInt())
-
-        if dbgBp[2] != 0:
-            #
-            # If filename is sent, get it from the rawDataDict.
-            #
-            fileName = self.getRawFrameData(dbgBp[2])
-            if not fileName:
-                return
-
-            #
-            # If this filename comes with a mod number, store this
-            # modNum/fileName into this session's modDict.  Notice it might
-            # overwrite previous value.
-            #
-            if dbgBp[0] != 0:
-                self.setMod(dbgBp[0], fileName)
-        elif dbgBp[0] != 0:
-            #
-            # Use modNum to get the fileName.
-            #
-            fileName = self.getModByNum(dbgBp[0])
-            if not fileName:
-                return
-        else:
-            #
-            # Couldn't get the filename; nothing we can do with.
-            #
-            return
-
-        bpKey = self.createBpKey(fileName, dbgBp[1])
-        if not self.bpDict.has_key(bpKey):
-            #
-            # Not in our bp list?  Anyway, create one for it.
-            #
-            ourBp              = BreakPoint(self, fileName, dbgBp[1], dbgBp[0], dbgBp[3], dbgBp[4], dbgBp[5], dbgBp[6], dbgBp[7], dbgBp[8], dbgBp[9])
-            self.bpDict[bpKey] = ourBp
-            newlyCreated       = True
-        else:
-            ourBp              = self.bpDict[bpKey]
-            newlyCreated       = False
-
-        #
-        # Update with the latest bp information.
-        #
-        if not newlyCreated:
-            ourBp.update(dbgBp)
-
-        return
-
-    def handleRespFrameVer(self, frame):
-        self.verMajor = frame.getNextInt()
-        self.verMinor = frame.getNextInt()
-        verFrameNo    = frame.getNextInt()
-        self.verDesc  = self.getRawFrameData(verFrameNo)
-        myprint("respFrameVer: verMajor=%s, verMinor=%s, verDesc=%s", (repr(self.verMajor), repr(self.verMinor), repr(self.verDesc)))
-
-        return
-
-    def handleRespFrameSid(self, frame):
-        self.sessID   = frame.getNextInt()
-        self.sessType = frame.getNextInt()
-        myprint("respFrameSid: sessID=%s, sessType=%s", (self.sessID, self.sessType))
-
-        return
-
-    def handleRespFrameSrclinesinfo(self, frame):
-        return
-
-    def handleRespFrameSrcctxinfo(self, frame):
-        return
-
-    def handleRespFrameLog(self, frame):
-        #
-        # TODO:
-        # Now we don't do much here besides following the protocol to retrieve
-        # the data.
-        #
-        logId           = frame.getNextInt()
-        logType         = frame.getNextInt()
-        modNo           = frame.getNextInt()
-        lineNo          = frame.getNextInt()
-        fileNameFrameId = frame.getNextInt()
-        extInfo         = frame.getNextInt()
-
-        fileName = self.getModByNum(modNo)
-        if not fileName:
-            self.setFileMod(modNo, fileNameFrameId)
-
-        return
-
-    def handleRespFrameProf(self, frame):
-        return
-
-    def handleRespFrameProfC(self, frame):
-        return
-
-    def handleRespFrameSetOpt(self, frame):
-        return
-
-    def handleRespCmdReply(self):
-        return
-
-    def handleRespCmdStartup(self):
-        return
-
-    def handleRespCmdEnd(self):
-        self.sessEnded = True
-        return
-
-    def handleRespCmdBreakpoint(self):
-        return
-
-    def handleRespCmdStepintoDone(self):
-        return
-
-    def handleRespCmdStepoverDone(self):
-        return
-
-    def handleRespCmdStepoutDone(self):
-        return
-
-    def handleRespCmdEmbeddedBreak(self):
-        return
-
-    def handleRespCmdPause(self):
-        return
-
-    def handleRespCmdError(self):
-        self.stackList = []
-
-        if len(self.errStackList) > 0:
-            self.errStr = self.errStr + "Stack Trace:\n"
-
-        while len(self.errStackList) > 0:
-            oneStack = self.errStackList.pop()
-            self.errStr = self.errStr + "%s\n" % oneStack.getLongDisplayStr()
-
-        self.ui.showErrorDialog(self.errStr, "PHP Error")
-        myprint("Got PHP Error:\n%s", self.errStr)
-
-        return
-
-    def handleRespCmdLog(self):
-        return
-
-    def handleRespCmdSid(self):
-        return
-
-    def setFileMod(self, modNo, fileNameFrameId):
-        if fileNameFrameId != 0:
-            fileName = self.getRawFrameData(fileNameFrameId)
-            if fileName and modNo != 0:
-                self.setMod(modNo, fileName)
-
-        return
-
-    def createBpKey(self, fileName, lineNo):
-        #
-        # This is to work around a bug in dbg module where it changes the path
-        # names that we pass to it to lower cases.
-        #
-        if sysutils.isWindows():
-            fileName = fileName.lower()
-
-        return (fileName, lineNo)
-
-    def setLsnrAction(self, actioni):
-        self.lsnrAction = actioni
-        return
-
-    def getLsnrAction(self):
-        return self.lsnrAction
-
-    def currConnFinished(self):
-        self.clearInternals()
-        self.setLsnrAction(PHPDebuggerCallback.ACTION_LISTEN)
-        self.actionEvent.set()
-        self.ui.DisableAfterStop()
-
-    def stopPhpDbg(self):
-        #
-        # TODO: should send a request to stop the current running PHP program.
-        #       should handle network blocking issue correctly, otherwise, we
-        #       might hang here.
-        #
-        reqPacket = PHPDBGPacket(DBGA_STOP)
-
-        try:
-            reqPacket.sendPacket(self.lsnrThr)
-            self.awaitAndHandleResponse(stopping = True)
-        except PHPDBGConnException:
-            pass
-
-        self.currConnFinished()
-        return
-
-    def stopLsnr(self):
-        if not self.lsnrThr:
-            return
-
-        #
-        # Then we try to stop our listener thread.
-        #
-        if self.lsnrThr.hasBeenConnected():
-            #
-            # If the listener thread has already accepted a connection from a
-            # php debug module/client, it is sleeping now and wait for this
-            # condition object to be set so that it can exit.
-            #
-            self.setLsnrAction(PHPDebuggerCallback.ACTION_STOP)
-            self.actionEvent.set()
-        else:
-            #
-            # If the listener thread has never been connected from a php debug
-            # module/client, it is still blocking on a accept() call.  We
-            # connect to it here and send a special shutdown command asking it
-            # to exit.
-            #
-            shutdownMessage = IntToC4(DBG_SYNC) + IntToC4(DBGC_AG_SHUTDOWN_REQ) + IntToC4(0) + IntToC4(0)
-            tempSocket      = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
-            try:
-                tempSocket.connect((self.lsnrHost, self.lsnrPort))
-                tempSocket.sendall(shutdownMessage)
-            except:
-                myprint("shutdown connection/send message got exception!")
-
-            tempSocket.close()
-
-        self.lsnrThr.join()
-        self.lsnrThr = None
-
-
-class PHPDBGLsnrThr(threading.Thread):
-    def __init__(self, interfacei, hosti, porti, actionEventi, uii):
-        threading.Thread.__init__(self)
-        self.interface          = interfacei
-        self.svrHost            = hosti
-        self.svrPort            = porti
-        self.actionEvent        = actionEventi
-        self.svrSocket          = None
-        self.clntConn           = None
-        self.clntAddr           = None
-        self.nonBlockingTimeout = 1
-        self.connHeader         = None
-        self.ui                 = uii
-
-    def initSvrSocket(self):
-        self.svrSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
-        self.svrSocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
-        self.svrSocket.bind((self.svrHost, self.svrPort))
-
-    def waitForClntConn(self):
-        self.svrSocket.listen(5)
-        self.clntConn, self.clntAddr = self.svrSocket.accept()
-        self.clntConn.settimeout(self.nonBlockingTimeout)
-
-    def run(self):
-        #
-        # Initialize this server socket.
-        #
-        self.initSvrSocket()
-
-        while True:
-            #
-            # Block until we get a new connection from a php debug client or our
-            # debugger ui (with a special shutting down header/command).
-            #
-            self.waitForClntConn()
-    
-            #
-            # Ok, a new connection comes in ...  Read the header to see where it
-            # comes from.
-            #
-            self.connHeader = ResponseHeader(self)
-            if self.connHeader.command == DBGC_AG_SHUTDOWN_REQ:
-                #
-                # This is a special command coming from our UI asking this
-                # thread to exit.  This only happens if after this thread has
-                # been waiting for new connections from PHP debug module, no one
-                # connects, and UI is ready to shutdown this thread.
-                #
-                self.shutdown()
-                break
-            else:
-                #
-                # Tell the main gui thread to handle this new connection.
-                #
-                wx.CallAfter(self.interface.newConnEventHandler)
-    
-                #
-                # From now on, PHPDebuggerCallback will communicate with the php
-                # debug module using this thread's clntConn socket.  This thread
-                # itself will keep sleeping until get notified to make some
-                # actions.
-                #
-                self.actionEvent.wait()
-                self.actionEvent.clear()
-
-                action = self.interface.getLsnrAction()
-                if action == PHPDebuggerCallback.ACTION_STOP:
-                    self.shutdown()
-                    break
-                elif action == PHPDebuggerCallback.ACTION_LISTEN:
-                    if self.clntConn:
-                        self.clntConn.shutdown(socket.SHUT_RDWR)
-                        self.clntConn.close()
-                        self.clntConn = None
-
-                    continue
-                else:
-                    continue
-
-    def shutdown(self):
-        #
-        # Cleanup and ready to exit.
-        #
-        self.clntConn.shutdown(socket.SHUT_RDWR)
-        self.clntConn.close()
-        self.svrSocket.close()
-
-    def recv(self, size, blocking = False):
-        if self.clntConn:
-            myprint("recv: trying to receive %d bytes of data ...", size)
-            if blocking:
-                self.clntConn.settimeout(None)
-            else:
-                self.clntConn.settimeout(self.nonBlockingTimeout)
-
-            try:
-                rData = self.clntConn.recv(size)
-            except socket.timeout:
-                myprint("recv: got timed out")
-                rData = None
-            except:
-                myprint("recv: got an unexpected exception: %s", sys.exc_info()[0])
-                raise PHPDBGConnException
-
-            return rData
-        else:
-            raise PHPDBGConnException
-
-    def sendall(self, message):
-        if self.clntConn:
-            try:
-                self.clntConn.sendall(message)
-            except:
-                myprint("sendall: got an unexpected exception: %s", sys.exc_info()[0])
-                raise PHPDBGConnException
-        else:
-            raise PHPDBGConnException
-
-    def hasBeenConnected(self):
-        return self.clntConn != None
-
-    def getConnHeader(self):
-        return self.connHeader
-
-
-class PHPValue(object):
-    PEV_NAMES           = ("undefined", "long", "double", "string", "array", "object", "boolean", "resource", "reference", "soft reference", "null")
-    PEVT_UNKNOWN        = 0
-    PEVT_LONG           = 1
-    PEVT_DOUBLE         = 2
-    PEVT_STRING         = 3
-    PEVT_ARRAY          = 4
-    PEVT_OBJECT         = 5
-    PEVT_BOOLEAN        = 6
-    PEVT_RESOURCE       = 7
-    PEVT_REF            = 8
-    PEVT_SOFTREF        = 9
-    PEVT_NULL           = 10
-
-    NULL_VALUE_STR      = "NULL"
-    TRUE_VALUE_STR      = "True"
-    FALSE_VALUE_STR     = "False"
-    OBJECT_VALUE_STR    = "<%s> object"
-    STRING_VALUE_STR    = "\"%s\""
-    REFERENCE_VALUE_STR = "<reference><%s>"
-    RESOURCE_VALUE_STR  = "<%s><%s>"
-
-    def __init__(self, frame, type, valueList):
-        self.fStackFrame = frame
-        self.fValueType  = type
-
-        if type == self.PEVT_OBJECT:
-            self.fValueString = self.OBJECT_VALUE_STR % valueList[0]
-            self.fVariables   = valueList[1:]
-        elif type == self.PEVT_ARRAY:
-            self.fValueString = ''
-            self.fVariables   = valueList
-        else:
-            self.fVariables = []
-            if type == self.PEVT_STRING:
-                self.fValueString = self.STRING_VALUE_STR % valueList[0]
-            elif type == self.PEVT_NULL:
-                self.fValueString = self.NULL_VALUE_STR
-            elif type == self.PEVT_BOOLEAN:
-                if valueList[0] == "0":
-                    self.fValueString = self.FALSE_VALUE_STR
-                else:
-                    self.fValueString = self.TRUE_VALUE_STR
-            elif type == self.PEVT_REF or type == self.PEVT_SOFTREF:
-                self.fValueString = self.REFERENCE_VALUE_STR % valueList[0]
-            elif type == self.PEVT_RESOURCE:
-                self.fValueString = self.RESOURCE_VALUE_STR % (valueList[0], valueList[1])
-            else:
-                self.fValueString = valueList[0]
-
-    def addVariable(self, item):
-        if item != None:
-            self.fVariables.append(item)
-
-        return self.fVariables
-
-    def setParent(self, parent):
-        if self.fVariables != None and len(self.fVariables) > 0:
-            for item in self.fVariables:
-                item.setParent(parent)
-
-    def getReferenceType(self):
-        return self.fValueType
-
-    def getReferenceTypeName(self):
-        return self.PEV_NAMES[self.fValueType]
-
-    def setReferenceType(self, type):
-        self.fValueType = type
-
-    def getValueString(self):
-        return self.fValueString
-
-    def getChildrenVariables(self):
-        return self.fVariables
-
-    def hasVariables(self):
-        return len(self.fVariables) > 0
-
-    def childrenIsSortable(self):
-        #
-        # TODO: if self.fValueType != self.PEVT_ARRAY:
-        #
-        return True
-
-
-class PHPVariable(object):
-    def __init__(self, frame, parent, valueType, name, valueList):
-        self.fStackFrame = frame
-        self.fName       = None
-        self.fLongName   = None
-        self.fPureName   = None
-        self.fValue      = PHPValue(frame, valueType, valueList)
-        self.fParent     = parent
-        self.setName(name)
-        self.setChildrensParent(valueList)
-
-    def setName(self, name):
-        self.fPureName = name
-
-        type = self.getReferenceType()
-        if type == PHPValue.PEVT_ARRAY:
-            numItems = len(self.getChildrenVariables())
-            self.fName = name + "[" + str(numItems) + "]"
-        else:
-            self.fName = name
-
-        if not self.fParent or self.fParent.getName() == None:
-            self.fLongName = name
-        else:
-            self.setLongName()
-
-        return
-
-    def setLongName(self):
-        parentType = self.fParent.getReferenceType()
-        if parentType == PHPValue.PEVT_ARRAY:
-            self.fLongName = self.fParent.getLongName() + "['" + self.fPureName + "']"
-        elif parentType == PHPValue.PEVT_OBJECT:
-            self.fLongName = self.fParent.getLongName() + "." + self.fName
-        else:
-            self.fLongName = self.fName
-
-        return
-
-    def getValue(self):
-        return self.fValue
-
-    def getValueString(self):
-        return self.fValue.getValueString()
-
-    def getChildrenVariables(self):
-        return self.fValue.getChildrenVariables()
-
-    def getName(self):
-        return self.fName
-
-    def getParent(self):
-        return self.fParent
-
-    def setParent(self, parent):
-        self.fParent = parent
-        self.setLongName()
-        return
-
-    def setChildrensParent(self, childrenList):
-        if self.fValue.hasVariables():
-            for child in self.fValue.getChildrenVariables():
-                child.setParent(self)
-
-    def getLongName(self):
-        return self.fLongName
-
-    def getReferenceTypeName(self):
-        return self.fValue.getReferenceTypeName()
-
-    def getReferenceType(self):
-        return self.fValue.getReferenceType()
-
-    def setReferenceType(self, type):
-        tp = self.getValue.setReferenceType(type)
-        return tp
-
-    def setValue(self, expression):
-        if self.fValue.getReferenceType() == PHPValue.PEVT_STRING:
-            evalString = self.fLongName + "=\"" + expression + "\""
-        else:
-            evalString = self.fLongName + "=" + expression
-
-        vars = self.fStackFrame.getPHPDBGInterface().evalBlock(self.fStackFrame, evalString)
-        self.fValue = vars[0].fValue
-
-    def toString(self):
-        rtype = self.getReferenceType()
-        if rtype == PHPValue.PEVT_ARRAY:
-            elements = len(self.fValue.getChildrenVariables())
-            if elements == 0:
-                tmpStr = self.getName() + " [no elements]"
-            elif elements == 1:
-                tmpStr = self.getName() + " [1 element]"
-            else:
-                tmpStr = self.getName() + " [" + str(elements) + " elements]"
-        elif rtype == PHPValue.PEVT_OBJECT:
-            tmpStr = self.getName() + " [ class: " + self.fValue.getValueString() + "]"
-        elif rtype == PHPValue.PEVT_STRING:
-            tmpStr = self.getName() + " = \"" + self.fValue.getValueString() + "\""
-        else:
-            tmpStr = self.getName() + " = " + self.fValue.getValueString()
-
-        return tmpStr
-
-    def hasChildren(self):
-        return self.fValue.hasVariables()
-
-    def childrenIsSortable(self):
-        return self.fValue.childrenIsSortable()
-
-
-class PHPStackFrame(object):
-    def __init__(self, interface, file, line, frameIndex, scopeId, desc, modNum):
-        self.interface      = interface
-        self.fileName       = file
-        self.lineNo         = line
-        self.frameIndex     = frameIndex
-        self.scopeId        = scopeId
-        self.desc           = desc
-        self.modNum         = modNum
-        self.variables      = []
-        self.shortFileName  = None
-        self.shortDesc      = None
-        self.displayStr     = None
-        self.longDisplayStr = None
-
-        self._getFileNamesAndShortDesc()
-
-        myprint("PHPStackFrame::__init__(): new PHPStackFrame: file=%s, lineNo=%s, frameIndex=%s, scopeId=%s, desc=%s, modNum=%s, shortFileName=%s, shortDesc=%s", (repr(file), repr(line), repr(frameIndex), repr(scopeId), repr(desc), repr(modNum), repr(self.shortFileName), repr(self.shortDesc)))
-
-    def _getFileNamesAndShortDesc(self):
-        tmp = []
-        if self.desc:
-            tmp = self.desc.split("::")
-
-        if self.fileName:
-            self.shortFileName = os.path.basename(self.fileName)
-            if len(tmp) == 2:
-                self.shortDesc = tmp[1]
-            elif len(tmp) == 1:
-                self.shortDesc = tmp[0]
-            else:
-                self.shortDesc = None
-
-            return
-
-        #
-        # The fileName is None, we will try our best efforts to get it.
-        #
-        if len(tmp) == 2:
-            #
-            # We retrieved long finename from the description.  If we haven't
-            # stored the file mod before, set this one as the new one.
-            # Otherwise, we prefer to keep the stored one.
-            #
-            if self.modNum != 0:
-                storedFileName = self.interface.getModByNum(self.modNum)
-                if not storedFileName:
-                    self.interface.setMod(self.modNum, tmp[0])
-
-            self.fileName      = tmp[0]
-            self.shortFileName = os.path.basename(tmp[0])
-            self.shortDesc     = tmp[1]
-        elif len(tmp) == 1:
-            self.fileName      = None
-            self.shortFileName = None
-            self.shortDesc     = tmp[0]
-        else:
-            self.shortFileName = None
-            self.shortDesc     = None
-            myprint("PHPStackFrame::_getFileNamesAndShortDesc(): something wrong with desc: %s?", self.desc)
-
-        return
-
-    def getShortFileName(self):
-        return self.shortFileName
-
-    def setShortFileName(self, shortFileName):
-        self.shortFileName = shortFileName
-
-    def getShortDesc(self):
-        return self.shortDesc
-
-    def getLineNo(self):
-        return self.lineNo
-
-    def getInterface(self):
-        return self.interface
-
-    def getVariables(self):
-        if len(self.variables) == 0:
-            self.variables = self.interface.getVariables(self)
-
-        return self.variables
-
-    def findVariables(self, s):
-        if self.hasVariables():
-            name = "$" + s
-            for var in self.variables:
-                if var.getName() == name:
-                    return var
-
-        return None
-
-    def hasVariables(self):
-        if len(self.variables) == 0:
-            return False
-        else:
-            return True
-
-    def getName(self):
-        if self.getDesc():
-            return self.getDesc() + " [line: " + str(self.getLineNo()) + "]"
-        else:
-            return self.getFileName() + " [line: " + str(self.getLineNo()) + "]"
-
-    def getFileName(self):
-        return self.fileName
-
-    def setFileName(self, fileName):
-        self.fileName = fileName
-
-    def setDesc(self, desc):
-        self.desc = desc
-
-    def getDesc(self):
-        return self.desc
-
-    def getFrameScopeId(self):
-        return self.scopeId
-
-    def getFrameIndex(self):
-        return self.frameIndex
-
-    def getDisplayStr(self, stackList = None):
-        if self.displayStr:
-            return self.displayStr
-
-        if not self.shortFileName:
-            if stackList:
-                i = stackList.index(self)
-                for j in range(i + 1, len(stackList)):
-                    self.shortFileName = stackList[j].getShortFileName()
-                    if self.shortFileName:
-                        self.fileName = stackList[j].getFileName()
-
-        if self.shortFileName:
-            if self.shortDesc:
-                self.displayStr = "<%s> at %s:%d" % (self.shortDesc, self.shortFileName, self.lineNo)
-            else:
-                self.displayStr = "%s:%d" % (self.shortFileName, self.lineNo)
-        else:
-            if self.shortDesc:
-                self.displayStr = "<%s>" % self.shortDesc
-            else:
-                self.displayStr = "<internal stack error>"
-
-        return self.displayStr
-
-    def getLongDisplayStr(self):
-        if self.longDisplayStr:
-            return self.longDisplayStr
-
-        if self.fileName:
-            if self.shortDesc:
-                self.longDisplayStr = "<%s> at %s:%d" % (self.shortDesc, self.fileName, self.lineNo)
-            else:
-                self.longDisplayStr = "%s:%d" % (self.fileName, self.lineNo)
-        else:
-            if self.shortDesc:
-                self.longDisplayStr = "<%s>" % self.shortDesc
-            else:
-                self.longDisplayStr = "<internal stack error>"
-
-        return self.longDisplayStr
-
-class BreakPoint(object):
-    def __init__(self, interface, fileName, lineNo, modNum = 0, state = BPS_ENABLED + BPS_UNRESOLVED, isTemp = 0, hitCount = 0, skipHits = 0, condition = 0, bpId = 0, isUnderHit = 0):
-        self.interface  = interface
-        self.fileName   = fileName
-        self.lineNo     = lineNo
-        self.bpID       = bpId
-        self.state      = state
-        self.isTemp     = isTemp
-        self.hitCount   = hitCount
-        self.skipHits   = skipHits
-        self.condition  = condition
-        self.isUnderHit = 0
-        if modNum == 0:
-            self.modNum = self.interface.getModByFileName(fileName)
-        else:
-            self.modNum = modNum
-
-        if self.modNum:
-            self.fCounterOrZero = 0
-        else:
-            self.fCounterOrZero = interface.getNextFrameCounter()
-
-    def sendSelf(self):
-        reqPacket = PHPDBGPacket(DBGA_REQUEST)
-        reqFrame1 = PHPDBGFrame(FRAME_BPS)
-
-        if self.modNum:
-            reqFrame1.addInt(self.modNum)
-        else:
-            #
-            # 0 in modNum to tell to use fileName instead.
-            #
-            reqFrame1.addInt(0)
-
-        reqFrame1.addInt(self.lineNo)             # lineNo
-        reqFrame1.addInt(self.fCounterOrZero)     # fileName frameCounter or 0
-        reqFrame1.addInt(self.state)              # state
-        reqFrame1.addInt(self.isTemp)             # isTemp
-        reqFrame1.addInt(self.hitCount)           # hitCount
-        reqFrame1.addInt(self.skipHits)           # skipHits
-        reqFrame1.addInt(self.condition)          # condition
-        reqFrame1.addInt(self.bpID)               # breakpoint sequence id
-        reqFrame1.addInt(self.isUnderHit)         # isUnderHit
-
-        if not self.modNum:
-            reqFrame2 = PHPDBGFrame(FRAME_RAWDATA)
-            reqFrame2.addInt(self.fCounterOrZero)
-            reqFrame2.addInt(len(self.fileName) + 1)
-            reqFrame2.addStr(self.fileName)
-            reqPacket.addFrame(reqFrame2)
-
-        reqPacket.addFrame(reqFrame1)
-
-        try:
-            reqPacket.sendPacket(self.interface.lsnrThr)
-            self.interface.awaitAndHandleResponse()
-        except PHPDBGConnException:
-            self.interface.currConnFinished()
-
-        return
-
-    def addSelf(self):
-        self.sendSelf()
-
-    def removeSelf(self):
-        self.state = BPS_DISABLED
-        self.sendSelf()
-
-    def isUnderHit(self):
-        return self.isUnderHit == 1
-
-    def update(self, dbgBp):
-        self.modNum     = dbgBp[0]
-        self.state      = dbgBp[3]
-        self.isTemp     = dbgBp[4]
-        self.hitCount   = dbgBp[5]
-        self.skipHits   = dbgBp[6]
-        self.condition  = dbgBp[7]
-        self.bpID       = dbgBp[8]
-        self.isUnderHit = dbgBp[9]
-
-
-class PHPDBGEvalString(object):
-    def __init__(self, stackFrame, dataStr):
-        self.stackFrame = stackFrame
-        self.dataStr    = dataStr
-
-    #
-    # Get a list of variables under self.stackFrame.
-    #
-    def getVars(self):
-        return self.parseAVariable(isRealVar = False)
-
-    #
-    # if isRealVar:
-    #    returnList[0] = The Variable
-    # else:
-    #    returnList    = list of variables.
-    #
-    def parseAVariable(self, isRealVar = True):
-        returnList = []
-
-        #
-        # Get the variable name first.  Notice we ignore this entity's data
-        # type here.
-        #
-        if isRealVar:
-            nameEntity = self.parseAnEntity()
-            if not nameEntity or len(nameEntity) != 2 or type(nameEntity[1]) != str:
-                myprint("PHPDBGEvalStr::parseAVariable() got a wrong name entity")
-                return returnList
-            else:
-                varName = nameEntity[1]
-
-        #
-        # Get the variable's value.
-        #
-        valueEntity = self.parseAnEntity()
-        if not valueEntity or len(valueEntity) < 1:
-            myprint("PHPDBGEvalStr::parseAVariable(): couldn't get a variable's value entity.")
-            return returnList
-
-        #
-        # This variable's data type.
-        #
-        varType = valueEntity[0]
-
-        if isRealVar:
-            #
-            # If this is a real variable, return a list which contains only
-            # this variable item.
-            #
-            #valueEntity = valueEntity[1:]
-            variable    = PHPVariable(self.stackFrame, None, varType, varName, valueEntity[1:])
-            #myprint("xxxxCreated variable varName=%s, valueEntity=%s", (repr(varName), repr(valueEntity[1])))
-            myprint("xxxxCreated variable: %s", repr(variable.toString()))
-            returnList.append(variable)
-        else:
-            #
-            # If this is a root variable container, returns a list of
-            # variables under the root.  Do a sanity check here.
-            #
-            if valueEntity[0] != PHPValue.PEVT_ARRAY:
-                myprint("PHPDBGEvalStr::parseAVariable(): failed to parse the root variable container.")
-            else:
-                returnList = valueEntity[1:]
-
-        return returnList
-
-    #
-    # An entity could be a variable's name or its value.
-    #
-    # returnList[0]  = variable data type
-    # returnList[1:] = the real list
-    #
-    def parseAnEntity(self):
-        if not self.dataStr or len(self.dataStr) < 2  or (self.dataStr[1] != ':' and self.dataStr[1] != ';'):
-            myprint("PHPDBGEvalStr::parseAnEntity(): failed to parse %s.", repr(self.dataStr))
-            return None
-
-        returnList    = []
-        typeChar      = self.dataStr[0]
-        self.dataStr  = self.dataStr[2:]
-        if typeChar   == 'i':
-            returnList.append(PHPValue.PEVT_LONG)
-            self.parseInt(returnList)
-        elif typeChar == 'a':
-            returnList.append(PHPValue.PEVT_ARRAY)
-            self.parseArray(returnList)
-        elif typeChar == 's':
-            returnList.append(PHPValue.PEVT_STRING)
-            self.parseString(returnList)
-        elif typeChar == 'O':
-            returnList.append(PHPValue.PEVT_OBJECT)
-            self.parseObject(returnList)
-        elif typeChar == 'r':
-            returnList.append(PHPValue.PEVT_SOFTREF)
-            self.parseReference(returnList, isSoftRef = True)
-        elif typeChar == 'R':
-            returnList.append(PHPValue.PEVT_REF)
-            self.parseReference(returnList, isSoftRef = False)
-        elif typeChar == 'b':
-            returnList.append(PHPValue.PEVT_BOOLEAN)
-            self.parseBoolean(returnList)
-        elif typeChar == 'd':
-            returnList.append(PHPValue.PEVT_DOUBLE)
-            self.parseDouble(returnList)
-        elif typeChar == 'z':
-            returnList.append(PHPValue.PEVT_RESOURCE)
-            self.parseResource(returnList)
-        elif typeChar == 'N':
-            returnList.append(PHPValue.PEVT_NULL)
-            self.parseNull(returnList)
-        else:
-            myprint("PHPDBGEvalStr::parseAnEntity(): unknown data type: %s", typeChar)
-
-        return returnList
-
-    def parseInt(self, returnList):
-        myprint("enter parseInt().")
-        returnList.append(self.getAnIntStr(';'))
-
-        return
-
-    def parseArray(self, returnList):
-        myprint("enter parseArray().")
-        #
-        # The shortest array is 'a:0:{}'.
-        #
-        if len(self.dataStr) < 4:
-            myprint("PHPDBGEvalStr::parseArray(): failed (1) to parse an array: %s.", repr(self.dataStr))
-            return
-
-        expectedNumItems = self.getAnInt(':')
-        if len(self.dataStr) < 2 or self.dataStr[0] != '{':
-            myprint("PHPDBGEvalStr::parseArray(): failed (3) to parse an array: %s.", repr(self.dataStr))
-            return
-
-        self.dataStr = self.dataStr[1:]
-        varList      = []
-        while self.dataStr and len(self.dataStr) > 0 and self.dataStr[0] != '}':
-            tmpList = self.parseAVariable()
-            if not tmpList or len(tmpList) != 1 or not tmpList[0]:
-                myprint("PHPDBGEvalStr::parseArray(): failed (4) to parse an array.  dataStr=%s.", repr(self.dataStr))
-                break
-            else:
-                varList.append(tmpList[0])
-
-        if expectedNumItems != len(varList):
-            myprint("PHPDBGEvalStr::parseArray(): failed (5) expected no. of items=%d, but got %d", (expectedNumItems, len(varList)))
-
-        #
-        # An array should end with a '}'.
-        #
-        if self.dataStr and len(self.dataStr) > 0 and self.dataStr[0] == '}':
-            self.dataStr = self.dataStr[1:]
-            returnList.extend(varList)
-        else:
-            myprint("PHPDBGEvalStr::parseArray(): failed (6) to parse an array.  dataStr=%s.", repr(self.dataStr))
-
-        myprint("parseArray() ends.")
-        return
-
-    def parseString(self, returnList, endChar = ';'):
-        myprint("enter parseString().")
-        #
-        # The shortest string is 's:<str_len>:"<str>"<endChar>'.
-        #
-        if len(self.dataStr) < 5:
-            myprint("PHPDBGEvalStr::parseString(): failed (1) to parse a string.  dataStr=%s.", repr(self.dataStr))
-            return
-
-        expectedStrLen = self.getAnInt(':')
-        if len(self.dataStr) < expectedStrLen + 3 or self.dataStr[0] != '"':
-            myprint("PHPDBGEvalStr::parseString(): failed (3) to parse a string.  dataStr=%s.", repr(self.dataStr))
-            return
-
-        strValue = self.dataStr[1:expectedStrLen + 1]
-        if self.dataStr[expectedStrLen + 1:expectedStrLen + 3] != '"' + endChar:
-            myprint("PHPDBGEvalStr::parseString(): failed (4) to parse a string.  dataStr=%s.", repr(self.dataStr))
-            return
-
-        #
-        # Skip the starting double quote, real string, ending double quote, and ending semicolon.
-        #
-        self.dataStr = self.dataStr[expectedStrLen + 3:]
-        returnList.append(strValue)
-
-        return
-
-    def parseObject(self, returnList):
-        #
-        # A simple sanity check.  The shortest object is:
-        # 'O:<class_name_len>:"<class_name>":<num_of_items>:{<list_of_items>}'
-        #
-        if not self.dataStr or len(self.dataStr) < 10:
-            myprint("PHPDBGEvalStr::parseObject(): failed (1) to parse an object: %s.", repr(self.dataStr))
-
-        #
-        # Get the class name in classNameList[0].
-        #
-        classNameList = []
-        self.parseString(classNameList, ':')
-
-        expectedNumItems = self.getAnInt(':')
-        if len(self.dataStr) < 2 or self.dataStr[0] != '{':
-            myprint("PHPDBGEvalStr::parseObject(): failed (2) to parse an object: %s.", repr(self.dataStr))
-            return
-
-        self.dataStr = self.dataStr[1:]
-        varList      = []
-        while self.dataStr and len(self.dataStr) > 0 and self.dataStr[0] != '}':
-            tmpList = self.parseAVariable()
-            if not tmpList or len(tmpList) != 1 or not tmpList[0]:
-                myprint("PHPDBGEvalStr::parseObject(): failed (3) to parse an object.  dataStr=%s.", repr(self.dataStr))
-                break
-            else:
-                varList.append(tmpList[0])
-
-        if expectedNumItems != len(varList):
-            myprint("PHPDBGEvalStr::parseObject(): failed (4) expected no. of items=%d, but got %d", (expectedNumItems, len(varList)))
-
-        #
-        # An object should end with a '}'.
-        #
-        if self.dataStr and len(self.dataStr) > 0 and self.dataStr[0] == '}':
-            self.dataStr = self.dataStr[1:]
-            returnList.append(classNameList[0])
-            returnList.extend(varList)
-        else:
-            myprint("PHPDBGEvalStr::parseObject(): failed (6) to parse an object.  dataStr=%s.", repr(self.dataStr))
-
-        myprint("parseObject() ends.")
-        return
-
-    def parseReference(self, returnList, isSoftRef):
-        myprint("enter parseReference().")
-        intStr = self.getAnIntStr(';')
-        if intStr:
-            returnList.append(intStr)
-
-        return
-
-    def parseBoolean(self, returnList):
-        tmpBooleanStr = self.getAnIntStr(';')
-        returnList.append(tmpBooleanStr)
-
-        return
-
-    def parseDouble(self, returnList):
-        tmpStr = self.getAStrTillEndChar(';')
-        if tmpStr:
-            returnList.append(tmpStr)
-
-        return
-
-    def parseResource(self, returnList):
-        tmpList = []
-        self.parseString(tmpList, ':')
-
-        if len(tmpList) == 1:
-            returnList.extend(tmpList)
-        else:
-            return
-
-        resourceId = self.getAnIntStr(';')
-        if resourceId:
-            returnList.append(resourceId)
-
-        return
-
-    def parseNull(self, returnList):
-        return
-
-    def getAStrTillEndChar(self, endChar):
-        if len(self.dataStr) < 1:
-            myprint("PHPDBGEvalStr::getAStrTillEndChar(): no more data string to work with.")
-            return
-
-        i = self.findNextChar(self.dataStr, endChar)
-        if i == -1:
-            myprint("PHPDBGEvalStr::getAStrTillEndChar(): no double/float string supplied.")
-            return
-
-        tmpStr       = self.dataStr[:i]
-        self.dataStr = self.dataStr[i + 1:]
-
-        if self.isFloat(tmpStr):
-            return tmpStr
-        else:
-            myprint("PHPDBGEvalStr::getAStrTillEndChar(): parsing error.  tried to get an float number, but get %s.", tmpStr)
-            return None
-
-    def getAnInt(self, endChar):
-        tmpStr = self.getAnIntStr(endChar)
-        if tmpStr:
-            return int(tmpStr)
-        else:
-            return 0
-
-    def getAnIntStr(self, endChar):
-        if len(self.dataStr) == 0:
-            myprint("PHPDBGEvalStr::getAnIntStr(): no more data string to work with.")
-            return
-
-        i = self.findNextChar(self.dataStr, endChar)
-        if i == -1:
-            tmpStr = self.dataStr
-            self.dataStr = ''
-        else:
-            tmpStr = self.dataStr[:i]
-            self.dataStr = self.dataStr[i + 1:]
-
-        if self.isInt(tmpStr):
-            return tmpStr
-        else:
-            myprint("PHPDBGEvalStr::getAnIntStr(): parsing error.  tried to get an integer, but get %s.", tmpStr)
-            return None
-
-    def isInt(self, aStr):
-        try:
-            int(aStr)
-        except ValueError:
-            return False
-
-        return True
-
-    def isFloat(self, aStr):
-        try:
-            float(aStr)
-        except ValueError:
-            return False
-
-        return True
-
-    def findNextChar(self, aStr, aChar):
-        try:
-            index = aStr.index(aChar)
-        except ValueError:
-            index = -1
-
-        return index