Jonas Devlieghere 850e90c47b
[lldb] Support Unicode in the prompt (#66312)
Account for Unicode when computing the prompt column width. Previously,
the string length (i.e. number of bytes) rather than the width of the
Glyph was used to compute the cursor position. The result was that the
cursor would be offset to the right when using a prompt containing
Unicode.
2023-09-13 20:08:05 -07:00

103 lines
3.0 KiB
Python

# System modules
import os
import sys
# LLDB Modules
import lldb
from .lldbtest import *
from . import lldbutil
from lldbsuite.test.decorators import *
@skipIfRemote
@skipIfWindows # llvm.org/pr22274: need a pexpect replacement for windows
class PExpectTest(TestBase):
NO_DEBUG_INFO_TESTCASE = True
PROMPT = "(lldb) "
def expect_prompt(self):
self.child.expect_exact(self.PROMPT)
def launch(
self,
executable=None,
extra_args=None,
timeout=60,
dimensions=None,
run_under=None,
post_spawn=None,
encoding=None,
use_colors=False,
):
logfile = getattr(sys.stdout, "buffer", sys.stdout) if self.TraceOn() else None
args = []
if run_under is not None:
args += run_under
args += [lldbtest_config.lldbExec, "--no-lldbinit"]
if not use_colors:
args.append("--no-use-colors")
for cmd in self.setUpCommands():
if "use-color false" in cmd and use_colors:
continue
args += ["-O", cmd]
if executable is not None:
args += ["--file", executable]
if extra_args is not None:
args.extend(extra_args)
env = dict(os.environ)
env["TERM"] = "vt100"
env["HOME"] = self.getBuildDir()
import pexpect
self.child = pexpect.spawn(
args[0],
args=args[1:],
logfile=logfile,
timeout=timeout,
dimensions=dimensions,
env=env,
encoding=encoding,
)
self.child.ptyproc.delayafterclose = timeout / 10
self.child.ptyproc.delayafterterminate = timeout / 10
if post_spawn is not None:
post_spawn()
self.expect_prompt()
for cmd in self.setUpCommands():
if "use-color false" in cmd and use_colors:
continue
self.child.expect_exact(cmd)
self.expect_prompt()
if executable is not None:
self.child.expect_exact("target create")
self.child.expect_exact("Current executable set to")
self.expect_prompt()
def expect(self, cmd, substrs=None):
self.assertNotIn("\n", cmd)
# If 'substrs' is a string then this code would just check that every
# character of the string is in the output.
assert not isinstance(substrs, str), "substrs must be a collection of strings"
self.child.sendline(cmd)
if substrs is not None:
for s in substrs:
self.child.expect_exact(s)
self.expect_prompt()
def quit(self, gracefully=True):
self.child.sendeof()
self.child.close(force=not gracefully)
self.child = None
def cursor_forward_escape_seq(self, chars_to_move):
"""
Returns the escape sequence to move the cursor forward/right
by a certain amount of characters.
"""
return b"\x1b\[" + str(chars_to_move).encode("utf-8") + b"C"