425 """ |
425 """ |
426 Public method to set the environment for a program to debug, run, ... |
426 Public method to set the environment for a program to debug, run, ... |
427 |
427 |
428 @param env environment settings (dictionary) |
428 @param env environment settings (dictionary) |
429 """ |
429 """ |
430 self.__sendCommand('{0}{1}\n'.format( |
430 ## self.__sendCommand('{0}{1}\n'.format( |
431 DebugProtocol.RequestEnv, str(env))) |
431 ## DebugProtocol.RequestEnv, str(env))) |
|
432 self.__sendJsonCommand("RequestEnvironment", {"environment": env}) |
432 |
433 |
433 def remoteLoad(self, fn, argv, wd, traceInterpreter=False, |
434 def remoteLoad(self, fn, argv, wd, traceInterpreter=False, |
434 autoContinue=True, autoFork=False, forkChild=False): |
435 autoContinue=True, autoFork=False, forkChild=False): |
435 """ |
436 """ |
436 Public method to load a new program to debug. |
437 Public method to load a new program to debug. |
449 self.__autoContinue = autoContinue |
450 self.__autoContinue = autoContinue |
450 self.__scriptName = os.path.abspath(fn) |
451 self.__scriptName = os.path.abspath(fn) |
451 |
452 |
452 wd = self.translate(wd, False) |
453 wd = self.translate(wd, False) |
453 fn = self.translate(os.path.abspath(fn), False) |
454 fn = self.translate(os.path.abspath(fn), False) |
454 self.__sendCommand('{0}{1}\n'.format( |
455 ## self.__sendCommand('{0}{1}\n'.format( |
455 DebugProtocol.RequestForkMode, repr((autoFork, forkChild)))) |
456 ## DebugProtocol.RequestForkMode, repr((autoFork, forkChild)))) |
456 self.__sendCommand('{0}{1}|{2}|{3}|{4:d}\n'.format( |
457 ## self.__sendCommand('{0}{1}|{2}|{3}|{4:d}\n'.format( |
457 DebugProtocol.RequestLoad, wd, fn, |
458 ## DebugProtocol.RequestLoad, wd, fn, |
458 str(Utilities.parseOptionString(argv)), |
459 ## str(Utilities.parseOptionString(argv)), |
459 traceInterpreter)) |
460 ## traceInterpreter)) |
|
461 self.__sendJsonCommand("RequestLoad", { |
|
462 "workdir": wd, |
|
463 "filename": fn, |
|
464 "argv": Utilities.parseOptionString(argv), |
|
465 "traceInterpreter": traceInterpreter, |
|
466 "autofork": autoFork, |
|
467 "forkChild": forkChild, |
|
468 }) |
460 |
469 |
461 def remoteRun(self, fn, argv, wd, autoFork=False, forkChild=False): |
470 def remoteRun(self, fn, argv, wd, autoFork=False, forkChild=False): |
462 """ |
471 """ |
463 Public method to load a new program to run. |
472 Public method to load a new program to run. |
464 |
473 |
725 |
734 |
726 def remoteBanner(self): |
735 def remoteBanner(self): |
727 """ |
736 """ |
728 Public slot to get the banner info of the remote client. |
737 Public slot to get the banner info of the remote client. |
729 """ |
738 """ |
730 self.__sendCommand(DebugProtocol.RequestBanner + '\n') |
739 ## self.__sendCommand(DebugProtocol.RequestBanner + '\n') |
|
740 self.__sendJsonCommand("RequestBanner", {}) |
731 |
741 |
732 def remoteCapabilities(self): |
742 def remoteCapabilities(self): |
733 """ |
743 """ |
734 Public slot to get the debug clients capabilities. |
744 Public slot to get the debug clients capabilities. |
735 """ |
745 """ |
736 self.__sendCommand(DebugProtocol.RequestCapabilities + '\n') |
746 ## self.__sendCommand(DebugProtocol.RequestCapabilities + '\n') |
|
747 self.__sendJsonCommand("RequestCapabilities", {}) |
737 |
748 |
738 def remoteCompletion(self, text): |
749 def remoteCompletion(self, text): |
739 """ |
750 """ |
740 Public slot to get the a list of possible commandline completions |
751 Public slot to get the a list of possible commandline completions |
741 from the remote client. |
752 from the remote client. |
811 line = line[:-len(DebugProtocol.EOT)] |
822 line = line[:-len(DebugProtocol.EOT)] |
812 if not line: |
823 if not line: |
813 continue |
824 continue |
814 |
825 |
815 ## print("Server: ", line) ##debug |
826 ## print("Server: ", line) ##debug |
|
827 |
|
828 if line.startswith("{") and "jsonrpc" in line: |
|
829 self.__handleJsonCommand(line) |
|
830 continue |
816 |
831 |
817 eoc = line.find('<') + 1 |
832 eoc = line.find('<') + 1 |
818 |
833 |
819 # Deal with case where user has written directly to stdout |
834 # Deal with case where user has written directly to stdout |
820 # or stderr, but not line terminated and we stepped over the |
835 # or stderr, but not line terminated and we stepped over the |
976 if resp == DebugProtocol.ResponseRaw: |
991 if resp == DebugProtocol.ResponseRaw: |
977 prompt, echo = eval(line[eoc:-1]) |
992 prompt, echo = eval(line[eoc:-1]) |
978 self.debugServer.signalClientRawInput(prompt, echo) |
993 self.debugServer.signalClientRawInput(prompt, echo) |
979 continue |
994 continue |
980 |
995 |
981 if resp == DebugProtocol.ResponseBanner: |
996 ## if resp == DebugProtocol.ResponseBanner: |
982 version, platform, dbgclient = eval(line[eoc:-1]) |
997 ## version, platform, dbgclient = eval(line[eoc:-1]) |
983 self.debugServer.signalClientBanner( |
998 ## self.debugServer.signalClientBanner( |
984 version, platform, dbgclient) |
999 ## version, platform, dbgclient) |
985 continue |
1000 ## continue |
986 |
1001 ## |
987 if resp == DebugProtocol.ResponseCapabilities: |
1002 ## if resp == DebugProtocol.ResponseCapabilities: |
988 cap, clType = eval(line[eoc:-1]) |
1003 ## cap, clType = eval(line[eoc:-1]) |
989 self.clientCapabilities = cap |
1004 ## self.clientCapabilities = cap |
990 self.debugServer.signalClientCapabilities(cap, clType) |
1005 ## self.debugServer.signalClientCapabilities(cap, clType) |
991 continue |
1006 ## continue |
992 |
1007 ## |
993 if resp == DebugProtocol.ResponseCompletion: |
1008 if resp == DebugProtocol.ResponseCompletion: |
994 clstring, text = line[eoc:-1].split('||') |
1009 clstring, text = line[eoc:-1].split('||') |
995 cl = eval(clstring) |
1010 cl = eval(clstring) |
996 self.debugServer.signalClientCompletionList(cl, text) |
1011 self.debugServer.signalClientCompletionList(cl, text) |
997 continue |
1012 continue |
1053 if resp == DebugProtocol.RequestForkTo: |
1068 if resp == DebugProtocol.RequestForkTo: |
1054 self.__askForkTo() |
1069 self.__askForkTo() |
1055 continue |
1070 continue |
1056 |
1071 |
1057 self.debugServer.signalClientOutput(line) |
1072 self.debugServer.signalClientOutput(line) |
1058 |
1073 |
|
1074 def __handleJsonCommand(self, jsonStr): |
|
1075 """ |
|
1076 Private method to handle a command serialized as a JSON string. |
|
1077 """ |
|
1078 import json |
|
1079 |
|
1080 try: |
|
1081 commandDict = json.loads(jsonStr.strip()) |
|
1082 except json.JSONDecodeError as err: |
|
1083 print(str(err)) |
|
1084 return |
|
1085 |
|
1086 method = commandDict["method"] |
|
1087 params = commandDict["params"] |
|
1088 |
|
1089 if method == "ResponseCapabilities": |
|
1090 self.clientCapabilities = params["capabilities"] |
|
1091 self.debugServer.signalClientCapabilities( |
|
1092 params["capabilities"], params["clientType"]) |
|
1093 return |
|
1094 |
|
1095 if method == "ResponseBanner": |
|
1096 self.debugServer.signalClientBanner( |
|
1097 params["version"], |
|
1098 params["platform"], |
|
1099 params["dbgclient"]) |
|
1100 return |
|
1101 |
1059 def __sendCommand(self, cmd): |
1102 def __sendCommand(self, cmd): |
1060 """ |
1103 """ |
1061 Private method to send a single line command to the client. |
1104 Private method to send a single line command to the client. |
1062 |
1105 |
1063 @param cmd command to send to the debug client (string) |
1106 @param cmd command to send to the debug client (string) |
1064 """ |
1107 """ |
|
1108 if self.qsock is not None: |
|
1109 self.qsock.write(cmd.encode('utf8', 'backslashreplace')) |
|
1110 else: |
|
1111 self.queue.append(cmd) |
|
1112 |
|
1113 def __sendJsonCommand(self, command, params): |
|
1114 """ |
|
1115 Private method to send a single command to the client. |
|
1116 |
|
1117 @param command command name to be sent |
|
1118 @type str |
|
1119 @param params dictionary of named parameters for the command |
|
1120 @type dict |
|
1121 """ |
|
1122 import json |
|
1123 |
|
1124 commandDict = { |
|
1125 "jsonrpc": "2.0", |
|
1126 "method": command, |
|
1127 "params": params, |
|
1128 } |
|
1129 cmd = json.dumps(commandDict) + '\n' |
1065 if self.qsock is not None: |
1130 if self.qsock is not None: |
1066 self.qsock.write(cmd.encode('utf8', 'backslashreplace')) |
1131 self.qsock.write(cmd.encode('utf8', 'backslashreplace')) |
1067 else: |
1132 else: |
1068 self.queue.append(cmd) |
1133 self.queue.append(cmd) |
1069 |
1134 |