Skip to content
Merged
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
19 changes: 18 additions & 1 deletion lldb/include/lldb/Host/common/DiagnosticsRendering.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,10 +59,27 @@ struct DiagnosticDetail {

StructuredData::ObjectSP Serialize(llvm::ArrayRef<DiagnosticDetail> details);

/// Renders an array of DiagnosticDetail instances.
///
/// \param[in] stream
/// The stream to render the diagnostics to.
/// \param offset_in_command
/// An optional offset to the column position of the diagnostic in the
/// source.
/// \param show_inline
/// Whether to show the diagnostics inline.
/// \param details
/// The array of DiagnosticsDetail to render.
/// \param force_ascii
/// Whether to force ascii rendering. If false, Unicode characters will be
/// used if the output file supports them.
///
/// \see lldb_private::Terminal::SupportsUnicode
void RenderDiagnosticDetails(Stream &stream,
std::optional<uint16_t> offset_in_command,
bool show_inline,
llvm::ArrayRef<DiagnosticDetail> details);
llvm::ArrayRef<DiagnosticDetail> details,
bool force_ascii = false);

class DiagnosticError
: public llvm::ErrorInfo<DiagnosticError, CloneableECError> {
Expand Down
11 changes: 5 additions & 6 deletions lldb/source/Host/common/DiagnosticsRendering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
//===----------------------------------------------------------------------===//

#include "lldb/Host/common/DiagnosticsRendering.h"
#include "lldb/Host/Terminal.h"

#include <cstdint>

using namespace lldb_private;
Expand Down Expand Up @@ -85,7 +87,8 @@ static llvm::raw_ostream &PrintSeverity(Stream &stream,
void RenderDiagnosticDetails(Stream &stream,
std::optional<uint16_t> offset_in_command,
bool show_inline,
llvm::ArrayRef<DiagnosticDetail> details) {
llvm::ArrayRef<DiagnosticDetail> details,
bool force_ascii) {
if (details.empty())
return;

Expand All @@ -97,12 +100,8 @@ void RenderDiagnosticDetails(Stream &stream,
return;
}

// Since there is no other way to find this out, use the color
// attribute as a proxy for whether the terminal supports Unicode
// 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() && !force_ascii) {
cursor = "˄";
underline = "˜";
vbar = "│";
Expand Down
16 changes: 16 additions & 0 deletions lldb/source/Host/common/Terminal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -400,6 +400,22 @@ llvm::Error Terminal::SetHardwareFlowControl(bool enabled) {
#endif // LLDB_ENABLE_TERMIOS
}

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

TerminalState::TerminalState(Terminal term, bool save_process_group)
: m_tty(term) {
Save(term, save_process_group);
Expand Down
2 changes: 1 addition & 1 deletion lldb/unittests/Host/common/DiagnosticsRenderingTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ class ErrorDisplayTest : public ::testing::Test {};

std::string Render(std::vector<DiagnosticDetail> details) {
StreamString stream;
RenderDiagnosticDetails(stream, 0, true, details);
RenderDiagnosticDetails(stream, 0, true, details, /*force_ascii=*/true);
return stream.GetData();
}
} // namespace
Expand Down
Loading