Thu, 01 Sep 2016 19:00:46 +0200
Continued modernizing the debugger interface.
--- 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): """