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>
This commit is contained in:
parent
a802f71908
commit
2771b20d29
|
@ -92,6 +92,7 @@ The full list of supported commands are:
|
||||||
|
|
||||||
Options 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
|
- ``--capture <file>``, to capture output of the REPL session to the given
|
||||||
file
|
file
|
||||||
- ``--inject-code <string>``, to specify characters to inject at the REPL when
|
- ``--inject-code <string>``, to specify characters to inject at the REPL when
|
||||||
|
|
|
@ -119,6 +119,7 @@ def argparse_mount():
|
||||||
|
|
||||||
def argparse_repl():
|
def argparse_repl():
|
||||||
cmd_parser = argparse.ArgumentParser(description="connect to given device")
|
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(
|
cmd_parser.add_argument(
|
||||||
"--capture",
|
"--capture",
|
||||||
type=str,
|
type=str,
|
||||||
|
|
|
@ -3,7 +3,9 @@ from .console import Console, ConsolePosix
|
||||||
from . import pyboardextended as pyboard
|
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:
|
while True:
|
||||||
console_in.waitchar(state.pyb.serial)
|
console_in.waitchar(state.pyb.serial)
|
||||||
c = console_in.readchar()
|
c = console_in.readchar()
|
||||||
|
@ -37,26 +39,34 @@ def do_repl_main_loop(state, console_in, console_out_write, *, code_to_inject, f
|
||||||
break
|
break
|
||||||
|
|
||||||
if n > 0:
|
if n > 0:
|
||||||
c = state.pyb.serial.read(1)
|
dev_data_in = state.pyb.serial.read(n)
|
||||||
if c is not None:
|
if dev_data_in is not None:
|
||||||
# pass character through to the console
|
if escape_non_printable:
|
||||||
oc = ord(c)
|
# Pass data through to the console, with escaping of non-printables.
|
||||||
if oc in (8, 9, 10, 13, 27) or 32 <= oc <= 126:
|
console_data_out = bytearray()
|
||||||
console_out_write(c)
|
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:
|
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):
|
def do_repl(state, args):
|
||||||
state.ensure_friendly_repl()
|
state.ensure_friendly_repl()
|
||||||
state.did_action()
|
state.did_action()
|
||||||
|
|
||||||
|
escape_non_printable = args.escape_non_printable
|
||||||
capture_file = args.capture
|
capture_file = args.capture
|
||||||
code_to_inject = args.inject_code
|
code_to_inject = args.inject_code
|
||||||
file_to_inject = args.inject_file
|
file_to_inject = args.inject_file
|
||||||
|
|
||||||
print("Connected to MicroPython at %s" % state.pyb.device_name)
|
print("Connected to MicroPython at %s" % state.pyb.device_name)
|
||||||
print("Use Ctrl-] or Ctrl-x to exit this shell")
|
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:
|
if capture_file is not None:
|
||||||
print('Capturing session to file "%s"' % capture_file)
|
print('Capturing session to file "%s"' % capture_file)
|
||||||
capture_file = open(capture_file, "wb")
|
capture_file = open(capture_file, "wb")
|
||||||
|
@ -80,6 +90,7 @@ def do_repl(state, args):
|
||||||
state,
|
state,
|
||||||
console,
|
console,
|
||||||
console_out_write,
|
console_out_write,
|
||||||
|
escape_non_printable=escape_non_printable,
|
||||||
code_to_inject=code_to_inject,
|
code_to_inject=code_to_inject,
|
||||||
file_to_inject=file_to_inject,
|
file_to_inject=file_to_inject,
|
||||||
)
|
)
|
||||||
|
|
Loading…
Reference in New Issue