917 qs = self.qsock.readLine() |
926 qs = self.qsock.readLine() |
918 if self.codec is not None: |
927 if self.codec is not None: |
919 line = self.codec.toUnicode(qs) |
928 line = self.codec.toUnicode(qs) |
920 else: |
929 else: |
921 line = bytes(qs).decode() |
930 line = bytes(qs).decode() |
922 if line.endswith(DebugProtocol.EOT): |
931 ## if line.endswith(EOT): |
923 line = line[:-len(DebugProtocol.EOT)] |
932 ## line = line[:-len(EOT)] |
924 if not line: |
933 ## if not line: |
925 continue |
934 ## continue |
926 |
935 |
927 ## print("Server: ", line) ##debug |
936 ## print("Server: ", line) ##debug |
928 |
937 |
929 if line.startswith("{") and "jsonrpc" in line: |
938 ## if line.startswith("{") and "jsonrpc" in line: |
930 self.__handleJsonCommand(line) |
939 self.__handleJsonCommand(line) |
931 continue |
940 continue |
932 |
941 ## |
933 eoc = line.find('<') + 1 |
942 ## eoc = line.find('<') + 1 |
934 |
943 ## |
935 # Deal with case where user has written directly to stdout |
944 ## # Deal with case where user has written directly to stdout |
936 # or stderr, but not line terminated and we stepped over the |
945 ## # or stderr, but not line terminated and we stepped over the |
937 # write call, in that case the >line< will not be the first |
946 ## # write call, in that case the >line< will not be the first |
938 # string read from the socket... |
947 ## # string read from the socket... |
939 boc = line.find('>') |
948 ## boc = line.find('>') |
940 if boc > 0 and eoc > boc: |
949 ## if boc > 0 and eoc > boc: |
941 self.debugServer.signalClientOutput(line[:boc]) |
950 ## self.debugServer.signalClientOutput(line[:boc]) |
942 line = line[boc:] |
951 ## line = line[boc:] |
943 eoc = line.find('<') + 1 |
952 ## eoc = line.find('<') + 1 |
944 boc = line.find('>') |
953 ## boc = line.find('>') |
945 |
954 ## |
946 if boc >= 0 and eoc > boc: |
955 ## self.debugServer.signalClientOutput(line) |
947 resp = line[boc:eoc] |
956 ## if boc >= 0 and eoc > boc: |
948 |
957 ## resp = line[boc:eoc] |
|
958 ## |
949 ## if resp == DebugProtocol.ResponseLine or \ |
959 ## if resp == DebugProtocol.ResponseLine or \ |
950 ## resp == DebugProtocol.ResponseStack: |
960 ## resp == DebugProtocol.ResponseStack: |
951 ## stack = eval(line[eoc:-1]) |
961 ## stack = eval(line[eoc:-1]) |
952 ## for s in stack: |
962 ## for s in stack: |
953 ## s[0] = self.translate(s[0], True) |
963 ## s[0] = self.translate(s[0], True) |
1122 ## if resp == DebugProtocol.ResponseUTPrepared: |
1132 ## if resp == DebugProtocol.ResponseUTPrepared: |
1123 ## res, exc_type, exc_value = eval(line[eoc:-1]) |
1133 ## res, exc_type, exc_value = eval(line[eoc:-1]) |
1124 ## self.debugServer.clientUtPrepared(res, exc_type, exc_value) |
1134 ## self.debugServer.clientUtPrepared(res, exc_type, exc_value) |
1125 ## continue |
1135 ## continue |
1126 ## |
1136 ## |
1127 if resp == DebugProtocol.ResponseUTStartTest: |
1137 ## if resp == DebugProtocol.ResponseUTStartTest: |
1128 testname, doc = eval(line[eoc:-1]) |
1138 ## testname, doc = eval(line[eoc:-1]) |
1129 self.debugServer.clientUtStartTest(testname, doc) |
1139 ## self.debugServer.clientUtStartTest(testname, doc) |
1130 continue |
1140 ## continue |
1131 |
1141 ## |
1132 if resp == DebugProtocol.ResponseUTStopTest: |
1142 ## if resp == DebugProtocol.ResponseUTStopTest: |
1133 self.debugServer.clientUtStopTest() |
1143 ## self.debugServer.clientUtStopTest() |
1134 continue |
1144 ## continue |
1135 |
1145 ## |
1136 if resp == DebugProtocol.ResponseUTTestFailed: |
1146 ## if resp == DebugProtocol.ResponseUTTestFailed: |
1137 testname, traceback, id = eval(line[eoc:-1]) |
1147 ## testname, traceback, id = eval(line[eoc:-1]) |
1138 self.debugServer.clientUtTestFailed( |
1148 ## self.debugServer.clientUtTestFailed( |
1139 testname, traceback, id) |
1149 ## testname, traceback, id) |
1140 continue |
1150 ## continue |
1141 |
1151 ## |
1142 if resp == DebugProtocol.ResponseUTTestErrored: |
1152 ## if resp == DebugProtocol.ResponseUTTestErrored: |
1143 testname, traceback, id = eval(line[eoc:-1]) |
1153 ## testname, traceback, id = eval(line[eoc:-1]) |
1144 self.debugServer.clientUtTestErrored( |
1154 ## self.debugServer.clientUtTestErrored( |
1145 testname, traceback, id) |
1155 ## testname, traceback, id) |
1146 continue |
1156 ## continue |
1147 |
1157 ## |
1148 if resp == DebugProtocol.ResponseUTTestSkipped: |
1158 ## if resp == DebugProtocol.ResponseUTTestSkipped: |
1149 testname, reason, id = eval(line[eoc:-1]) |
1159 ## testname, reason, id = eval(line[eoc:-1]) |
1150 self.debugServer.clientUtTestSkipped(testname, reason, id) |
1160 ## self.debugServer.clientUtTestSkipped(testname, reason, id) |
1151 continue |
1161 ## continue |
1152 |
1162 ## |
1153 if resp == DebugProtocol.ResponseUTTestFailedExpected: |
1163 ## if resp == DebugProtocol.ResponseUTTestFailedExpected: |
1154 testname, traceback, id = eval(line[eoc:-1]) |
1164 ## testname, traceback, id = eval(line[eoc:-1]) |
1155 self.debugServer.clientUtTestFailedExpected( |
1165 ## self.debugServer.clientUtTestFailedExpected( |
1156 testname, traceback, id) |
1166 ## testname, traceback, id) |
1157 continue |
1167 ## continue |
1158 |
1168 ## |
1159 if resp == DebugProtocol.ResponseUTTestSucceededUnexpected: |
1169 ## if resp == DebugProtocol.ResponseUTTestSucceededUnexpected: |
1160 testname, id = eval(line[eoc:-1]) |
1170 ## testname, id = eval(line[eoc:-1]) |
1161 self.debugServer.clientUtTestSucceededUnexpected( |
1171 ## self.debugServer.clientUtTestSucceededUnexpected( |
1162 testname, id) |
1172 ## testname, id) |
1163 continue |
1173 ## continue |
1164 |
1174 ## |
1165 if resp == DebugProtocol.ResponseUTFinished: |
1175 ## if resp == DebugProtocol.ResponseUTFinished: |
1166 self.debugServer.clientUtFinished() |
1176 ## self.debugServer.clientUtFinished() |
1167 continue |
1177 ## continue |
1168 |
1178 ## |
1169 if resp == DebugProtocol.RequestForkTo: |
1179 ## if resp == DebugProtocol.RequestForkTo: |
1170 self.__askForkTo() |
1180 ## self.__askForkTo() |
1171 continue |
1181 ## continue |
1172 |
1182 ## |
1173 self.debugServer.signalClientOutput(line) |
1183 ## self.debugServer.signalClientOutput(line) |
1174 |
1184 |
1175 def __handleJsonCommand(self, jsonStr): |
1185 def __handleJsonCommand(self, jsonStr): |
1176 """ |
1186 """ |
1177 Private method to handle a command serialized as a JSON string. |
1187 Private method to handle a command serialized as a JSON string. |
1178 """ |
1188 """ |
1180 |
1190 |
1181 try: |
1191 try: |
1182 commandDict = json.loads(jsonStr.strip()) |
1192 commandDict = json.loads(jsonStr.strip()) |
1183 except json.JSONDecodeError as err: |
1193 except json.JSONDecodeError as err: |
1184 # TODO: implement real error handling |
1194 # TODO: implement real error handling |
1185 print(str(err)) |
1195 ## print(str(err)) |
1186 return |
1196 return |
1187 |
1197 |
1188 method = commandDict["method"] |
1198 method = commandDict["method"] |
1189 params = commandDict["params"] |
1199 params = commandDict["params"] |
1190 |
1200 |
1191 if method in ["ResponseLine", "ResponseStack"]: |
1201 if method == "ClientOutput": |
|
1202 self.debugServer.signalClientOutput(params["text"]) |
|
1203 |
|
1204 elif method in ["ResponseLine", "ResponseStack"]: |
1192 for s in params["stack"]: |
1205 for s in params["stack"]: |
1193 s[0] = self.translate(s[0], True) |
1206 s[0] = self.translate(s[0], True) |
1194 cf = params["stack"][0] |
1207 cf = params["stack"][0] |
1195 if self.__autoContinue: |
1208 if self.__autoContinue: |
1196 self.__autoContinue = False |
1209 self.__autoContinue = False |
1198 else: |
1211 else: |
1199 self.debugServer.signalClientLine( |
1212 self.debugServer.signalClientLine( |
1200 cf[0], int(cf[1]), |
1213 cf[0], int(cf[1]), |
1201 method == "ResponseStack") |
1214 method == "ResponseStack") |
1202 self.debugServer.signalClientStack(params["stack"]) |
1215 self.debugServer.signalClientStack(params["stack"]) |
1203 return |
1216 |
1204 |
1217 elif method == "CallTrace": |
1205 if method == "CallTrace": |
|
1206 isCall = params["event"].lower() == "c" |
1218 isCall = params["event"].lower() == "c" |
1207 fromFile, fromLineno, fromFunc = params["from"].rsplit(":", 2) |
1219 fromFile, fromLineno, fromFunc = params["from"].rsplit(":", 2) |
1208 toFile, toLineno, toFunc = params["to"].rsplit(":", 2) |
1220 toFile, toLineno, toFunc = params["to"].rsplit(":", 2) |
1209 self.debugServer.signalClientCallTrace( |
1221 self.debugServer.signalClientCallTrace( |
1210 isCall, |
1222 isCall, |
1211 fromFile, fromLineno, fromFunc, |
1223 fromFile, fromLineno, fromFunc, |
1212 toFile, toLineno, toFunc) |
1224 toFile, toLineno, toFunc) |
1213 return |
1225 |
1214 |
1226 elif method == "ResponseVariables": |
1215 if method == "ResponseVariables": |
|
1216 self.debugServer.signalClientVariables( |
1227 self.debugServer.signalClientVariables( |
1217 params["scope"], params["variables"]) |
1228 params["scope"], params["variables"]) |
1218 return |
1229 |
1219 |
1230 elif method == "ResponseVariable": |
1220 if method == "ResponseVariable": |
|
1221 self.debugServer.signalClientVariable( |
1231 self.debugServer.signalClientVariable( |
1222 params["scope"], [params["variable"]] + params["variables"]) |
1232 params["scope"], [params["variable"]] + params["variables"]) |
1223 return |
1233 |
1224 |
1234 elif method == "ResponseThreadList": |
1225 if method == "ResponseThreadList": |
|
1226 self.debugServer.signalClientThreadList( |
1235 self.debugServer.signalClientThreadList( |
1227 params["currentID"], params["threadList"]) |
1236 params["currentID"], params["threadList"]) |
1228 return |
1237 |
1229 |
1238 elif method == "ResponseThreadSet": |
1230 if method == "ResponseThreadSet": |
|
1231 self.debugServer.signalClientThreadSet() |
1239 self.debugServer.signalClientThreadSet() |
1232 return |
1240 |
1233 |
1241 elif method == "ResponseCapabilities": |
1234 if method == "ResponseCapabilities": |
|
1235 self.clientCapabilities = params["capabilities"] |
1242 self.clientCapabilities = params["capabilities"] |
1236 self.debugServer.signalClientCapabilities( |
1243 self.debugServer.signalClientCapabilities( |
1237 params["capabilities"], params["clientType"]) |
1244 params["capabilities"], params["clientType"]) |
1238 return |
1245 |
1239 |
1246 elif method == "ResponseBanner": |
1240 if method == "ResponseBanner": |
|
1241 self.debugServer.signalClientBanner( |
1247 self.debugServer.signalClientBanner( |
1242 params["version"], |
1248 params["version"], |
1243 params["platform"], |
1249 params["platform"], |
1244 params["dbgclient"]) |
1250 params["dbgclient"]) |
1245 return |
1251 |
1246 |
1252 elif method == "ResponseOK": |
1247 if method == "ResponseOK": |
|
1248 self.debugServer.signalClientStatement(False) |
1253 self.debugServer.signalClientStatement(False) |
1249 return |
1254 |
1250 |
1255 elif method == "ResponseContinue": |
1251 if method == "ResponseContinue": |
|
1252 self.debugServer.signalClientStatement(True) |
1256 self.debugServer.signalClientStatement(True) |
1253 return |
1257 |
1254 |
1258 elif method == "RequestRaw": |
1255 if method == "RequestRaw": |
|
1256 self.debugServer.signalClientRawInput( |
1259 self.debugServer.signalClientRawInput( |
1257 params["prompt"], params["echo"]) |
1260 params["prompt"], params["echo"]) |
1258 return |
1261 |
1259 |
1262 elif method == "ResponseBPConditionError": |
1260 if method == "ResponseBPConditionError": |
|
1261 params["filename"] = self.translate(params["filename"], True) |
1263 params["filename"] = self.translate(params["filename"], True) |
1262 self.debugServer.signalClientBreakConditionError( |
1264 self.debugServer.signalClientBreakConditionError( |
1263 params["filename"], params["line"]) |
1265 params["filename"], params["line"]) |
1264 return |
1266 |
1265 |
1267 elif method == "ResponseClearBreakpoint": |
1266 if method == "ResponseClearBreakpoint": |
|
1267 params["filename"] = self.translate(params["filename"], True) |
1268 params["filename"] = self.translate(params["filename"], True) |
1268 self.debugServer.signalClientClearBreak( |
1269 self.debugServer.signalClientClearBreak( |
1269 params["filename"], params["line"]) |
1270 params["filename"], params["line"]) |
1270 return |
1271 |
1271 |
1272 elif method == "ResponseWatchConditionError": |
1272 if method == "ResponseWatchConditionError": |
|
1273 self.debugServer.signalClientWatchConditionError( |
1273 self.debugServer.signalClientWatchConditionError( |
1274 params["condition"]) |
1274 params["condition"]) |
1275 return |
1275 |
1276 |
1276 elif method == "ResponseClearWatch": |
1277 if method == "ResponseClearWatch": |
|
1278 self.debugServer.signalClientClearWatch(params["condition"]) |
1277 self.debugServer.signalClientClearWatch(params["condition"]) |
1279 return |
1278 |
1280 |
1279 elif method == "ResponseException": |
1281 if method == "ResponseException": |
|
1282 if params: |
1280 if params: |
1283 exctype = params["type"] |
1281 exctype = params["type"] |
1284 excmessage = params["message"] |
1282 excmessage = params["message"] |
1285 stack = params["stack"] |
1283 stack = params["stack"] |
1286 if stack: |
1284 if stack: |
1291 if stackEntry[0] == "<string>": |
1289 if stackEntry[0] == "<string>": |
1292 stackEntry[0] = self.__scriptName |
1290 stackEntry[0] = self.__scriptName |
1293 else: |
1291 else: |
1294 break |
1292 break |
1295 else: |
1293 else: |
1296 exctype = None |
1294 exctype = '' |
1297 excmessage = '' |
1295 excmessage = '' |
1298 stack = [] |
1296 stack = [] |
1299 |
1297 |
1300 self.debugServer.signalClientException( |
1298 self.debugServer.signalClientException( |
1301 exctype, excmessage, stack) |
1299 exctype, excmessage, stack) |
1302 return |
1300 |
1303 |
1301 elif method == "ResponseSyntax": |
1304 if method == "ResponseSyntax": |
|
1305 self.debugServer.signalClientSyntaxError( |
1302 self.debugServer.signalClientSyntaxError( |
1306 params["message"], self.translate(params["filename"], True), |
1303 params["message"], self.translate(params["filename"], True), |
1307 params["linenumber"], params["characternumber"]) |
1304 params["linenumber"], params["characternumber"]) |
1308 return |
1305 |
1309 |
1306 elif method == "ResponseSignal": |
1310 if method == "ResponseSignal": |
|
1311 self.debugServer.signalClientSignal( |
1307 self.debugServer.signalClientSignal( |
1312 params["message"], self.translate(params["filename"], True), |
1308 params["message"], self.translate(params["filename"], True), |
1313 params["linenumber"], params["function"], params["arguments"]) |
1309 params["linenumber"], params["function"], params["arguments"]) |
1314 return |
1310 |
1315 |
1311 elif method == "ResponseExit": |
1316 if method == "ResponseExit": |
|
1317 self.__scriptName = "" |
1312 self.__scriptName = "" |
1318 self.debugServer.signalClientExit(params["status"]) |
1313 self.debugServer.signalClientExit(params["status"]) |
1319 return |
1314 if params["message"]: |
1320 |
1315 self.debugServer.signalClientOutput(params["message"]) |
1321 if method == "PassiveStartup": |
1316 |
|
1317 elif method == "PassiveStartup": |
1322 self.debugServer.passiveStartUp( |
1318 self.debugServer.passiveStartUp( |
1323 self.translate(params["filename"], True), params["exceptions"]) |
1319 self.translate(params["filename"], True), params["exceptions"]) |
1324 return |
1320 |
1325 |
1321 elif method == "ResponseCompletion": |
1326 if method == "ResponseCompletion": |
|
1327 self.debugServer.signalClientCompletionList( |
1322 self.debugServer.signalClientCompletionList( |
1328 params["completions"], params["text"]) |
1323 params["completions"], params["text"]) |
1329 return |
1324 |
1330 |
1325 elif method == "ResponseUTPrepared": |
1331 if method == "ResponseUTPrepared": |
|
1332 self.debugServer.clientUtPrepared( |
1326 self.debugServer.clientUtPrepared( |
1333 params["count"], params["exception"], params["message"]) |
1327 params["count"], params["exception"], params["message"]) |
1334 return |
1328 |
|
1329 elif method == "ResponseUTFinished": |
|
1330 self.debugServer.clientUtFinished() |
|
1331 |
|
1332 elif method == "ResponseUTStartTest": |
|
1333 self.debugServer.clientUtStartTest( |
|
1334 params["testname"], params["description"]) |
|
1335 |
|
1336 elif method == "ResponseUTStopTest": |
|
1337 self.debugServer.clientUtStopTest() |
|
1338 |
|
1339 elif method == "ResponseUTTestFailed": |
|
1340 self.debugServer.clientUtTestFailed( |
|
1341 params["testname"], params["traceback"], params["id"]) |
|
1342 |
|
1343 elif method == "ResponseUTTestErrored": |
|
1344 self.debugServer.clientUtTestErrored( |
|
1345 params["testname"], params["traceback"], params["id"]) |
|
1346 |
|
1347 elif method == "ResponseUTTestSkipped": |
|
1348 self.debugServer.clientUtTestSkipped( |
|
1349 params["testname"], params["reason"], params["id"]) |
|
1350 |
|
1351 elif method == "ResponseUTTestFailedExpected": |
|
1352 self.debugServer.clientUtTestFailedExpected( |
|
1353 params["testname"], params["traceback"], params["id"]) |
|
1354 |
|
1355 elif method == "ResponseUTTestSucceededUnexpected": |
|
1356 self.debugServer.clientUtTestSucceededUnexpected( |
|
1357 params["testname"], params["id"]) |
|
1358 |
|
1359 elif method == "RequestForkTo": |
|
1360 self.__askForkTo() |
1335 |
1361 |
1336 def __sendCommand(self, cmd): |
1362 def __sendCommand(self, cmd): |
1337 """ |
1363 """ |
1338 Private method to send a single line command to the client. |
1364 Private method to send a single line command to the client. |
1339 |
1365 |