LLDB mainline
Statusline.cpp
Go to the documentation of this file.
1//===-- Statusline.cpp ---------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
10#include "lldb/Core/Debugger.h"
15#include "lldb/Target/Process.h"
19#include "llvm/ADT/StringRef.h"
20#include "llvm/Support/Locale.h"
21
22#define ESCAPE "\x1b"
23#define ANSI_NORMAL ESCAPE "[0m"
24#define ANSI_SAVE_CURSOR ESCAPE "7"
25#define ANSI_RESTORE_CURSOR ESCAPE "8"
26#define ANSI_CLEAR_BELOW ESCAPE "[J"
27#define ANSI_CLEAR_SCREEN ESCAPE "[2J"
28#define ANSI_SET_SCROLL_ROWS ESCAPE "[1;%ur"
29#define ANSI_TO_START_OF_ROW ESCAPE "[%u;1f"
30#define ANSI_REVERSE_VIDEO ESCAPE "[7m"
31#define ANSI_UP_ROWS ESCAPE "[%dA"
32
33using namespace lldb;
34using namespace lldb_private;
35
37 : m_debugger(debugger), m_terminal_width(m_debugger.GetTerminalWidth()),
38 m_terminal_height(m_debugger.GetTerminalHeight()) {
39 Enable();
40}
41
43
45 m_terminal_width = m_debugger.GetTerminalWidth();
46 m_terminal_height = m_debugger.GetTerminalHeight();
47
49
50 // Draw the old statusline.
51 Redraw(/*update=*/false);
52}
53
55 // Reduce the scroll window to make space for the status bar below.
57
58 // Draw the statusline.
59 Redraw(/*update=*/true);
60}
61
63 // Extend the scroll window to cover the status bar.
65}
66
67void Statusline::Draw(std::string str) {
68 lldb::LockableStreamFileSP stream_sp = m_debugger.GetOutputStreamSP();
69 if (!stream_sp)
70 return;
71
72 m_last_str = str;
73
75
76 LockedStreamFile locked_stream = stream_sp->Lock();
77 locked_stream << ANSI_SAVE_CURSOR;
78 locked_stream.Printf(ANSI_TO_START_OF_ROW,
79 static_cast<unsigned>(m_terminal_height));
80
81 // Use "reverse video" to make sure the statusline has a background. Only do
82 // this when colors are disabled, and rely on the statusline format otherwise.
83 if (!m_debugger.GetUseColor())
84 locked_stream << ANSI_REVERSE_VIDEO;
85
86 locked_stream << str;
87 locked_stream << ANSI_NORMAL;
88 locked_stream << ANSI_RESTORE_CURSOR;
89}
90
92 assert(m_terminal_width != 0 && m_terminal_height != 0);
93
94 lldb::LockableStreamFileSP stream_sp = m_debugger.GetOutputStreamSP();
95 if (!stream_sp)
96 return;
97
98 const unsigned reduced_scroll_window = m_terminal_height - 1;
99 LockedStreamFile locked_stream = stream_sp->Lock();
100
101 switch (mode) {
102 case EnableStatusline:
103 // Move everything on the screen up.
104 locked_stream << '\n';
105 locked_stream.Printf(ANSI_UP_ROWS, 1);
106 // Reduce the scroll window.
107 locked_stream << ANSI_SAVE_CURSOR;
108 locked_stream.Printf(ANSI_SET_SCROLL_ROWS, reduced_scroll_window);
109 locked_stream << ANSI_RESTORE_CURSOR;
110 break;
112 // Reset the scroll window.
113 locked_stream << ANSI_SAVE_CURSOR;
114 locked_stream.Printf(ANSI_SET_SCROLL_ROWS, 0);
115 locked_stream << ANSI_RESTORE_CURSOR;
116 // Clear the screen below to hide the old statusline.
117 locked_stream << ANSI_CLEAR_BELOW;
118 break;
119 case ResizeStatusline:
120 // Clear the screen and update the scroll window.
121 // FIXME: Find a better solution (#146919).
122 locked_stream << ANSI_CLEAR_SCREEN;
123 locked_stream.Printf(ANSI_SET_SCROLL_ROWS, reduced_scroll_window);
124 break;
125 }
126
127 m_debugger.RefreshIOHandler();
128}
129
130void Statusline::Redraw(bool update) {
131 if (!update) {
133 return;
134 }
135
136 ExecutionContext exe_ctx = m_debugger.GetSelectedExecutionContext();
137
138 // For colors and progress events, the format entity needs access to the
139 // debugger, which requires a target in the execution context.
140 if (!exe_ctx.HasTargetScope())
141 exe_ctx.SetTargetPtr(&m_debugger.GetSelectedOrDummyTarget());
142
143 SymbolContext symbol_ctx;
144 if (ProcessSP process_sp = exe_ctx.GetProcessSP()) {
145 // Check if the process is stopped, and if it is, make sure it remains
146 // stopped until we've computed the symbol context.
147 Process::StopLocker stop_locker;
148 if (stop_locker.TryLock(&process_sp->GetRunLock())) {
149 if (auto frame_sp = exe_ctx.GetFrameSP())
150 symbol_ctx = frame_sp->GetSymbolContext(eSymbolContextEverything);
151 }
152 }
153
154 StreamString stream;
155 FormatEntity::Entry format = m_debugger.GetStatuslineFormat();
156 FormatEntity::Format(format, stream, &symbol_ctx, &exe_ctx, nullptr, nullptr,
157 false, false);
158
159 Draw(stream.GetString().str());
160}
#define ANSI_SET_SCROLL_ROWS
#define ANSI_TO_START_OF_ROW
#define ANSI_CLEAR_SCREEN
#define ANSI_UP_ROWS
#define ANSI_SAVE_CURSOR
#define ANSI_NORMAL
#define ANSI_RESTORE_CURSOR
#define ANSI_REVERSE_VIDEO
#define ANSI_CLEAR_BELOW
A class to manage flag bits.
Definition Debugger.h:80
"lldb/Target/ExecutionContext.h" A class that contains an execution context.
const lldb::ProcessSP & GetProcessSP() const
Get accessor to get the process shared pointer.
void SetTargetPtr(Target *target)
Set accessor to set only the target shared pointer from a target pointer.
const lldb::StackFrameSP & GetFrameSP() const
Get accessor to get the frame shared pointer.
bool HasTargetScope() const
Returns true the ExecutionContext object contains a valid target.
ProcessRunLock::ProcessRunLocker StopLocker
Definition Process.h:396
void UpdateScrollWindow(ScrollWindowMode mode)
Set the scroll window for the given mode.
void Enable()
Reduce the scroll window and draw the statusline.
void TerminalSizeChanged()
Inform the statusline that the terminal dimensions have changed.
Statusline(Debugger &debugger)
void Disable()
Hide the statusline and extend the scroll window.
void Redraw(bool update=true)
Redraw the statusline.
void Draw(std::string msg)
Draw the statusline with the given text.
llvm::StringRef GetString() const
size_t Printf(const char *format,...) __attribute__((format(printf
Output printf formatted output to the stream.
Definition Stream.cpp:134
Defines a symbol context baton that can be handed other debug core functions.
bool Format(const Entry &entry, Stream &s, const SymbolContext *sc, const ExecutionContext *exe_ctx, const Address *addr, ValueObject *valobj, bool function_changed, bool initial_function)
std::string TrimAndPad(llvm::StringRef str, size_t visible_length, char padding=' ')
A class that represents a running process on the host machine.
std::shared_ptr< lldb_private::Process > ProcessSP
std::shared_ptr< lldb_private::LockableStreamFile > LockableStreamFileSP