|
5 | 5 | import threading |
6 | 6 | import socket |
7 | 7 | import traceback |
| 8 | +from enum import Enum |
8 | 9 | from lldbsuite.support import seven |
9 | | -from typing import Optional, List, Tuple, Literal |
| 10 | +from typing import Optional, List, Tuple, Literal, Union, Sequence |
10 | 11 |
|
11 | 12 |
|
12 | 13 | def checksum(message): |
@@ -90,21 +91,29 @@ class MockGDBServerResponder: |
90 | 91 |
|
91 | 92 | registerCount: int = 40 |
92 | 93 |
|
93 | | - class RESPONSE_DISCONNECT: |
94 | | - pass |
| 94 | + class SpecialResponse(Enum): |
| 95 | + RESPONSE_DISCONNECT = 0 |
| 96 | + RESPONSE_NONE = 1 |
95 | 97 |
|
96 | | - class RESPONSE_NONE: |
97 | | - pass |
| 98 | + RESPONSE_DISCONNECT = SpecialResponse.RESPONSE_DISCONNECT |
| 99 | + RESPONSE_NONE = SpecialResponse.RESPONSE_NONE |
| 100 | + type Response = Union[str, SpecialResponse] |
98 | 101 |
|
99 | 102 | def __init__(self): |
100 | 103 | self.packetLog: List[str] = [] |
101 | 104 |
|
102 | | - def respond(self, packet): |
| 105 | + def respond(self, packet: str) -> Sequence[Response]: |
103 | 106 | """ |
104 | 107 | Return the unframed packet data that the server should issue in response |
105 | 108 | to the given packet received from the client. |
106 | 109 | """ |
107 | 110 | self.packetLog.append(packet) |
| 111 | + response = self._respond_impl(packet) |
| 112 | + if not isinstance(response, list): |
| 113 | + response = [response] |
| 114 | + return response |
| 115 | + |
| 116 | + def _respond_impl(self, packet) -> Union[Response, List[Response]]: |
108 | 117 | if packet is MockGDBServer.PACKET_INTERRUPT: |
109 | 118 | return self.interrupt() |
110 | 119 | if packet == "c": |
@@ -668,24 +677,28 @@ def _handlePacket(self, packet): |
668 | 677 | # adding validation code to make sure the client only sends ACKs |
669 | 678 | # when it's supposed to. |
670 | 679 | return |
671 | | - response = "" |
| 680 | + response = [""] |
672 | 681 | # We'll handle the ack stuff here since it's not something any of the |
673 | 682 | # tests will be concerned about, and it'll get turned off quickly anyway. |
674 | 683 | if self._shouldSendAck: |
675 | 684 | self._socket.sendall(seven.bitcast_to_bytes("+")) |
676 | 685 | if packet == "QStartNoAckMode": |
677 | 686 | self._shouldSendAck = False |
678 | | - response = "OK" |
| 687 | + response = ["OK"] |
679 | 688 | elif self.responder is not None: |
680 | 689 | # Delegate everything else to our responder |
681 | 690 | response = self.responder.respond(packet) |
| 691 | + # MockGDBServerResponder no longer returns non-lists but others like |
| 692 | + # ReverseTestBase still do |
682 | 693 | if not isinstance(response, list): |
683 | 694 | response = [response] |
684 | 695 | for part in response: |
685 | 696 | if part is MockGDBServerResponder.RESPONSE_NONE: |
686 | 697 | continue |
687 | 698 | if part is MockGDBServerResponder.RESPONSE_DISCONNECT: |
688 | 699 | raise self.TerminateConnectionException() |
| 700 | + # Should have handled the non-str's above |
| 701 | + assert isinstance(part, str) |
689 | 702 | self._sendPacket(part) |
690 | 703 |
|
691 | 704 | PACKET_ACK = object() |
|
0 commit comments