Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions lldb/include/lldb/Host/Terminal.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,18 @@ class Terminal {

llvm::Error SetHardwareFlowControl(bool enabled);

/// Returns whether or not the current terminal supports Unicode rendering.
///
/// The value is cached after the first computation.
///
/// On POSIX systems, we check if the LANG environment variable contains the
/// substring "UTF-8", case insensitive.
///
/// On Windows, we always return true since we use the `WriteConsoleW` API
/// internally. Note that the default Windows codepage (437) does not support
/// all Unicode characters. This function does not check the codepage.
static bool SupportsUnicode();

protected:
struct Data;

Expand Down
11 changes: 11 additions & 0 deletions lldb/include/lldb/Host/common/DiagnosticsRendering.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,17 @@ void RenderDiagnosticDetails(Stream &stream,
bool show_inline,
llvm::ArrayRef<DiagnosticDetail> details);

/// Returns whether or not the current terminal supports Unicode rendering.
///
/// The value is cached after the first computation.
///
/// On POSIX systems, we check if the LANG environment variable contains the
/// substring "UTF-8";
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's so much better than checking for color!

///
/// On Windows, we check that we are running from the Windows Terminal
/// application.
bool TerminalSupportsUnicode();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we move this into Host/Terminal.h?


class DiagnosticError
: public llvm::ErrorInfo<DiagnosticError, CloneableECError> {
public:
Expand Down
4 changes: 2 additions & 2 deletions lldb/include/lldb/Target/StackFrame.h
Original file line number Diff line number Diff line change
Expand Up @@ -354,7 +354,7 @@ class StackFrame : public ExecutionContextScope,
/// \param [in] frame_marker
/// Optional string that will be prepended to the frame output description.
void DumpUsingSettingsFormat(Stream *strm, bool show_unique = false,
const char *frame_marker = nullptr);
llvm::StringRef frame_marker = "");

/// Print a description for this frame using a default format.
///
Expand Down Expand Up @@ -390,7 +390,7 @@ class StackFrame : public ExecutionContextScope,
/// \return
/// Returns true if successful.
bool GetStatus(Stream &strm, bool show_frame_info, bool show_source,
bool show_unique = false, const char *frame_marker = nullptr);
bool show_unique = false, llvm::StringRef frame_marker = "");

/// Query whether this frame is a concrete frame on the call stack, or if it
/// is an inlined frame derived from the debug information and presented by
Expand Down
11 changes: 10 additions & 1 deletion lldb/include/lldb/Target/StackFrameList.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,15 @@ class StackFrameList {
/// Resets the selected frame index of this object.
void ClearSelectedFrameIndex();

/// Return \code true if the next frame is hidden.
bool IsNextFrameHidden(lldb_private::StackFrame &frame);

/// Return \code true if the previous frame is hidden.
bool IsPreviousFrameHidden(lldb_private::StackFrame &frame);

std::wstring FrameMarker(lldb::StackFrameSP frame_sp,
lldb::StackFrameSP selected_frame_sp);

/// Get the currently selected frame index.
/// We should only call SelectMostRelevantFrame if (a) the user hasn't already
/// selected a frame, and (b) if this really is a user facing
Expand Down Expand Up @@ -96,7 +105,7 @@ class StackFrameList {
size_t GetStatus(Stream &strm, uint32_t first_frame, uint32_t num_frames,
bool show_frame_info, uint32_t num_frames_with_source,
bool show_unique = false, bool show_hidden = false,
const char *frame_marker = nullptr);
bool show_selected_frame = false);

/// Returns whether we have currently fetched all the frames of a stack.
bool WereAllFramesFetched() const;
Expand Down
4 changes: 2 additions & 2 deletions lldb/source/Host/common/DiagnosticsRendering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
//===----------------------------------------------------------------------===//

#include "lldb/Host/common/DiagnosticsRendering.h"
#include "lldb/Host/Terminal.h"
#include <cstdint>

using namespace lldb_private;
Expand Down Expand Up @@ -102,7 +103,7 @@ void RenderDiagnosticDetails(Stream &stream,
// characters. In the future it might make sense to move this into
// Host so it can be customized for a specific platform.
llvm::StringRef cursor, underline, vbar, joint, hbar, spacer;
if (stream.AsRawOstream().colors_enabled()) {
if (Terminal::SupportsUnicode()) {
cursor = "˄";
underline = "˜";
vbar = "│";
Expand Down Expand Up @@ -231,5 +232,4 @@ void RenderDiagnosticDetails(Stream &stream,
stream << detail.rendered << '\n';
}
}

} // namespace lldb_private
15 changes: 15 additions & 0 deletions lldb/source/Host/common/Terminal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -400,6 +400,21 @@ llvm::Error Terminal::SetHardwareFlowControl(bool enabled) {
#endif // LLDB_ENABLE_TERMIOS
}

bool Terminal::SupportsUnicode() {
static std::optional<bool> result;
if (result)
return result.value();
#ifdef _WIN32
return true;
#else
const char *lang_var = std::getenv("LANG");
if (!lang_var)
return false;
result = llvm::StringRef(lang_var).lower().find("utf-8") != std::string::npos;
#endif
return result.value();
}

TerminalState::TerminalState(Terminal term, bool save_process_group)
: m_tty(term) {
Save(term, save_process_group);
Expand Down
5 changes: 3 additions & 2 deletions lldb/source/Target/StackFrame.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1935,7 +1935,7 @@ bool StackFrame::DumpUsingFormat(Stream &strm,
}

void StackFrame::DumpUsingSettingsFormat(Stream *strm, bool show_unique,
const char *frame_marker) {
llvm::StringRef frame_marker) {
if (strm == nullptr)
return;

Expand All @@ -1953,6 +1953,7 @@ void StackFrame::DumpUsingSettingsFormat(Stream *strm, bool show_unique,
frame_format = &format_entry;
}
}

if (!DumpUsingFormat(*strm, frame_format, frame_marker)) {
Dump(strm, true, false);
strm->EOL();
Expand Down Expand Up @@ -2034,7 +2035,7 @@ bool StackFrame::HasCachedData() const {
}

bool StackFrame::GetStatus(Stream &strm, bool show_frame_info, bool show_source,
bool show_unique, const char *frame_marker) {
bool show_unique, llvm::StringRef frame_marker) {
if (show_frame_info) {
strm.Indent();
DumpUsingSettingsFormat(&strm, show_unique, frame_marker);
Expand Down
57 changes: 41 additions & 16 deletions lldb/source/Target/StackFrameList.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include "lldb/Utility/LLDBLog.h"
#include "lldb/Utility/Log.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/Support/ConvertUTF.h"

#include <memory>

Expand Down Expand Up @@ -879,11 +880,42 @@ StackFrameList::GetStackFrameSPForStackFramePtr(StackFrame *stack_frame_ptr) {
return ret_sp;
}

bool StackFrameList::IsNextFrameHidden(lldb_private::StackFrame &frame) {
uint32_t frame_idx = frame.GetFrameIndex();
StackFrameSP frame_sp = GetFrameAtIndex(frame_idx + 1);
if (!frame_sp)
return false;
return frame_sp->IsHidden();
}

bool StackFrameList::IsPreviousFrameHidden(lldb_private::StackFrame &frame) {
uint32_t frame_idx = frame.GetFrameIndex();
if (frame_idx == 0)
return false;
StackFrameSP frame_sp = GetFrameAtIndex(frame_idx - 1);
if (!frame_sp)
return false;
return frame_sp->IsHidden();
}

std::wstring StackFrameList::FrameMarker(lldb::StackFrameSP frame_sp,
lldb::StackFrameSP selected_frame_sp) {
if (frame_sp == selected_frame_sp)
return Terminal::SupportsUnicode() ? L" * " : L"* ";
else if (!Terminal::SupportsUnicode())
return L" ";
else if (IsPreviousFrameHidden(*frame_sp))
return L" ﹉";
else if (IsNextFrameHidden(*frame_sp))
return L" ﹍";
return L"  ";
}

size_t StackFrameList::GetStatus(Stream &strm, uint32_t first_frame,
uint32_t num_frames, bool show_frame_info,
uint32_t num_frames_with_source,
bool show_unique, bool show_hidden,
const char *selected_frame_marker) {
bool show_selected_frame) {
size_t num_frames_displayed = 0;

if (num_frames == 0)
Expand All @@ -901,25 +933,17 @@ size_t StackFrameList::GetStatus(Stream &strm, uint32_t first_frame,

StackFrameSP selected_frame_sp =
m_thread.GetSelectedFrame(DoNoSelectMostRelevantFrame);
const char *unselected_marker = nullptr;
std::string buffer;
if (selected_frame_marker) {
size_t len = strlen(selected_frame_marker);
buffer.insert(buffer.begin(), len, ' ');
unselected_marker = buffer.c_str();
}
const char *marker = nullptr;
std::wstring marker;
for (frame_idx = first_frame; frame_idx < last_frame; ++frame_idx) {
frame_sp = GetFrameAtIndex(frame_idx);
if (!frame_sp)
break;

if (selected_frame_marker != nullptr) {
if (frame_sp == selected_frame_sp)
marker = selected_frame_marker;
else
marker = unselected_marker;
}
if (show_selected_frame)
marker = FrameMarker(frame_sp, selected_frame_sp);
else
marker = FrameMarker(frame_sp, nullptr);

// Hide uninteresting frames unless it's the selected frame.
if (!show_hidden && frame_sp != selected_frame_sp && frame_sp->IsHidden())
Expand All @@ -933,10 +957,11 @@ size_t StackFrameList::GetStatus(Stream &strm, uint32_t first_frame,
m_thread.GetID(), num_frames_displayed))
break;


std::string marker_utf8;
llvm::convertWideToUTF8(marker, marker_utf8);
if (!frame_sp->GetStatus(strm, show_frame_info,
num_frames_with_source > (first_frame - frame_idx),
show_unique, marker))
show_unique, marker_utf8))
break;
++num_frames_displayed;
}
Expand Down
6 changes: 3 additions & 3 deletions lldb/source/Target/Thread.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1817,16 +1817,16 @@ size_t Thread::GetStatus(Stream &strm, uint32_t start_frame,

const bool show_frame_info = true;
const bool show_frame_unique = only_stacks;
const char *selected_frame_marker = nullptr;
bool show_selected_frame = false;
if (num_frames == 1 || only_stacks ||
(GetID() != GetProcess()->GetThreadList().GetSelectedThread()->GetID()))
strm.IndentMore();
else
selected_frame_marker = "* ";
show_selected_frame = true;

num_frames_shown = GetStackFrameList()->GetStatus(
strm, start_frame, num_frames, show_frame_info, num_frames_with_source,
show_frame_unique, show_hidden, selected_frame_marker);
show_frame_unique, show_hidden, show_selected_frame);
if (num_frames == 1)
strm.IndentLess();
strm.IndentLess();
Expand Down
Loading