Continued modernizing the debugger interface. jsonrpc

Thu, 01 Sep 2016 19:00:46 +0200

author
Detlev Offenbach <detlev@die-offenbachs.de>
date
Thu, 01 Sep 2016 19:00:46 +0200
branch
jsonrpc
changeset 5124
1ba8ee313b57
parent 5123
d07dd3cf0dc3
child 5125
eb1b3e0577e4

Continued modernizing the debugger interface.

DebugClients/Python3/DebugBase.py file | annotate | diff | comparison | revisions
DebugClients/Python3/DebugClientBase.py file | annotate | diff | comparison | revisions
Debugger/DebugServer.py file | annotate | diff | comparison | revisions
Debugger/DebugUI.py file | annotate | diff | comparison | revisions
Debugger/DebuggerInterfaceNone.py file | annotate | diff | comparison | revisions
Debugger/DebuggerInterfacePython3.py file | annotate | diff | comparison | revisions
--- a/DebugClients/Python3/DebugBase.py	Thu Sep 01 18:28:27 2016 +0200
+++ b/DebugClients/Python3/DebugBase.py	Thu Sep 01 19:00:46 2016 +0200
@@ -15,8 +15,6 @@
 import ctypes
 from inspect import CO_GENERATOR
 
-from DebugProtocol import ResponseClearWatch, ResponseClearBreak, \
-    ResponseLine, ResponseSyntax, ResponseException, CallTrace
 from DebugUtilities import getargvalues, formatargvalues
 
 gRecursionLimit = 64
@@ -210,8 +208,7 @@
                         self._dbgClient.absPath(self.fix_frame_filename(fr)),
                         fr.f_lineno,
                         fr.f_code.co_name)
-                    self._dbgClient.write("{0}{1}@@{2}@@{3}\n".format(
-                        CallTrace, event[0], fromStr, toStr))
+                    self._dbgClient.sendCallTrace(event, fromStr, toStr)
     
     def trace_dispatch(self, frame, event, arg):
         """
@@ -445,7 +442,7 @@
         @param cond expression of the watch expression to be cleared (string)
         """
         self.clear_watch(cond)
-        self._dbgClient.write('{0}{1}\n'.format(ResponseClearWatch, cond))
+        self._dbgClient.sendClearTemporaryWatch(cond)
 
     def __effective(self, frame):
         """
@@ -582,8 +579,7 @@
         @param lineno linenumber of the bp
         """
         self.clear_break(filename, lineno)
-        self._dbgClient.write('{0}{1},{2:d}\n'.format(
-                              ResponseClearBreak, filename, lineno))
+        self._dbgClient.sendClearTemporaryBreakpoint(filename, lineno)
 
     def getStack(self):
         """
@@ -644,7 +640,9 @@
                 return
             fr = frame
             while (fr is not None and
-                    fr.f_code != self._dbgClient.handleLine.__code__):
+                   fr.f_code not in [
+                    self._dbgClient.handleLine.__code__,
+                    self._dbgClient.handleJsonCommand.__code__]):
                 self._dbgClient.mainFrame = fr
                 fr = fr.f_back
 
@@ -687,7 +685,7 @@
         
         self.__isBroken = True
         
-        self._dbgClient.write('{0}{1}\n'.format(ResponseLine, str(stack)))
+        self._dbgClient.sendResponseLine(stack)
         self._dbgClient.eventLoop()
 
     def user_exception(self, frame, excinfo, unhandled=False):
@@ -724,18 +722,19 @@
             try:
                 message = str(excval)
                 filename = excval.filename
-                linenr = excval.lineno
-                charnr = excval.offset
+                lineno = excval.lineno
+                charno = excval.offset
+                realSyntaxError = os.path.exists(filename)
             except (AttributeError, ValueError):
-                exclist = []
+                message = ""
+                filename = ""
+                lineno = 0
+                charno = 0
                 realSyntaxError = True
-            else:
-                exclist = [message, [filename, linenr, charnr]]
-                realSyntaxError = os.path.exists(filename)
             
             if realSyntaxError:
-                self._dbgClient.write("{0}{1}\n".format(
-                    ResponseSyntax, str(exclist)))
+                self._dbgClient.sendSyntaxError(
+                    message, filename, lineno, charno)
                 self._dbgClient.eventLoop()
                 return
         
@@ -748,11 +747,8 @@
             exctypetxt = "unhandled {0!s}".format(str(exctype))
         else:
             exctypetxt = str(exctype)
-        try:
-            exclist = [exctypetxt, str(excval)]
-        except TypeError:
-            exclist = [exctypetxt, str(excval)]
         
+        stack = []
         if exctb:
             frlist = self.__extract_stack(exctb)
             frlist.reverse()
@@ -783,10 +779,9 @@
                 else:
                     fargs = ""
                 
-                exclist.append([filename, linenr, ffunc, fargs])
+                stack.append([filename, linenr, ffunc, fargs])
         
-        self._dbgClient.write("{0}{1}\n".format(
-            ResponseException, str(exclist)))
+        self._dbgClient.sendException(exctypetxt, str(excval), stack)
         
         if exctb is None:
             return
--- a/DebugClients/Python3/DebugClientBase.py	Thu Sep 01 18:28:27 2016 +0200
+++ b/DebugClients/Python3/DebugClientBase.py	Thu Sep 01 19:00:46 2016 +0200
@@ -191,7 +191,7 @@
         self.pendingResponse = DebugProtocol.ResponseOK
         self._fncache = {}
         self.dircache = []
-        self.inRawMode = False
+##        self.inRawMode = False
         self.mainProcStr = None     # used for the passive mode
         self.passive = False        # used to indicate the passive mode
         self.running = None
@@ -302,8 +302,12 @@
                 d["broken"] = False
             threadList.append(d)
         
-        self.write("{0}{1!r}\n".format(DebugProtocol.ResponseThreadList,
-                                       (currentId, threadList)))
+##        self.write("{0}{1!r}\n".format(DebugProtocol.ResponseThreadList,
+##                                       (currentId, threadList)))
+        self.__sendJsonCommand("ResponseThreadList", {
+            "currentID": currentId,
+            "threadList": threadList,
+        })
     
     def input(self, prompt, echo=True):
         """
@@ -319,7 +323,7 @@
             "prompt": prompt,
             "echo": echo,
         })
-        self.inRawMode = True
+##        self.inRawMode = True
         self.eventLoop(True)
         return self.rawLine
 
@@ -329,7 +333,8 @@
         
         It ensures that the debug server is informed of the raised exception.
         """
-        self.pendingResponse = DebugProtocol.ResponseException
+##        self.pendingResponse = DebugProtocol.ResponseException
+        self.__sendJsonCommand("ResponseException", {})
     
     def sessionClose(self, exit=True):
         """
@@ -376,15 +381,14 @@
             try:
                 message = str(excval)
                 filename = excval.filename
-                linenr = excval.lineno
-                charnr = excval.offset
+                lineno = excval.lineno
+                charno = excval.offset
             except (AttributeError, ValueError):
-                exclist = []
-            else:
-                exclist = [message, [filename, linenr, charnr]]
-            
-            self.write("{0}{1}\n".format(
-                DebugProtocol.ResponseSyntax, str(exclist)))
+                message = ""
+                filename = ""
+                lineno = 0
+                charno = 0
+            self.sendSyntaxError(message, filename, lineno, charno)
             return None
         
         return code
@@ -405,7 +409,7 @@
 ##        printerr(line)          ##debug
         
         if "jsonrpc" in line:
-            return self.__handleJsonCommand(line)
+            return self.handleJsonCommand(line)
 
         eoc = line.find('<')
 
@@ -414,30 +418,30 @@
             cmd = line[:eoc + 1]
             arg = line[eoc + 1:]
             
-            if cmd == DebugProtocol.RequestVariables:
-                frmnr, scope, filter = eval(arg.replace("u'", "'"))
-                self.__dumpVariables(int(frmnr), int(scope), filter)
-                return
-            
-            if cmd == DebugProtocol.RequestVariable:
-                var, frmnr, scope, filter = eval(arg.replace("u'", "'"))
-                self.__dumpVariable(var, int(frmnr), int(scope), filter)
-                return
-            
-            if cmd == DebugProtocol.RequestThreadList:
-                self.__dumpThreadList()
-                return
-            
-            if cmd == DebugProtocol.RequestThreadSet:
-                tid = eval(arg)
-                if tid in self.threads:
-                    self.setCurrentThread(tid)
-                    self.write(DebugProtocol.ResponseThreadSet + '\n')
-                    stack = self.currentThread.getStack()
-                    self.write('{0}{1!r}\n'.format(
-                        DebugProtocol.ResponseStack, stack))
-                return
-            
+##            if cmd == DebugProtocol.RequestVariables:
+##                frmnr, scope, filter = eval(arg.replace("u'", "'"))
+##                self.__dumpVariables(int(frmnr), int(scope), filter)
+##                return
+##            
+##            if cmd == DebugProtocol.RequestVariable:
+##                var, frmnr, scope, filter = eval(arg.replace("u'", "'"))
+##                self.__dumpVariable(var, int(frmnr), int(scope), filter)
+##                return
+##            
+##            if cmd == DebugProtocol.RequestThreadList:
+##                self.__dumpThreadList()
+##                return
+##            
+##            if cmd == DebugProtocol.RequestThreadSet:
+##                tid = eval(arg)
+##                if tid in self.threads:
+##                    self.setCurrentThread(tid)
+##                    self.write(DebugProtocol.ResponseThreadSet + '\n')
+##                    stack = self.currentThread.getStack()
+##                    self.write('{0}{1!r}\n'.format(
+##                        DebugProtocol.ResponseStack, stack))
+##                return
+##            
 ##            if cmd == DebugProtocol.RequestStep:
 ##                self.currentThread.step(True)
 ##                self.eventExit = True
@@ -472,18 +476,18 @@
 ##                self.pendingResponse = DebugProtocol.ResponseOK
 ##                return
 ##
-            if cmd == DebugProtocol.RequestCallTrace:
-                if arg.strip().lower() == "on":
-                    callTraceEnabled = True
-                else:
-                    callTraceEnabled = False
-                if self.debugging:
-                    self.callTraceEnabled = callTraceEnabled
-                else:
-                    self.__newCallTraceEnabled = callTraceEnabled
-                    # remember for later
-                return
-            
+##            if cmd == DebugProtocol.RequestCallTrace:
+##                if arg.strip().lower() == "on":
+##                    callTraceEnabled = True
+##                else:
+##                    callTraceEnabled = False
+##                if self.debugging:
+##                    self.callTraceEnabled = callTraceEnabled
+##                else:
+##                    self.__newCallTraceEnabled = callTraceEnabled
+##                    # remember for later
+##                return
+##            
 ##            if cmd == DebugProtocol.RequestEnv:
 ##                env = eval(arg.replace("u'", "'"))
 ##                for key, value in env.items():
@@ -676,168 +680,168 @@
 ##                    self.writestream.flush()
 ##                    self.progTerminated(res)
 ##                return
-
-            if cmd == DebugProtocol.RequestShutdown:
-                self.sessionClose()
-                return
-            
-            if cmd == DebugProtocol.RequestBreak:
-                fn, line, temporary, set, cond = arg.split('@@')
-                line = int(line)
-                set = int(set)
-                temporary = int(temporary)
-
-                if set:
-                    if cond == 'None' or cond == '':
-                        cond = None
-                    else:
-                        try:
-                            compile(cond, '<string>', 'eval')
-                        except SyntaxError:
-                            self.write('{0}{1},{2:d}\n'.format(
-                                       DebugProtocol.ResponseBPConditionError,
-                                       fn, line))
-                            return
-                    self.mainThread.set_break(fn, line, temporary, cond)
-                else:
-                    self.mainThread.clear_break(fn, line)
-
-                return
-            
-            if cmd == DebugProtocol.RequestBreakEnable:
-                fn, line, enable = arg.split(',')
-                line = int(line)
-                enable = int(enable)
-                
-                bp = self.mainThread.get_break(fn, line)
-                if bp is not None:
-                    if enable:
-                        bp.enable()
-                    else:
-                        bp.disable()
-                
-                return
-            
-            if cmd == DebugProtocol.RequestBreakIgnore:
-                fn, line, count = arg.split(',')
-                line = int(line)
-                count = int(count)
-                
-                bp = self.mainThread.get_break(fn, line)
-                if bp is not None:
-                    bp.ignore = count
-                
-                return
-            
-            if cmd == DebugProtocol.RequestWatch:
-                cond, temporary, set = arg.split('@@')
-                set = int(set)
-                temporary = int(temporary)
-
-                if set:
-                    if not cond.endswith('??created??') and \
-                       not cond.endswith('??changed??'):
-                        try:
-                            compile(cond, '<string>', 'eval')
-                        except SyntaxError:
-                            self.write('{0}{1}\n'.format(
-                                DebugProtocol.ResponseWPConditionError, cond))
-                            return
-                    self.mainThread.set_watch(cond, temporary)
-                else:
-                    self.mainThread.clear_watch(cond)
-
-                return
-            
-            if cmd == DebugProtocol.RequestWatchEnable:
-                cond, enable = arg.split(',')
-                enable = int(enable)
-                
-                bp = self.mainThread.get_watch(cond)
-                if bp is not None:
-                    if enable:
-                        bp.enable()
-                    else:
-                        bp.disable()
-                
-                return
-            
-            if cmd == DebugProtocol.RequestWatchIgnore:
-                cond, count = arg.split(',')
-                count = int(count)
-                
-                bp = self.mainThread.get_watch(cond)
-                if bp is not None:
-                    bp.ignore = count
-                
-                return
-            
-            if cmd == DebugProtocol.RequestEval:
-                try:
-                    value = eval(
-                        arg,
-                        self.currentThread.getCurrentFrame().f_globals,
-                        self.currentThread.getFrameLocals(self.framenr))
-                    self.currentThread.storeFrameLocals(self.framenr)
-                except Exception:
-                    # Report the exception and the traceback
-                    try:
-                        type, value, tb = sys.exc_info()
-                        sys.last_type = type
-                        sys.last_value = value
-                        sys.last_traceback = tb
-                        tblist = traceback.extract_tb(tb)
-                        del tblist[:1]
-                        list = traceback.format_list(tblist)
-                        if list:
-                            list.insert(0, "Traceback (innermost last):\n")
-                            list[len(list):] = \
-                                traceback.format_exception_only(type, value)
-                    finally:
-                        tblist = tb = None
-
-                    for l in list:
-                        self.write(l)
-
-                    self.write(DebugProtocol.ResponseException + '\n')
-                
-                else:
-                    self.write(str(value) + '\n')
-                    self.write(DebugProtocol.ResponseOK + '\n')
-                
-                return
-            
-            if cmd == DebugProtocol.RequestExec:
-                _globals = self.currentThread.getCurrentFrame().f_globals
-                _locals = self.currentThread.getFrameLocals(self.framenr)
-                try:
-                    code = compile(arg + '\n', '<stdin>', 'single')
-                    exec(code, _globals, _locals)
-                    self.currentThread.storeFrameLocals(self.framenr)
-                except Exception:
-                    # Report the exception and the traceback
-                    try:
-                        type, value, tb = sys.exc_info()
-                        sys.last_type = type
-                        sys.last_value = value
-                        sys.last_traceback = tb
-                        tblist = traceback.extract_tb(tb)
-                        del tblist[:1]
-                        list = traceback.format_list(tblist)
-                        if list:
-                            list.insert(0, "Traceback (innermost last):\n")
-                            list[len(list):] = \
-                                traceback.format_exception_only(type, value)
-                    finally:
-                        tblist = tb = None
-
-                    for l in list:
-                        self.write(l)
-
-                    self.write(DebugProtocol.ResponseException + '\n')
-                
-                return
-            
+##
+##            if cmd == DebugProtocol.RequestShutdown:
+##                self.sessionClose()
+##                return
+##            
+##            if cmd == DebugProtocol.RequestBreak:
+##                fn, line, temporary, set, cond = arg.split('@@')
+##                line = int(line)
+##                set = int(set)
+##                temporary = int(temporary)
+##
+##                if set:
+##                    if cond == 'None' or cond == '':
+##                        cond = None
+##                    else:
+##                        try:
+##                            compile(cond, '<string>', 'eval')
+##                        except SyntaxError:
+##                            self.write('{0}{1},{2:d}\n'.format(
+##                                       DebugProtocol.ResponseBPConditionError,
+##                                       fn, line))
+##                            return
+##                    self.mainThread.set_break(fn, line, temporary, cond)
+##                else:
+##                    self.mainThread.clear_break(fn, line)
+##
+##                return
+##            
+##            if cmd == DebugProtocol.RequestBreakEnable:
+##                fn, line, enable = arg.split(',')
+##                line = int(line)
+##                enable = int(enable)
+##                
+##                bp = self.mainThread.get_break(fn, line)
+##                if bp is not None:
+##                    if enable:
+##                        bp.enable()
+##                    else:
+##                        bp.disable()
+##                
+##                return
+##            
+##            if cmd == DebugProtocol.RequestBreakIgnore:
+##                fn, line, count = arg.split(',')
+##                line = int(line)
+##                count = int(count)
+##                
+##                bp = self.mainThread.get_break(fn, line)
+##                if bp is not None:
+##                    bp.ignore = count
+##                
+##                return
+##            
+##            if cmd == DebugProtocol.RequestWatch:
+##                cond, temporary, set = arg.split('@@')
+##                set = int(set)
+##                temporary = int(temporary)
+##
+##                if set:
+##                    if not cond.endswith('??created??') and \
+##                       not cond.endswith('??changed??'):
+##                        try:
+##                            compile(cond, '<string>', 'eval')
+##                        except SyntaxError:
+##                            self.write('{0}{1}\n'.format(
+##                                DebugProtocol.ResponseWPConditionError, cond))
+##                            return
+##                    self.mainThread.set_watch(cond, temporary)
+##                else:
+##                    self.mainThread.clear_watch(cond)
+##
+##                return
+##            
+##            if cmd == DebugProtocol.RequestWatchEnable:
+##                cond, enable = arg.split(',')
+##                enable = int(enable)
+##                
+##                bp = self.mainThread.get_watch(cond)
+##                if bp is not None:
+##                    if enable:
+##                        bp.enable()
+##                    else:
+##                        bp.disable()
+##                
+##                return
+##            
+##            if cmd == DebugProtocol.RequestWatchIgnore:
+##                cond, count = arg.split(',')
+##                count = int(count)
+##                
+##                bp = self.mainThread.get_watch(cond)
+##                if bp is not None:
+##                    bp.ignore = count
+##                
+##                return
+##            
+##            if cmd == DebugProtocol.RequestEval:
+##                try:
+##                    value = eval(
+##                        arg,
+##                        self.currentThread.getCurrentFrame().f_globals,
+##                        self.currentThread.getFrameLocals(self.framenr))
+##                    self.currentThread.storeFrameLocals(self.framenr)
+##                except Exception:
+##                    # Report the exception and the traceback
+##                    try:
+##                        type, value, tb = sys.exc_info()
+##                        sys.last_type = type
+##                        sys.last_value = value
+##                        sys.last_traceback = tb
+##                        tblist = traceback.extract_tb(tb)
+##                        del tblist[:1]
+##                        list = traceback.format_list(tblist)
+##                        if list:
+##                            list.insert(0, "Traceback (innermost last):\n")
+##                            list[len(list):] = \
+##                                traceback.format_exception_only(type, value)
+##                    finally:
+##                        tblist = tb = None
+##
+##                    for l in list:
+##                        self.write(l)
+##
+##                    self.write(DebugProtocol.ResponseException + '\n')
+##                
+##                else:
+##                    self.write(str(value) + '\n')
+##                    self.write(DebugProtocol.ResponseOK + '\n')
+##                
+##                return
+##            
+##            if cmd == DebugProtocol.RequestExec:
+##                _globals = self.currentThread.getCurrentFrame().f_globals
+##                _locals = self.currentThread.getFrameLocals(self.framenr)
+##                try:
+##                    code = compile(arg + '\n', '<stdin>', 'single')
+##                    exec(code, _globals, _locals)
+##                    self.currentThread.storeFrameLocals(self.framenr)
+##                except Exception:
+##                    # Report the exception and the traceback
+##                    try:
+##                        type, value, tb = sys.exc_info()
+##                        sys.last_type = type
+##                        sys.last_value = value
+##                        sys.last_traceback = tb
+##                        tblist = traceback.extract_tb(tb)
+##                        del tblist[:1]
+##                        list = traceback.format_list(tblist)
+##                        if list:
+##                            list.insert(0, "Traceback (innermost last):\n")
+##                            list[len(list):] = \
+##                                traceback.format_exception_only(type, value)
+##                    finally:
+##                        tblist = tb = None
+##
+##                    for l in list:
+##                        self.write(l)
+##
+##                    self.write(DebugProtocol.ResponseException + '\n')
+##                
+##                return
+##            
 ##            if cmd == DebugProtocol.RequestBanner:
 ##                self.write('{0}{1}\n'.format(DebugProtocol.ResponseBanner,
 ##                           str(("Python {0}".format(sys.version),
@@ -850,15 +854,15 @@
 ##                    self.__clientCapabilities()))
 ##                return
 ##            
-            if cmd == DebugProtocol.RequestCompletion:
-                self.__completionList(arg.replace("u'", "'"))
-                return
-            
-            if cmd == DebugProtocol.RequestSetFilter:
-                scope, filterString = eval(arg.replace("u'", "'"))
-                self.__generateFilterObjects(int(scope), filterString)
-                return
-            
+##            if cmd == DebugProtocol.RequestCompletion:
+##                self.__completionList(arg.replace("u'", "'"))
+##                return
+##            
+##            if cmd == DebugProtocol.RequestSetFilter:
+##                scope, filterString = eval(arg.replace("u'", "'"))
+##                self.__generateFilterObjects(int(scope), filterString)
+##                return
+##            
             if cmd == DebugProtocol.RequestUTPrepare:
                 fn, tn, tfn, failed, cov, covname, erase = arg.split('|')
                 sys.path.insert(0, os.path.dirname(os.path.abspath(fn)))
@@ -1024,9 +1028,9 @@
 ##                    for l in list:
 ##                        self.write(l)
     
-    def __handleJsonCommand(self, jsonStr):
+    def handleJsonCommand(self, jsonStr):
         """
-        Private method to handle a command serialized as a JSON string.
+        Public method to handle a command serialized as a JSON string.
         """
         import json
         
@@ -1039,6 +1043,31 @@
         method = commandDict["method"]
         params = commandDict["params"]
         
+        if method == "RequestVariables":
+            self.__dumpVariables(
+                params["frameNumber"], params["scope"], params["filters"])
+            return
+        
+        if method == "RequestVariable":
+            self.__dumpVariable(
+                params["variable"], params["frameNumber"],
+                params["scope"], params["filters"])
+            return
+        
+        if method == "RequestThreadList":
+            self.__dumpThreadList()
+            return
+        
+        if method == "RequestThreadSet":
+            if params["threadID"] in self.threads:
+                self.setCurrentThread(params["threadID"])
+                self.__sendJsonCommand("ResponseThreadSet", {})
+                stack = self.currentThread.getStack()
+                self.__sendJsonCommand("ResponseStack", {
+                    "stack": stack,
+                })
+            return
+        
         if method == "RequestCapabilities":
             self.__sendJsonCommand("ResponseCapabilities", {
                 "capabilities": self.__clientCapabilities(),
@@ -1054,6 +1083,18 @@
             })
             return
         
+        if method == "RequestSetFilter":
+            self.__generateFilterObjects(params["scope"], params["filter"])
+            return
+        
+        if method == "RequestCallTrace":
+            if self.debugging:
+                self.callTraceEnabled = params["enable"]
+            else:
+                self.__newCallTraceEnabled = params["enable"]
+                # remember for later
+            return
+        
         if method == "RequestEnvironment":
             for key, value in params["environment"].items():
                 if key.endswith("+"):
@@ -1080,7 +1121,7 @@
             
             self.running = sys.argv[0]
             self.mainFrame = None
-            self.inRawMode = False
+##            self.inRawMode = False
             self.debugging = True
             
             self.fork_auto = params["autofork"]
@@ -1124,7 +1165,7 @@
             self.running = sys.argv[0]
             self.mainFrame = None
             self.botframe = None
-            self.inRawMode = False
+##            self.inRawMode = False
             
             self.fork_auto = params["autofork"]
             self.fork_child = params["forkChild"]
@@ -1367,14 +1408,87 @@
             return
         
         if method == "RawInput":
-            # If we are handling raw mode input then reset the mode and break out
-            # of the current event loop.
-##        if self.inRawMode:
-##            self.inRawMode = False
+            # If we are handling raw mode input then break out of the current
+            # event loop.
             self.rawLine = params["input"]
             self.eventExit = True
             return
+        
+        if method == "RequestBreakpoint":
+            if params["setBreakpoint"]:
+                if params["condition"] in ['None', '']:
+                    params["condition"] = None
+                elif params["condition"] is not None:
+                    try:
+                        compile(params["condition"], '<string>', 'eval')
+                    except SyntaxError:
+                        self.__sendJsonCommand("ResponseBPConditionError", {
+                            "filename": params["filename"],
+                            "line": params["line"],
+                        })
+                        return
+                self.mainThread.set_break(
+                    params["filename"], params["line"], params["temporary"],
+                    params["condition"])
+            else:
+                self.mainThread.clear_break(params["filename"], params["line"])
 
+            return
+        
+        if method == "RequestBreakpointEnable":
+            bp = self.mainThread.get_break(params["filename"], params["line"])
+            if bp is not None:
+                if params["enable"]:
+                    bp.enable()
+                else:
+                    bp.disable()
+            return
+        
+        if method == "RequestBreakpointIgnore":
+            bp = self.mainThread.get_break(params["filename"], params["line"])
+            if bp is not None:
+                bp.ignore = params["count"]
+            return
+        
+        if method == "RequestWatch":
+            if params["setWatch"]:
+                if not params["condition"].endswith(
+                        ('??created??', '??changed??')):
+                    try:
+                        compile(params["condition"], '<string>', 'eval')
+                    except SyntaxError:
+                        self.__sendJsonCommand("ResponseWatchConditionError", {
+                            "condition": params["condition"],
+                        })
+                        return
+                self.mainThread.set_watch(
+                    params["condition"], params["temporary"])
+            else:
+                self.mainThread.clear_watch(params["condition"])
+            return
+        
+        if method == "RequestWatchEnable":
+            wp = self.mainThread.get_watch(params["condition"])
+            if wp is not None:
+                if params["enable"]:
+                    wp.enable()
+                else:
+                    wp.disable()
+            return
+        
+        if method == "RequestWatchIgnore":
+            wp = self.mainThread.get_watch(params["condition"])
+            if wp is not None:
+                wp.ignore = params["count"]
+            return
+        
+        if method == "RequestShutdown":
+            self.sessionClose()
+            return
+        
+        if method == "RequestCompletion":
+            self.__completionList(params["text"])
+            return
     
     def __sendJsonCommand(self, command, params):
         """
@@ -1395,6 +1509,110 @@
         cmd = json.dumps(commandDict) + '\n'
         self.write(cmd)
     
+    def sendClearTemporaryBreakpoint(self, filename, lineno):
+        """
+        Public method to signal the deletion of a temporary breakpoint.
+        
+        @param filename name of the file the bp belongs to
+        @type str
+        @param lineno linenumber of the bp
+        @type int
+        """
+        self.__sendJsonCommand("ResponseClearBreakpoint", {
+            "filename": filename,
+            "line": lineno
+        })
+    
+    def sendClearTemporaryWatch(self, condition):
+        """
+        Public method to signal the deletion of a temporary watch expression.
+        
+        @param condition condition of the watch expression to be cleared
+        @type str
+        """
+        self.__sendJsonCommand("ResponseClearWatch", {
+            "condition": condition,
+        })
+    
+    def sendResponseLine(self, stack):
+        """
+        Public method to send the current call stack.
+        
+        @param stack call stack
+        @type list
+        """
+        self.__sendJsonCommand("ResponseLine", {
+            "stack": stack,
+        })
+    
+    def sendCallTrace(self, event, fromStr, toStr):
+        """
+        Public method to send a call trace entry.
+        
+        @param event trace event (call or return)
+        @type str
+        @param fromstr pre-formatted origin info
+        @type str
+        @param toStr pre-formatted target info
+        @type str
+        """
+        self.__sendJsonCommand("CallTrace", {
+            "event": event[0],
+            "from": fromStr,
+            "to": toStr,
+        })
+    
+    def sendException(self, exceptionType, exceptionMessage, stack):
+        """
+        Public method to send information for an exception.
+        
+        @param exceptionType type of exception raised
+        @type str
+        @param exceptionMessage message of the exception
+        @type str
+        @param stack stack trace information
+        @param list
+        """
+        self.__sendJsonCommand("ResponseException", {
+            "type": exceptionType,
+            "message": exceptionMessage,
+            "stack": stack,
+        })
+    
+    def sendSyntaxError(self, message, filename, lineno, charno):
+        """
+        Public method to send information for a syntax error.
+        
+        @param message syntax error message
+        @type str
+        @param filename name of the faulty file
+        @type str
+        @param lineno line number info
+        @type int
+        @param charno character number info
+        @tyoe int
+        """
+        self.__sendJsonCommand("ResponseSyntax", {
+            "message": message,
+            "filename": filename,
+            "linenumber": lineno,
+            "characternumber": charno,
+        })
+    
+    def sendPassiveStartup(self, filename, exceptions):
+        """
+        Public method to send the passive start information.
+        
+        @param filename name of the script
+        @type str
+        @param exceptions flag to enable exception reporting of the IDE
+        @type bool
+        """
+        self.__sendJsonCommand("PassiveStartup", {
+            "filename": filename,
+            "exceptions": exceptions,
+        })
+    
     def __clientCapabilities(self):
         """
         Private method to determine the clients capabilities.
@@ -1606,9 +1824,16 @@
         else:
             fargs = ""
         
-        siglist = [message, [filename, linenr, ffunc, fargs]]
-        
-        self.write("{0}{1}".format(DebugProtocol.ResponseSignal, str(siglist)))
+##        siglist = [message, [filename, linenr, ffunc, fargs]]
+##        
+##        self.write("{0}{1}".format(DebugProtocol.ResponseSignal, str(siglist)))
+        self.__sendJsonCommand("ResponseSignal", {
+            "message": message,
+            "filename": filename, 
+            "linenumber": linenr, 
+            "function": ffunc, 
+            "arguments": fargs,
+        })
     
     def absPath(self, fn):
         """
@@ -1701,7 +1926,10 @@
         if self.running:
             self.set_quit()
             self.running = None
-            self.write('{0}{1:d}\n'.format(DebugProtocol.ResponseExit, status))
+##            self.write('{0}{1:d}\n'.format(DebugProtocol.ResponseExit, status))
+            self.__sendJsonCommand("ResponseExit", {
+                "status": status,
+            })
         
         # reset coding
         self.__coding = self.defaultCoding
@@ -1740,7 +1968,7 @@
         else:
             dict = f.f_locals
             
-        varlist = [scope]
+        varlist = []
         
         if scope != -1:
             keylist = dict.keys()
@@ -1748,8 +1976,12 @@
             vlist = self.__formatVariablesList(keylist, dict, scope, filter)
             varlist.extend(vlist)
         
-        self.write('{0}{1}\n'.format(
-            DebugProtocol.ResponseVariables, str(varlist)))
+##        self.write('{0}{1}\n'.format(
+##            DebugProtocol.ResponseVariables, str(varlist)))
+        self.__sendJsonCommand("ResponseVariables", {
+            "scope": scope,
+            "variables": varlist,
+        })
     
     def __dumpVariable(self, var, frmnr, scope, filter):
         """
@@ -1784,7 +2016,7 @@
         else:
             dict = f.f_locals
         
-        varlist = [scope, var]
+        varlist = []
         
         if scope != -1:
             # search the correct dictionary
@@ -1807,7 +2039,7 @@
                     udict = dict
                 ndict = {}
                 # this has to be in line with VariablesViewer.indicators
-                if var[i][-2:] in ["[]", "()", "{}"]:       # __IGNORE_WARNING__
+                if var[i][-2:] in ["[]", "()", "{}"]:   # __IGNORE_WARNING__
                     if i + 1 == len(var):
                         if var[i][:-2] == '...':
                             dictkeys = [var[i - 1]]
@@ -2033,8 +2265,13 @@
                 except Exception:
                     pass
         
-        self.write('{0}{1}\n'.format(
-            DebugProtocol.ResponseVariable, str(varlist)))
+##        self.write('{0}{1}\n'.format(
+##            DebugProtocol.ResponseVariable, str(varlist)))
+        self.__sendJsonCommand("ResponseVariable", {
+            "scope": scope,
+            "variable": var,
+            "variables": varlist,
+        })
         
     def __formatQtVariable(self, value, vtype):
         """
@@ -2330,8 +2567,12 @@
             pass
         self.__getCompletionList(text, self.complete, completions)
         
-        self.write("{0}{1}||{2}\n".format(DebugProtocol.ResponseCompletion,
-                                          str(list(completions)), text))
+##        self.write("{0}{1}||{2}\n".format(DebugProtocol.ResponseCompletion,
+##                                          str(list(completions)), text))
+        self.__sendJsonCommand("ResponseCompletion", {
+            "completions": list(completions),
+            "text": text, 
+        })
 
     def __getCompletionList(self, text, completer, completions):
         """
@@ -2389,15 +2630,14 @@
         if self.running:
             self.__setCoding(self.running)
         self.passive = True
-        self.write("{0}{1}|{2:d}\n".format(DebugProtocol.PassiveStartup,
-                                           self.running, exceptions))
+        self.sendPassiveStartup(self.running, exceptions)
         self.__interact()
         
         # setup the debugger variables
         self._fncache = {}
         self.dircache = []
         self.mainFrame = None
-        self.inRawMode = False
+##        self.inRawMode = False
         self.debugging = True
         
         self.attachThread(mainThread=True)
@@ -2450,12 +2690,13 @@
         self.running = sys.argv[0]
         self.__setCoding(self.running)
         self.mainFrame = None
-        self.inRawMode = False
+##        self.inRawMode = False
         self.debugging = True
         
         self.passive = True
-        self.write("{0}{1}|{2:d}\n".format(
-            DebugProtocol.PassiveStartup, self.running, exceptions))
+        self.sendPassiveStartup(self.running, exceptions)
+##        self.write("{0}{1}|{2:d}\n".format(
+##            DebugProtocol.PassiveStartup, self.running, exceptions))
         self.__interact()
         
         self.attachThread(mainThread=True)
--- a/Debugger/DebugServer.py	Thu Sep 01 18:28:27 2016 +0200
+++ b/Debugger/DebugServer.py	Thu Sep 01 19:00:46 2016 +0200
@@ -1125,24 +1125,6 @@
         """
         self.debuggerInterface.setCallTraceEnabled(on)
         
-    def remoteEval(self, arg):
-        """
-        Public method to evaluate arg in the current context of the debugged
-        program.
-        
-        @param arg the arguments to evaluate (string)
-        """
-        self.debuggerInterface.remoteEval(arg)
-        
-    def remoteExec(self, stmt):
-        """
-        Public method to execute stmt in the current context of the debugged
-        program.
-        
-        @param stmt statement to execute (string)
-        """
-        self.debuggerInterface.remoteExec(stmt)
-        
     def remoteBanner(self):
         """
         Public slot to get the banner info of the remote client.
--- a/Debugger/DebugUI.py	Thu Sep 01 18:28:27 2016 +0200
+++ b/Debugger/DebugUI.py	Thu Sep 01 19:00:46 2016 +0200
@@ -13,8 +13,7 @@
 
 from PyQt5.QtCore import pyqtSignal, QObject, Qt
 from PyQt5.QtGui import QKeySequence
-from PyQt5.QtWidgets import QMenu, QToolBar, QApplication, QDialog, \
-    QInputDialog
+from PyQt5.QtWidgets import QMenu, QToolBar, QApplication, QDialog
 
 from UI.Info import Program
 
@@ -104,8 +103,6 @@
         self.forkIntoChild = Preferences.toBool(
             Preferences.Prefs.settings.value('DebugInfo/ForkIntoChild', False))
         
-        self.evalHistory = []
-        self.execHistory = []
         self.lastDebuggedFile = None
         self.lastStartAction = 0    # 0=None, 1=Script, 2=Project
         self.clientType = ""
@@ -428,36 +425,6 @@
         act.triggered.connect(self.__stepQuit)
         self.actions.append(act)
         
-        self.debugActGrp2 = createActionGroup(self)
-
-        act = E5Action(
-            self.tr('Evaluate'),
-            self.tr('E&valuate...'),
-            0, 0, self.debugActGrp2, 'dbg_evaluate')
-        act.setStatusTip(self.tr('Evaluate in current context'))
-        act.setWhatsThis(self.tr(
-            """<b>Evaluate</b>"""
-            """<p>Evaluate an expression in the current context of the"""
-            """ debugged program. The result is displayed in the"""
-            """ shell window.</p>"""
-        ))
-        act.triggered.connect(self.__eval)
-        self.actions.append(act)
-        
-        act = E5Action(
-            self.tr('Execute'),
-            self.tr('E&xecute...'),
-            0, 0, self.debugActGrp2, 'dbg_execute')
-        act.setStatusTip(
-            self.tr('Execute a one line statement in the current context'))
-        act.setWhatsThis(self.tr(
-            """<b>Execute</b>"""
-            """<p>Execute a one line statement in the current context"""
-            """ of the debugged program.</p>"""
-        ))
-        act.triggered.connect(self.__exec)
-        self.actions.append(act)
-        
         self.dbgFilterAct = E5Action(
             self.tr('Variables Type Filter'),
             self.tr('Varia&bles Type Filter...'), 0, 0, self,
@@ -585,7 +552,6 @@
         self.actions.append(act)
 
         self.debugActGrp.setEnabled(False)
-        self.debugActGrp2.setEnabled(False)
         self.dbgSetBpActGrp.setEnabled(False)
         self.runAct.setEnabled(False)
         self.runProjectAct.setEnabled(False)
@@ -627,8 +593,6 @@
         
         dmenu.addActions(self.debugActGrp.actions())
         dmenu.addSeparator()
-        dmenu.addActions(self.debugActGrp2.actions())
-        dmenu.addSeparator()
         dmenu.addActions(self.dbgSetBpActGrp.actions())
         self.menuBreakpointsAct = dmenu.addMenu(self.breakpointsMenu)
         dmenu.addSeparator()
@@ -806,7 +770,6 @@
         self.profileAct.setEnabled(False)
         self.coverageAct.setEnabled(False)
         self.debugActGrp.setEnabled(False)
-        self.debugActGrp2.setEnabled(False)
         self.dbgSetBpActGrp.setEnabled(False)
         self.lastAction = -1
         if not self.projectOpen:
@@ -978,7 +941,6 @@
         """
         self.lastAction = -1
         self.debugActGrp.setEnabled(False)
-        self.debugActGrp2.setEnabled(False)
         if not self.passive:
             if self.editorOpen:
                 editor = self.viewmanager.activeWindow()
@@ -1016,7 +978,6 @@
             self.__getClientVariables()
 
         self.debugActGrp.setEnabled(True)
-        self.debugActGrp2.setEnabled(True)
         
     def __clientExit(self, status):
         """
@@ -1192,7 +1153,6 @@
                 self.__getClientVariables()
                 self.ui.setDebugProfile()
                 self.debugActGrp.setEnabled(True)
-                self.debugActGrp2.setEnabled(True)
                 return
             elif res == E5MessageBox.Ignore:
                 if exceptionType not in self.excIgnoreList:
@@ -2192,64 +2152,6 @@
             aw.getFileName(), line, 1, None, 1)
         self.debugServer.remoteContinue()
     
-    def __eval(self):
-        """
-        Private method to handle the Eval action.
-        """
-        # Get the command line arguments.
-        if len(self.evalHistory) > 0:
-            curr = 0
-        else:
-            curr = -1
-
-        arg, ok = QInputDialog.getItem(
-            self.ui,
-            self.tr("Evaluate"),
-            self.tr("Enter the statement to evaluate"),
-            self.evalHistory,
-            curr, True)
-
-        if ok:
-            if not arg:
-                return
-
-            # This moves any previous occurrence of this expression to the head
-            # of the list.
-            if arg in self.evalHistory:
-                self.evalHistory.remove(arg)
-            self.evalHistory.insert(0, arg)
-            
-            self.debugServer.remoteEval(arg)
-            
-    def __exec(self):
-        """
-        Private method to handle the Exec action.
-        """
-        # Get the command line arguments.
-        if len(self.execHistory) > 0:
-            curr = 0
-        else:
-            curr = -1
-
-        stmt, ok = QInputDialog.getItem(
-            self.ui,
-            self.tr("Execute"),
-            self.tr("Enter the statement to execute"),
-            self.execHistory,
-            curr, True)
-
-        if ok:
-            if not stmt:
-                return
-
-            # This moves any previous occurrence of this statement to the head
-            # of the list.
-            if stmt in self.execHistory:
-                self.execHistory.remove(stmt)
-            self.execHistory.insert(0, stmt)
-            
-            self.debugServer.remoteExec(stmt)
-            
     def __enterRemote(self):
         """
         Private method to update the user interface.
@@ -2259,7 +2161,6 @@
         """
         # Disable further debug commands from the user.
         self.debugActGrp.setEnabled(False)
-        self.debugActGrp2.setEnabled(False)
         
         self.viewmanager.unhighlight(True)
 
--- a/Debugger/DebuggerInterfaceNone.py	Thu Sep 01 18:28:27 2016 +0200
+++ b/Debugger/DebuggerInterfaceNone.py	Thu Sep 01 19:00:46 2016 +0200
@@ -343,22 +343,6 @@
         """
         return
         
-    def remoteExec(self, stmt):
-        """
-        Public method to execute stmt in the current context of the debugged
-        program.
-        
-        @param stmt statement to execute (string)
-        """
-        return
-        
-    def remoteBanner(self):
-        """
-        Public slot to get the banner info of the remote client.
-        """
-        self.debugServer.signalClientBanner("No backend", "", "")
-        return
-        
     def remoteCapabilities(self):
         """
         Public slot to get the debug clients capabilities.
--- a/Debugger/DebuggerInterfacePython3.py	Thu Sep 01 18:28:27 2016 +0200
+++ b/Debugger/DebuggerInterfacePython3.py	Thu Sep 01 19:00:46 2016 +0200
@@ -404,7 +404,8 @@
         self.qsock.readyRead.disconnect(self.__parseClientLine)
         
         # close down socket, and shut down client as well.
-        self.__sendCommand('{0}\n'.format(DebugProtocol.RequestShutdown))
+##        self.__sendCommand('{0}\n'.format(DebugProtocol.RequestShutdown))
+        self.__sendJsonCommand("RequestShutdown", {})
         self.qsock.flush()
         
         self.qsock.close()
@@ -597,19 +598,27 @@
             "special": special,
         })
 
-    def remoteBreakpoint(self, fn, line, set, cond=None, temp=False):
+    def remoteBreakpoint(self, fn, line, setBreakpoint, cond=None, temp=False):
         """
         Public method to set or clear a breakpoint.
         
         @param fn filename the breakpoint belongs to (string)
         @param line linenumber of the breakpoint (int)
-        @param set flag indicating setting or resetting a breakpoint (boolean)
+        @param setBreakpoint flag indicating setting or resetting a
+            breakpoint (boolean)
         @param cond condition of the breakpoint (string)
         @param temp flag indicating a temporary breakpoint (boolean)
         """
-        fn = self.translate(fn, False)
-        self.__sendCommand('{0}{1}@@{2:d}@@{3:d}@@{4:d}@@{5}\n'.format(
-            DebugProtocol.RequestBreak, fn, line, temp, set, cond))
+##        fn = self.translate(fn, False)
+##        self.__sendCommand('{0}{1}@@{2:d}@@{3:d}@@{4:d}@@{5}\n'.format(
+##            DebugProtocol.RequestBreak, fn, line, temp, set, cond))
+        self.__sendJsonCommand("RequestBreakpoint", {
+            "filename": self.translate(fn, False),
+            "line": line,
+            "temporary": temp,
+            "setBreakpoint": setBreakpoint,
+            "condition": cond,
+        })
     
     def remoteBreakpointEnable(self, fn, line, enable):
         """
@@ -620,9 +629,14 @@
         @param enable flag indicating enabling or disabling a breakpoint
             (boolean)
         """
-        fn = self.translate(fn, False)
-        self.__sendCommand('{0}{1},{2:d},{3:d}\n'.format(
-            DebugProtocol.RequestBreakEnable, fn, line, enable))
+##        fn = self.translate(fn, False)
+##        self.__sendCommand('{0}{1},{2:d},{3:d}\n'.format(
+##            DebugProtocol.RequestBreakEnable, fn, line, enable))
+        self.__sendJsonCommand("RequestBreakpointEnable", {
+            "filename": self.translate(fn, False),
+            "line": line,
+            "enable": enable,
+        })
     
     def remoteBreakpointIgnore(self, fn, line, count):
         """
@@ -632,22 +646,32 @@
         @param line linenumber of the breakpoint (int)
         @param count number of occurrences to ignore (int)
         """
-        fn = self.translate(fn, False)
-        self.__sendCommand('{0}{1},{2:d},{3:d}\n'.format(
-            DebugProtocol.RequestBreakIgnore, fn, line, count))
+##        fn = self.translate(fn, False)
+##        self.__sendCommand('{0}{1},{2:d},{3:d}\n'.format(
+##            DebugProtocol.RequestBreakIgnore, fn, line, count))
+        self.__sendJsonCommand("RequestBreakpointIgnore", {
+            "filename": self.translate(fn, False),
+            "line": line,
+            "count": count,
+        })
     
-    def remoteWatchpoint(self, cond, set, temp=False):
+    def remoteWatchpoint(self, cond, setWatch, temp=False):
         """
         Public method to set or clear a watch expression.
         
         @param cond expression of the watch expression (string)
-        @param set flag indicating setting or resetting a watch expression
+        @param setWatch flag indicating setting or resetting a watch expression
             (boolean)
         @param temp flag indicating a temporary watch expression (boolean)
         """
         # cond is combination of cond and special (s. watch expression viewer)
-        self.__sendCommand('{0}{1}@@{2:d}@@{3:d}\n'.format(
-            DebugProtocol.RequestWatch, cond, temp, set))
+##        self.__sendCommand('{0}{1}@@{2:d}@@{3:d}\n'.format(
+##            DebugProtocol.RequestWatch, cond, temp, set))
+        self.__sendJsonCommand("RequestWatch", {
+            "temporary": temp,
+            "setWatch": setWatch,
+            "condition": cond,
+        })
     
     def remoteWatchpointEnable(self, cond, enable):
         """
@@ -658,8 +682,12 @@
             (boolean)
         """
         # cond is combination of cond and special (s. watch expression viewer)
-        self.__sendCommand('{0}{1},{2:d}\n'.format(
-            DebugProtocol.RequestWatchEnable, cond, enable))
+##        self.__sendCommand('{0}{1},{2:d}\n'.format(
+##            DebugProtocol.RequestWatchEnable, cond, enable))
+        self.__sendJsonCommand("RequestWatchEnable", {
+            "condition": cond,
+            "enable": enable,
+        })
     
     def remoteWatchpointIgnore(self, cond, count):
         """
@@ -670,8 +698,12 @@
         @param count number of occurrences to ignore (int)
         """
         # cond is combination of cond and special (s. watch expression viewer)
-        self.__sendCommand('{0}{1},{2:d}\n'.format(
-            DebugProtocol.RequestWatchIgnore, cond, count))
+##        self.__sendCommand('{0}{1},{2:d}\n'.format(
+##            DebugProtocol.RequestWatchIgnore, cond, count))
+        self.__sendJsonCommand("RequestWatchIgnore", {
+            "condition": cond,
+            "count": count,
+        })
     
     def remoteRawInput(self, s):
         """
@@ -688,7 +720,8 @@
         """
         Public method to request the list of threads from the client.
         """
-        self.__sendCommand('{0}\n'.format(DebugProtocol.RequestThreadList))
+##        self.__sendCommand('{0}\n'.format(DebugProtocol.RequestThreadList))
+        self.__sendJsonCommand("RequestThreadList", {})
         
     def remoteSetThread(self, tid):
         """
@@ -696,8 +729,11 @@
         
         @param tid id of the thread (integer)
         """
-        self.__sendCommand('{0}{1:d}\n'.format(
-            DebugProtocol.RequestThreadSet, tid))
+##        self.__sendCommand('{0}{1:d}\n'.format(
+##            DebugProtocol.RequestThreadSet, tid))
+        self.__sendJsonCommand("RequestThreadSet", {
+            "threadID": tid,
+        })
         
     def remoteClientVariables(self, scope, filter, framenr=0):
         """
@@ -707,8 +743,13 @@
         @param filter list of variable types to filter out (list of int)
         @param framenr framenumber of the variables to retrieve (int)
         """
-        self.__sendCommand('{0}{1:d}, {2:d}, {3}\n'.format(
-            DebugProtocol.RequestVariables, framenr, scope, str(filter)))
+##        self.__sendCommand('{0}{1:d}, {2:d}, {3}\n'.format(
+##            DebugProtocol.RequestVariables, framenr, scope, str(filter)))
+        self.__sendJsonCommand("RequestVariables", {
+            "frameNumber": framenr,
+            "scope": scope,
+            "filters": filter,
+        })
     
     def remoteClientVariable(self, scope, filter, var, framenr=0):
         """
@@ -719,9 +760,15 @@
         @param var list encoded name of variable to retrieve (string)
         @param framenr framenumber of the variables to retrieve (int)
         """
-        self.__sendCommand('{0}{1}, {2:d}, {3:d}, {4}\n'.format(
-            DebugProtocol.RequestVariable, str(var), framenr, scope,
-            str(filter)))
+##        self.__sendCommand('{0}{1}, {2:d}, {3:d}, {4}\n'.format(
+##            DebugProtocol.RequestVariable, str(var), framenr, scope,
+##            str(filter)))
+        self.__sendJsonCommand("RequestVariable", {
+            "variable": var,
+            "frameNumber": framenr,
+            "scope": scope,
+            "filters": filter,
+        })
     
     def remoteClientSetFilter(self, scope, filter):
         """
@@ -730,8 +777,12 @@
         @param scope the scope of the variables (0 = local, 1 = global)
         @param filter regexp string for variable names to filter out (string)
         """
-        self.__sendCommand('{0}{1:d}, "{2}"\n'.format(
-            DebugProtocol.RequestSetFilter, scope, filter))
+##        self.__sendCommand('{0}{1:d}, "{2}"\n'.format(
+##            DebugProtocol.RequestSetFilter, scope, filter))
+        self.__sendJsonCommand("RequestSetFilter", {
+            "scope": scope,
+            "filter": filter,
+        })
     
     def setCallTraceEnabled(self, on):
         """
@@ -739,31 +790,37 @@
         
         @param on flag indicating to enable the call trace function (boolean)
         """
-        if on:
-            cmd = "on"
-        else:
-            cmd = "off"
-        self.__sendCommand('{0}{1}\n'.format(
-            DebugProtocol.RequestCallTrace, cmd))
+##        if on:
+##            cmd = "on"
+##        else:
+##            cmd = "off"
+##        self.__sendCommand('{0}{1}\n'.format(
+##            DebugProtocol.RequestCallTrace, cmd))
+        self.__sendJsonCommand("RequestCallTrace", {
+            "enable": on,
+        })
     
-    def remoteEval(self, arg):
-        """
-        Public method to evaluate arg in the current context of the debugged
-        program.
-        
-        @param arg the arguments to evaluate (string)
-        """
-        self.__sendCommand('{0}{1}\n'.format(DebugProtocol.RequestEval, arg))
-    
-    def remoteExec(self, stmt):
-        """
-        Public method to execute stmt in the current context of the debugged
-        program.
-        
-        @param stmt statement to execute (string)
-        """
-        self.__sendCommand('{0}{1}\n'.format(DebugProtocol.RequestExec, stmt))
-    
+##    def remoteEval(self, arg):
+##        """
+##        Public method to evaluate arg in the current context of the debugged
+##        program.
+##        
+##        @param arg the arguments to evaluate (string)
+##        """
+####        self.__sendCommand('{0}{1}\n'.format(DebugProtocol.RequestEval, arg))
+##        self.__sendJsonCommand("RequestEval", {
+##            "argument": arg,
+##        })
+##    
+##    def remoteExec(self, stmt):
+##        """
+##        Public method to execute stmt in the current context of the debugged
+##        program.
+##        
+##        @param stmt statement to execute (string)
+##        """
+##        self.__sendCommand('{0}{1}\n'.format(DebugProtocol.RequestExec, stmt))
+##    
     def remoteBanner(self):
         """
         Public slot to get the banner info of the remote client.
@@ -785,8 +842,11 @@
         
         @param text the text to be completed (string)
         """
-        self.__sendCommand("{0}{1}\n".format(
-            DebugProtocol.RequestCompletion, text))
+##        self.__sendCommand("{0}{1}\n".format(
+##            DebugProtocol.RequestCompletion, text))
+        self.__sendJsonCommand("RequestCompletion", {
+            "text": text,
+        })
     
     def remoteUTPrepare(self, fn, tn, tfn, failed, cov, covname, coverase):
         """
@@ -877,63 +937,63 @@
             if boc >= 0 and eoc > boc:
                 resp = line[boc:eoc]
                 
-                if resp == DebugProtocol.ResponseLine or \
-                   resp == DebugProtocol.ResponseStack:
-                    stack = eval(line[eoc:-1])
-                    for s in stack:
-                        s[0] = self.translate(s[0], True)
-                    cf = stack[0]
-                    if self.__autoContinue:
-                        self.__autoContinue = False
-                        QTimer.singleShot(0, self.remoteContinue)
-                    else:
-                        self.debugServer.signalClientLine(
-                            cf[0], int(cf[1]),
-                            resp == DebugProtocol.ResponseStack)
-                        self.debugServer.signalClientStack(stack)
-                    continue
-                
-                if resp == DebugProtocol.CallTrace:
-                    event, fromStr, toStr = line[eoc:-1].split("@@")
-                    isCall = event.lower() == "c"
-                    fromFile, fromLineno, fromFunc = fromStr.rsplit(":", 2)
-                    toFile, toLineno, toFunc = toStr.rsplit(":", 2)
-                    self.debugServer.signalClientCallTrace(
-                        isCall,
-                        fromFile, fromLineno, fromFunc,
-                        toFile, toLineno, toFunc)
-                    continue
-                
-                if resp == DebugProtocol.ResponseThreadList:
-                    currentId, threadList = eval(line[eoc:-1])
-                    self.debugServer.signalClientThreadList(
-                        currentId, threadList)
-                    continue
-                
-                if resp == DebugProtocol.ResponseThreadSet:
-                    self.debugServer.signalClientThreadSet()
-                    continue
-                
-                if resp == DebugProtocol.ResponseVariables:
-                    vlist = eval(line[eoc:-1])
-                    scope = vlist[0]
-                    try:
-                        variables = vlist[1:]
-                    except IndexError:
-                        variables = []
-                    self.debugServer.signalClientVariables(scope, variables)
-                    continue
-                
-                if resp == DebugProtocol.ResponseVariable:
-                    vlist = eval(line[eoc:-1])
-                    scope = vlist[0]
-                    try:
-                        variables = vlist[1:]
-                    except IndexError:
-                        variables = []
-                    self.debugServer.signalClientVariable(scope, variables)
-                    continue
-                
+##                if resp == DebugProtocol.ResponseLine or \
+##                   resp == DebugProtocol.ResponseStack:
+##                    stack = eval(line[eoc:-1])
+##                    for s in stack:
+##                        s[0] = self.translate(s[0], True)
+##                    cf = stack[0]
+##                    if self.__autoContinue:
+##                        self.__autoContinue = False
+##                        QTimer.singleShot(0, self.remoteContinue)
+##                    else:
+##                        self.debugServer.signalClientLine(
+##                            cf[0], int(cf[1]),
+##                            resp == DebugProtocol.ResponseStack)
+##                        self.debugServer.signalClientStack(stack)
+##                    continue
+##                
+##                if resp == DebugProtocol.CallTrace:
+##                    event, fromStr, toStr = line[eoc:-1].split("@@")
+##                    isCall = event.lower() == "c"
+##                    fromFile, fromLineno, fromFunc = fromStr.rsplit(":", 2)
+##                    toFile, toLineno, toFunc = toStr.rsplit(":", 2)
+##                    self.debugServer.signalClientCallTrace(
+##                        isCall,
+##                        fromFile, fromLineno, fromFunc,
+##                        toFile, toLineno, toFunc)
+##                    continue
+##                
+##                if resp == DebugProtocol.ResponseThreadList:
+##                    currentId, threadList = eval(line[eoc:-1])
+##                    self.debugServer.signalClientThreadList(
+##                        currentId, threadList)
+##                    continue
+##                
+##                if resp == DebugProtocol.ResponseThreadSet:
+##                    self.debugServer.signalClientThreadSet()
+##                    continue
+##                
+##                if resp == DebugProtocol.ResponseVariables:
+##                    vlist = eval(line[eoc:-1])
+##                    scope = vlist[0]
+##                    try:
+##                        variables = vlist[1:]
+##                    except IndexError:
+##                        variables = []
+##                    self.debugServer.signalClientVariables(scope, variables)
+##                    continue
+##                
+##                if resp == DebugProtocol.ResponseVariable:
+##                    vlist = eval(line[eoc:-1])
+##                    scope = vlist[0]
+##                    try:
+##                        variables = vlist[1:]
+##                    except IndexError:
+##                        variables = []
+##                    self.debugServer.signalClientVariable(scope, variables)
+##                    continue
+##                
 ##                if resp == DebugProtocol.ResponseOK:
 ##                    self.debugServer.signalClientStatement(False)
 ##                    continue
@@ -942,84 +1002,84 @@
 ##                    self.debugServer.signalClientStatement(True)
 ##                    continue
 ##                
-                if resp == DebugProtocol.ResponseException:
-                    exc = line[eoc:-1]
-                    exc = self.translate(exc, True)
-                    try:
-                        exclist = eval(exc)
-                        exctype = exclist[0]
-                        excmessage = exclist[1]
-                        stack = exclist[2:]
-                        if stack and stack[0] and stack[0][0] == "<string>":
-                            for stackEntry in stack:
-                                if stackEntry[0] == "<string>":
-                                    stackEntry[0] = self.__scriptName
-                                else:
-                                    break
-                    except (IndexError, ValueError, SyntaxError):
-                        exctype = None
-                        excmessage = ''
-                        stack = []
-                    self.debugServer.signalClientException(
-                        exctype, excmessage, stack)
-                    continue
-                
-                if resp == DebugProtocol.ResponseSyntax:
-                    exc = line[eoc:-1]
-                    exc = self.translate(exc, True)
-                    try:
-                        message, (fn, ln, cn) = eval(exc)
-                        if fn is None:
-                            fn = ''
-                    except (IndexError, ValueError):
-                        message = None
-                        fn = ''
-                        ln = 0
-                        cn = 0
-                    if cn is None:
-                        cn = 0
-                    self.debugServer.signalClientSyntaxError(
-                        message, fn, ln, cn)
-                    continue
-                
-                if resp == DebugProtocol.ResponseSignal:
-                    sig = line[eoc:-1]
-                    sig = self.translate(sig, True)
-                    message, (fn, ln, func, args) = eval(sig)
-                    self.debugServer.signalClientSignal(
-                        message, fn, ln, func, args)
-                    continue
-                
-                if resp == DebugProtocol.ResponseExit:
-                    self.__scriptName = ""
-                    self.debugServer.signalClientExit(line[eoc:-1])
-                    continue
-                
-                if resp == DebugProtocol.ResponseClearBreak:
-                    fn, lineno = line[eoc:-1].split(',')
-                    lineno = int(lineno)
-                    fn = self.translate(fn, True)
-                    self.debugServer.signalClientClearBreak(fn, lineno)
-                    continue
-                
-                if resp == DebugProtocol.ResponseBPConditionError:
-                    fn, lineno = line[eoc:-1].split(',')
-                    lineno = int(lineno)
-                    fn = self.translate(fn, True)
-                    self.debugServer.signalClientBreakConditionError(
-                        fn, lineno)
-                    continue
-                
-                if resp == DebugProtocol.ResponseClearWatch:
-                    cond = line[eoc:-1]
-                    self.debugServer.signalClientClearWatch(cond)
-                    continue
-                
-                if resp == DebugProtocol.ResponseWPConditionError:
-                    cond = line[eoc:-1]
-                    self.debugServer.signalClientWatchConditionError(cond)
-                    continue
-                
+##                if resp == DebugProtocol.ResponseException:
+##                    exc = line[eoc:-1]
+##                    exc = self.translate(exc, True)
+##                    try:
+##                        exclist = eval(exc)
+##                        exctype = exclist[0]
+##                        excmessage = exclist[1]
+##                        stack = exclist[2:]
+##                        if stack and stack[0] and stack[0][0] == "<string>":
+##                            for stackEntry in stack:
+##                                if stackEntry[0] == "<string>":
+##                                    stackEntry[0] = self.__scriptName
+##                                else:
+##                                    break
+##                    except (IndexError, ValueError, SyntaxError):
+##                        exctype = None
+##                        excmessage = ''
+##                        stack = []
+##                    self.debugServer.signalClientException(
+##                        exctype, excmessage, stack)
+##                    continue
+##                
+##                if resp == DebugProtocol.ResponseSyntax:
+##                    exc = line[eoc:-1]
+##                    exc = self.translate(exc, True)
+##                    try:
+##                        message, (fn, ln, cn) = eval(exc)
+##                        if fn is None:
+##                            fn = ''
+##                    except (IndexError, ValueError):
+##                        message = None
+##                        fn = ''
+##                        ln = 0
+##                        cn = 0
+##                    if cn is None:
+##                        cn = 0
+##                    self.debugServer.signalClientSyntaxError(
+##                        message, fn, ln, cn)
+##                    continue
+##                
+##                if resp == DebugProtocol.ResponseSignal:
+##                    sig = line[eoc:-1]
+##                    sig = self.translate(sig, True)
+##                    message, (fn, ln, func, args) = eval(sig)
+##                    self.debugServer.signalClientSignal(
+##                        message, fn, ln, func, args)
+##                    continue
+##                
+##                if resp == DebugProtocol.ResponseExit:
+##                    self.__scriptName = ""
+##                    self.debugServer.signalClientExit(line[eoc:-1])
+##                    continue
+##                
+##                if resp == DebugProtocol.ResponseClearBreak:
+##                    fn, lineno = line[eoc:-1].split(',')
+##                    lineno = int(lineno)
+##                    fn = self.translate(fn, True)
+##                    self.debugServer.signalClientClearBreak(fn, lineno)
+##                    continue
+##                
+##                if resp == DebugProtocol.ResponseBPConditionError:
+##                    fn, lineno = line[eoc:-1].split(',')
+##                    lineno = int(lineno)
+##                    fn = self.translate(fn, True)
+##                    self.debugServer.signalClientBreakConditionError(
+##                        fn, lineno)
+##                    continue
+##                
+##                if resp == DebugProtocol.ResponseClearWatch:
+##                    cond = line[eoc:-1]
+##                    self.debugServer.signalClientClearWatch(cond)
+##                    continue
+##                
+##                if resp == DebugProtocol.ResponseWPConditionError:
+##                    cond = line[eoc:-1]
+##                    self.debugServer.signalClientWatchConditionError(cond)
+##                    continue
+##                
 ##                if resp == DebugProtocol.ResponseRaw:
 ##                    prompt, echo = eval(line[eoc:-1])
 ##                    self.debugServer.signalClientRawInput(prompt, echo)
@@ -1037,19 +1097,19 @@
 ##                    self.debugServer.signalClientCapabilities(cap, clType)
 ##                    continue
 ##                
-                if resp == DebugProtocol.ResponseCompletion:
-                    clstring, text = line[eoc:-1].split('||')
-                    cl = eval(clstring)
-                    self.debugServer.signalClientCompletionList(cl, text)
-                    continue
-                
-                if resp == DebugProtocol.PassiveStartup:
-                    fn, exc = line[eoc:-1].split('|')
-                    exc = bool(exc)
-                    fn = self.translate(fn, True)
-                    self.debugServer.passiveStartUp(fn, exc)
-                    continue
-                
+##                if resp == DebugProtocol.ResponseCompletion:
+##                    clstring, text = line[eoc:-1].split('||')
+##                    cl = eval(clstring)
+##                    self.debugServer.signalClientCompletionList(cl, text)
+##                    continue
+##                
+##                if resp == DebugProtocol.PassiveStartup:
+##                    fn, exc = line[eoc:-1].split('|')
+##                    exc = bool(exc)
+##                    fn = self.translate(fn, True)
+##                    self.debugServer.passiveStartUp(fn, exc)
+##                    continue
+##                
                 if resp == DebugProtocol.ResponseUTPrepared:
                     res, exc_type, exc_value = eval(line[eoc:-1])
                     self.debugServer.clientUtPrepared(res, exc_type, exc_value)
@@ -1112,12 +1172,56 @@
         try:
             commandDict = json.loads(jsonStr.strip())
         except json.JSONDecodeError as err:
+            # TODO: implement real error handling
             print(str(err))
             return
         
         method = commandDict["method"]
         params = commandDict["params"]
         
+        if method in ["ResponseLine", "ResponseStack"]:
+            for s in params["stack"]:
+                s[0] = self.translate(s[0], True)
+            cf = params["stack"][0]
+            if self.__autoContinue:
+                self.__autoContinue = False
+                QTimer.singleShot(0, self.remoteContinue)
+            else:
+                self.debugServer.signalClientLine(
+                    cf[0], int(cf[1]),
+                    method == "ResponseStack")
+                self.debugServer.signalClientStack(params["stack"])
+            return
+        
+        if method == "CallTrace":
+            isCall = params["event"].lower() == "c"
+            fromFile, fromLineno, fromFunc = params["from"].rsplit(":", 2)
+            toFile, toLineno, toFunc = params["to"].rsplit(":", 2)
+            self.debugServer.signalClientCallTrace(
+                isCall,
+                fromFile, fromLineno, fromFunc,
+                toFile, toLineno, toFunc)
+            return
+        
+        if method == "ResponseVariables":
+            self.debugServer.signalClientVariables(
+                params["scope"], params["variables"])
+            return
+        
+        if method == "ResponseVariable":
+            self.debugServer.signalClientVariable(
+                params["scope"], [params["variable"]] + params["variables"])
+            return
+        
+        if method == "ResponseThreadList":
+            self.debugServer.signalClientThreadList(
+                params["currentID"], params["threadList"])
+            return
+        
+        if method == "ResponseThreadSet":
+            self.debugServer.signalClientThreadSet()
+            return
+        
         if method == "ResponseCapabilities":
             self.clientCapabilities = params["capabilities"]
             self.debugServer.signalClientCapabilities(
@@ -1143,6 +1247,79 @@
             self.debugServer.signalClientRawInput(
                 params["prompt"], params["echo"])
             return
+        
+        if method == "ResponseBPConditionError":
+            params["filename"] = self.translate(params["filename"], True)
+            self.debugServer.signalClientBreakConditionError(
+                params["filename"], params["line"])
+            return
+        
+        if method == "ResponseClearBreakpoint":
+            params["filename"] = self.translate(params["filename"], True)
+            self.debugServer.signalClientClearBreak(
+                params["filename"], params["line"])
+            return
+        
+        if method == "ResponseWatchConditionError":
+            self.debugServer.signalClientWatchConditionError(
+                params["condition"])
+            return
+        
+        if method == "ResponseClearWatch":
+            self.debugServer.signalClientClearWatch(params["condition"])
+            return
+        
+        if method == "ResponseException":
+            if params:
+                exctype = params["type"]
+                excmessage = params["message"]
+                stack = params["stack"]
+                if stack:
+                    for stackEntry in stack:
+                        stackEntry[0] = self.translate(stackEntry[0], True)
+                    if stack[0] and stack[0][0] == "<string>":
+                        for stackEntry in stack:
+                            if stackEntry[0] == "<string>":
+                                stackEntry[0] = self.__scriptName
+                            else:
+                                break
+            else:
+                exctype = None
+                excmessage = ''
+                stack = []
+            
+            self.debugServer.signalClientException(
+                exctype, excmessage, stack)
+            return
+        
+        if method == "ResponseSyntax":
+            self.debugServer.signalClientSyntaxError(
+                params["message"], self.translate(params["filename"], True),
+                params["linenumber"], params["characternumber"])
+            return
+        
+        if method == "ResponseSignal":
+            self.debugServer.signalClientSignal(
+                params["message"], self.translate(params["filename"], True),
+                params["linenumber"], params["function"], params["arguments"])
+            return
+        
+        if method == "ResponseExit":
+            self.__scriptName = ""
+            self.debugServer.signalClientExit(params["status"])
+            return
+        
+        if method == "PassiveStartup":
+            self.debugServer.passiveStartUp(
+                self.translate(params["filename"], True), params["exceptions"])
+            return
+        
+        if method == "ResponseCompletion":
+##                    clstring, text = line[eoc:-1].split('||')
+##                    cl = eval(clstring)
+            self.debugServer.signalClientCompletionList(
+                params["completions"], params["text"])
+            return
     
     def __sendCommand(self, cmd):
         """

eric ide

mercurial