tools/mpremote: Add repl option to escape non-printable characters.

This commit adds the "--escape-non-printable" option to the repl command.
When specified the REPL console will escape non-printable characters,
printing them as their hex value in square brackets.

This escaping behaviour was previously the default and only behaviour, but
it is now opt-in.

As part of this change, the speed of echoing device data to the console is
improved by by reading and writing in chunks.

Signed-off-by: Damien George <damien@micropython.org>
pull/11467/head
Damien George 2023-05-11 13:24:14 +10:00
rodzic a802f71908
commit 2771b20d29
3 zmienionych plików z 21 dodań i 8 usunięć

Wyświetl plik

@ -92,6 +92,7 @@ The full list of supported commands are:
Options are:
- ``--escape-non-printable``, to print non-printable bytes/characters as their hex code
- ``--capture <file>``, to capture output of the REPL session to the given
file
- ``--inject-code <string>``, to specify characters to inject at the REPL when

Wyświetl plik

@ -119,6 +119,7 @@ def argparse_mount():
def argparse_repl():
cmd_parser = argparse.ArgumentParser(description="connect to given device")
_bool_flag(cmd_parser, "escape-non-printable", "e", False, "escape non-printable characters")
cmd_parser.add_argument(
"--capture",
type=str,

Wyświetl plik

@ -3,7 +3,9 @@ from .console import Console, ConsolePosix
from . import pyboardextended as pyboard
def do_repl_main_loop(state, console_in, console_out_write, *, code_to_inject, file_to_inject):
def do_repl_main_loop(
state, console_in, console_out_write, *, escape_non_printable, code_to_inject, file_to_inject
):
while True:
console_in.waitchar(state.pyb.serial)
c = console_in.readchar()
@ -37,26 +39,34 @@ def do_repl_main_loop(state, console_in, console_out_write, *, code_to_inject, f
break
if n > 0:
c = state.pyb.serial.read(1)
if c is not None:
# pass character through to the console
oc = ord(c)
if oc in (8, 9, 10, 13, 27) or 32 <= oc <= 126:
console_out_write(c)
dev_data_in = state.pyb.serial.read(n)
if dev_data_in is not None:
if escape_non_printable:
# Pass data through to the console, with escaping of non-printables.
console_data_out = bytearray()
for c in dev_data_in:
if c in (8, 9, 10, 13, 27) or 32 <= c <= 126:
console_data_out.append(c)
else:
console_data_out.extend(b"[%02x]" % c)
else:
console_out_write(b"[%02x]" % ord(c))
console_data_out = dev_data_in
console_out_write(console_data_out)
def do_repl(state, args):
state.ensure_friendly_repl()
state.did_action()
escape_non_printable = args.escape_non_printable
capture_file = args.capture
code_to_inject = args.inject_code
file_to_inject = args.inject_file
print("Connected to MicroPython at %s" % state.pyb.device_name)
print("Use Ctrl-] or Ctrl-x to exit this shell")
if escape_non_printable:
print("Escaping non-printable bytes/characters by printing their hex code")
if capture_file is not None:
print('Capturing session to file "%s"' % capture_file)
capture_file = open(capture_file, "wb")
@ -80,6 +90,7 @@ def do_repl(state, args):
state,
console,
console_out_write,
escape_non_printable=escape_non_printable,
code_to_inject=code_to_inject,
file_to_inject=file_to_inject,
)