Files
clang-p2996/lldb/test/API/functionalities/statusline/TestStatusline.py
David Spickett 6ec48b449f [lldb] Use 1 based row and column for statusline (#143385)
I can't find a proper source for this but many materials say that ANSI
rows and columns start at 1 not 0.

https://www2.math.upenn.edu/~kazdan/210/computer/ansi.html is as good as
I can get:
```
<row> is a number from 1 through 25 that specifies the row to which the cursor is to be moved.
<col> is a number from 1 through 80 that specifies the column to which the cursor is to be moved.
```

0 does work in Windows terminal and Linux terminals, but we might as
well be correct and it's one less thing to reason about when auditing
this code.

From what I read, some terminals correct 0 back to 1 and some treat 0 as
a missing argument, which also defaults to 1.
2025-06-10 09:59:16 +01:00

107 lines
3.5 KiB
Python

import lldb
import re
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
from lldbsuite.test.lldbpexpect import PExpectTest
# PExpect uses many timeouts internally and doesn't play well
# under ASAN on a loaded machine..
@skipIfAsan
class TestStatusline(PExpectTest):
# Change this value to something smaller to make debugging this test less
# tedious.
TIMEOUT = 60
TERMINAL_HEIGHT = 10
TERMINAL_WIDTH = 60
def do_setup(self):
# Create a target and run to a breakpoint.
exe = self.getBuildArtifact("a.out")
self.expect(
"target create {}".format(exe), substrs=["Current executable set to"]
)
self.expect('breakpoint set -p "Break here"', substrs=["Breakpoint 1"])
self.expect("run", substrs=["stop reason"])
self.resize()
def resize(self):
# Change the terminal dimensions. When we launch the tests, we reset
# all the settings, leaving the terminal dimensions unset.
self.child.setwinsize(self.TERMINAL_HEIGHT, self.TERMINAL_WIDTH)
def test(self):
"""Basic test for the statusline."""
self.build()
self.launch(timeout=self.TIMEOUT)
self.do_setup()
# Enable the statusline and check for the control character and that we
# can see the target, the location and the stop reason.
self.expect('set set separator "| "')
self.expect(
"set set show-statusline true",
[
"\x1b[1;{}r".format(self.TERMINAL_HEIGHT - 1),
"a.out | main.c:2:11 | breakpoint 1.1 ",
],
)
# Change the terminal dimensions and make sure it's reflected immediately.
self.child.setwinsize(self.TERMINAL_HEIGHT, 25)
self.child.expect(re.escape("a.out | main.c:2:11 | bre"))
self.child.setwinsize(self.TERMINAL_HEIGHT, self.TERMINAL_WIDTH)
# Change the separator.
self.expect('set set separator "S "', ["a.out S main.c:2:11"])
# Change the format.
self.expect(
'set set statusline-format "target = {${target.file.basename}} ${separator}"',
["target = a.out S"],
)
self.expect('set set separator "| "')
# Hide the statusline and check or the control character.
self.expect(
"set set show-statusline false", ["\x1b[1;{}r".format(self.TERMINAL_HEIGHT)]
)
def test_no_color(self):
"""Basic test for the statusline with colors disabled."""
self.build()
self.launch(use_colors=False, timeout=self.TIMEOUT)
self.do_setup()
# Enable the statusline and check for the "reverse video" control character.
self.expect(
"set set show-statusline true",
[
"\x1b[7m",
],
)
def test_deadlock(self):
"""Regression test for lock inversion between the statusline mutex and
the output mutex."""
self.build()
self.launch(
extra_args=["-o", "settings set use-color false"], timeout=self.TIMEOUT
)
self.child.expect("(lldb)")
self.resize()
exe = self.getBuildArtifact("a.out")
self.expect("file {}".format(exe), ["Current executable"])
self.expect("help", ["Debugger commands"])
def test_no_target(self):
"""Test that we print "no target" when launched without a target."""
self.launch(timeout=self.TIMEOUT)
self.resize()
self.expect("set set show-statusline true", ["no target"])