[lldb] refactor highlighting function for image lookup command (#76112)
Follow-up to #69422. This PR puts all the highlighting settings into a single struct for easier handling Co-authored-by: Talha Tahir <talha.tahir@10xengineers.ai>
This commit is contained in:
@@ -9,6 +9,7 @@
|
||||
#ifndef LLDB_CORE_ADDRESS_H
|
||||
#define LLDB_CORE_ADDRESS_H
|
||||
|
||||
#include "lldb/Utility/Stream.h"
|
||||
#include "lldb/lldb-defines.h"
|
||||
#include "lldb/lldb-forward.h"
|
||||
#include "lldb/lldb-private-enumerations.h"
|
||||
@@ -252,10 +253,11 @@ public:
|
||||
/// in such cases.
|
||||
///
|
||||
/// \see Address::DumpStyle
|
||||
bool Dump(Stream *s, ExecutionContextScope *exe_scope, DumpStyle style,
|
||||
DumpStyle fallback_style = DumpStyleInvalid,
|
||||
uint32_t addr_byte_size = UINT32_MAX, bool all_ranges = false,
|
||||
llvm::StringRef pattern = "") const;
|
||||
bool
|
||||
Dump(Stream *s, ExecutionContextScope *exe_scope, DumpStyle style,
|
||||
DumpStyle fallback_style = DumpStyleInvalid,
|
||||
uint32_t addr_byte_size = UINT32_MAX, bool all_ranges = false,
|
||||
std::optional<Stream::HighlightSettings> settings = std::nullopt) const;
|
||||
|
||||
AddressClass GetAddressClass() const;
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include "lldb/Core/Mangled.h"
|
||||
#include "lldb/Core/Section.h"
|
||||
#include "lldb/Symbol/SymbolContextScope.h"
|
||||
#include "lldb/Utility/Stream.h"
|
||||
#include "lldb/Utility/UserID.h"
|
||||
#include "lldb/lldb-private.h"
|
||||
#include "llvm/Support/JSON.h"
|
||||
@@ -174,8 +175,9 @@ public:
|
||||
|
||||
void SetFlags(uint32_t flags) { m_flags = flags; }
|
||||
|
||||
void GetDescription(Stream *s, lldb::DescriptionLevel level, Target *target,
|
||||
llvm::StringRef pattern = "") const;
|
||||
void GetDescription(
|
||||
Stream *s, lldb::DescriptionLevel level, Target *target,
|
||||
std::optional<Stream::HighlightSettings> settings = std::nullopt) const;
|
||||
|
||||
bool IsSynthetic() const { return m_is_synthetic; }
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#include "lldb/Core/Mangled.h"
|
||||
#include "lldb/Symbol/LineEntry.h"
|
||||
#include "lldb/Utility/Iterable.h"
|
||||
#include "lldb/Utility/Stream.h"
|
||||
#include "lldb/lldb-private.h"
|
||||
|
||||
namespace lldb_private {
|
||||
@@ -153,11 +154,11 @@ public:
|
||||
///
|
||||
/// \return
|
||||
/// \b true if some text was dumped, \b false otherwise.
|
||||
bool DumpStopContext(Stream *s, ExecutionContextScope *exe_scope,
|
||||
const Address &so_addr, bool show_fullpaths,
|
||||
bool show_module, bool show_inlined_frames,
|
||||
bool show_function_arguments, bool show_function_name,
|
||||
llvm::StringRef pattern = "") const;
|
||||
bool DumpStopContext(
|
||||
Stream *s, ExecutionContextScope *exe_scope, const Address &so_addr,
|
||||
bool show_fullpaths, bool show_module, bool show_inlined_frames,
|
||||
bool show_function_arguments, bool show_function_name,
|
||||
std::optional<Stream::HighlightSettings> settings = std::nullopt) const;
|
||||
|
||||
/// Get the address range contained within a symbol context.
|
||||
///
|
||||
@@ -223,8 +224,9 @@ public:
|
||||
/// The symbol that was found, or \b nullptr if none was found.
|
||||
const Symbol *FindBestGlobalDataSymbol(ConstString name, Status &error);
|
||||
|
||||
void GetDescription(Stream *s, lldb::DescriptionLevel level, Target *target,
|
||||
llvm::StringRef pattern = "") const;
|
||||
void GetDescription(
|
||||
Stream *s, lldb::DescriptionLevel level, Target *target,
|
||||
std::optional<Stream::HighlightSettings> settings = std::nullopt) const;
|
||||
|
||||
uint32_t GetResolvedMask() const;
|
||||
|
||||
|
||||
@@ -33,6 +33,17 @@ public:
|
||||
/// string mode.
|
||||
};
|
||||
|
||||
/// Struct to store information for color highlighting in the stream.
|
||||
struct HighlightSettings {
|
||||
llvm::StringRef pattern; ///< Regex pattern for highlighting.
|
||||
llvm::StringRef prefix; ///< ANSI color code to start colorization.
|
||||
llvm::StringRef suffix; ///< ANSI color code to end colorization.
|
||||
|
||||
HighlightSettings(llvm::StringRef p, llvm::StringRef pre,
|
||||
llvm::StringRef suf)
|
||||
: pattern(p), prefix(pre), suffix(suf) {}
|
||||
};
|
||||
|
||||
/// Utility class for counting the bytes that were written to a stream in a
|
||||
/// certain time span.
|
||||
///
|
||||
@@ -260,10 +271,9 @@ public:
|
||||
/// The ANSI color code to end colorization. This is
|
||||
/// environment-dependent.
|
||||
|
||||
void PutCStringColorHighlighted(llvm::StringRef text,
|
||||
llvm::StringRef pattern = "",
|
||||
llvm::StringRef prefix = "",
|
||||
llvm::StringRef suffix = "");
|
||||
void PutCStringColorHighlighted(
|
||||
llvm::StringRef text,
|
||||
std::optional<HighlightSettings> settings = std::nullopt);
|
||||
|
||||
/// Output and End of Line character to the stream.
|
||||
size_t EOL();
|
||||
|
||||
@@ -53,6 +53,7 @@
|
||||
#include "lldb/Utility/FileSpec.h"
|
||||
#include "lldb/Utility/LLDBLog.h"
|
||||
#include "lldb/Utility/State.h"
|
||||
#include "lldb/Utility/Stream.h"
|
||||
#include "lldb/Utility/StructuredData.h"
|
||||
#include "lldb/Utility/Timer.h"
|
||||
#include "lldb/lldb-enumerations.h"
|
||||
@@ -1531,9 +1532,10 @@ static void DumpOsoFilesTable(Stream &strm,
|
||||
});
|
||||
}
|
||||
|
||||
static void DumpAddress(ExecutionContextScope *exe_scope,
|
||||
const Address &so_addr, bool verbose, bool all_ranges,
|
||||
Stream &strm, llvm::StringRef pattern = "") {
|
||||
static void
|
||||
DumpAddress(ExecutionContextScope *exe_scope, const Address &so_addr,
|
||||
bool verbose, bool all_ranges, Stream &strm,
|
||||
std::optional<Stream::HighlightSettings> settings = std::nullopt) {
|
||||
strm.IndentMore();
|
||||
strm.Indent(" Address: ");
|
||||
so_addr.Dump(&strm, exe_scope, Address::DumpStyleModuleWithFileAddress);
|
||||
@@ -1544,13 +1546,13 @@ static void DumpAddress(ExecutionContextScope *exe_scope,
|
||||
const uint32_t save_indent = strm.GetIndentLevel();
|
||||
strm.SetIndentLevel(save_indent + 13);
|
||||
so_addr.Dump(&strm, exe_scope, Address::DumpStyleResolvedDescription,
|
||||
Address::DumpStyleInvalid, UINT32_MAX, false, pattern);
|
||||
Address::DumpStyleInvalid, UINT32_MAX, false, settings);
|
||||
strm.SetIndentLevel(save_indent);
|
||||
// Print out detailed address information when verbose is enabled
|
||||
if (verbose) {
|
||||
strm.EOL();
|
||||
so_addr.Dump(&strm, exe_scope, Address::DumpStyleDetailedSymbolContext,
|
||||
Address::DumpStyleInvalid, UINT32_MAX, all_ranges, pattern);
|
||||
Address::DumpStyleInvalid, UINT32_MAX, all_ranges, settings);
|
||||
}
|
||||
strm.IndentLess();
|
||||
}
|
||||
@@ -1615,6 +1617,9 @@ static uint32_t LookupSymbolInModule(CommandInterpreter &interpreter,
|
||||
DumpFullpath(strm, &module->GetFileSpec(), 0);
|
||||
strm.PutCString(":\n");
|
||||
strm.IndentMore();
|
||||
Stream::HighlightSettings settings(
|
||||
name, interpreter.GetDebugger().GetRegexMatchAnsiPrefix(),
|
||||
interpreter.GetDebugger().GetRegexMatchAnsiSuffix());
|
||||
for (uint32_t i = 0; i < num_matches; ++i) {
|
||||
Symbol *symbol = symtab->SymbolAtIndex(match_indexes[i]);
|
||||
if (symbol) {
|
||||
@@ -1622,18 +1627,18 @@ static uint32_t LookupSymbolInModule(CommandInterpreter &interpreter,
|
||||
DumpAddress(
|
||||
interpreter.GetExecutionContext().GetBestExecutionContextScope(),
|
||||
symbol->GetAddressRef(), verbose, all_ranges, strm,
|
||||
use_color && name_is_regex ? name : nullptr);
|
||||
use_color && name_is_regex
|
||||
? std::optional<Stream::HighlightSettings>{settings}
|
||||
: std::nullopt);
|
||||
strm.EOL();
|
||||
} else {
|
||||
strm.IndentMore();
|
||||
strm.Indent(" Name: ");
|
||||
llvm::StringRef ansi_prefix =
|
||||
interpreter.GetDebugger().GetRegexMatchAnsiPrefix();
|
||||
llvm::StringRef ansi_suffix =
|
||||
interpreter.GetDebugger().GetRegexMatchAnsiSuffix();
|
||||
strm.PutCStringColorHighlighted(
|
||||
symbol->GetDisplayName().GetStringRef(),
|
||||
use_color ? name : nullptr, ansi_prefix, ansi_suffix);
|
||||
use_color && name_is_regex
|
||||
? std::optional<Stream::HighlightSettings>{settings}
|
||||
: std::nullopt);
|
||||
strm.EOL();
|
||||
strm.Indent(" Value: ");
|
||||
strm.Printf("0x%16.16" PRIx64 "\n", symbol->GetRawValue());
|
||||
@@ -1650,10 +1655,10 @@ static uint32_t LookupSymbolInModule(CommandInterpreter &interpreter,
|
||||
return num_matches;
|
||||
}
|
||||
|
||||
static void DumpSymbolContextList(ExecutionContextScope *exe_scope,
|
||||
Stream &strm,
|
||||
const SymbolContextList &sc_list,
|
||||
bool verbose, bool all_ranges) {
|
||||
static void DumpSymbolContextList(
|
||||
ExecutionContextScope *exe_scope, Stream &strm,
|
||||
const SymbolContextList &sc_list, bool verbose, bool all_ranges,
|
||||
std::optional<Stream::HighlightSettings> settings = std::nullopt) {
|
||||
strm.IndentMore();
|
||||
bool first_module = true;
|
||||
for (const SymbolContext &sc : sc_list) {
|
||||
@@ -1664,7 +1669,8 @@ static void DumpSymbolContextList(ExecutionContextScope *exe_scope,
|
||||
|
||||
sc.GetAddressRange(eSymbolContextEverything, 0, true, range);
|
||||
|
||||
DumpAddress(exe_scope, range.GetBaseAddress(), verbose, all_ranges, strm);
|
||||
DumpAddress(exe_scope, range.GetBaseAddress(), verbose, all_ranges, strm,
|
||||
settings);
|
||||
first_module = false;
|
||||
}
|
||||
strm.IndentLess();
|
||||
|
||||
@@ -407,7 +407,8 @@ bool Address::GetDescription(Stream &s, Target &target,
|
||||
|
||||
bool Address::Dump(Stream *s, ExecutionContextScope *exe_scope, DumpStyle style,
|
||||
DumpStyle fallback_style, uint32_t addr_size,
|
||||
bool all_ranges, llvm::StringRef pattern) const {
|
||||
bool all_ranges,
|
||||
std::optional<Stream::HighlightSettings> settings) const {
|
||||
// If the section was nullptr, only load address is going to work unless we
|
||||
// are trying to deref a pointer
|
||||
SectionSP section_sp(GetSection());
|
||||
@@ -516,16 +517,7 @@ bool Address::Dump(Stream *s, ExecutionContextScope *exe_scope, DumpStyle style,
|
||||
if (symbol) {
|
||||
const char *symbol_name = symbol->GetName().AsCString();
|
||||
if (symbol_name) {
|
||||
llvm::StringRef ansi_prefix;
|
||||
llvm::StringRef ansi_suffix;
|
||||
if (target) {
|
||||
ansi_prefix =
|
||||
target->GetDebugger().GetRegexMatchAnsiPrefix();
|
||||
ansi_suffix =
|
||||
target->GetDebugger().GetRegexMatchAnsiSuffix();
|
||||
}
|
||||
s->PutCStringColorHighlighted(symbol_name, pattern,
|
||||
ansi_prefix, ansi_suffix);
|
||||
s->PutCStringColorHighlighted(symbol_name, settings);
|
||||
addr_t delta =
|
||||
file_Addr - symbol->GetAddressRef().GetFileAddress();
|
||||
if (delta)
|
||||
@@ -653,7 +645,7 @@ bool Address::Dump(Stream *s, ExecutionContextScope *exe_scope, DumpStyle style,
|
||||
pointer_sc.symbol != nullptr) {
|
||||
s->PutCString(": ");
|
||||
pointer_sc.DumpStopContext(s, exe_scope, so_addr, true, false,
|
||||
false, true, true, pattern);
|
||||
false, true, true, settings);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -693,13 +685,13 @@ bool Address::Dump(Stream *s, ExecutionContextScope *exe_scope, DumpStyle style,
|
||||
sc.DumpStopContext(s, exe_scope, *this, show_fullpaths,
|
||||
show_module, show_inlined_frames,
|
||||
show_function_arguments, show_function_name,
|
||||
pattern);
|
||||
settings);
|
||||
} else {
|
||||
// We found a symbol but it was in a different section so it
|
||||
// isn't the symbol we should be showing, just show the section
|
||||
// name + offset
|
||||
Dump(s, exe_scope, DumpStyleSectionNameOffset, DumpStyleInvalid,
|
||||
UINT32_MAX, false, pattern);
|
||||
UINT32_MAX, false, settings);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -707,7 +699,7 @@ bool Address::Dump(Stream *s, ExecutionContextScope *exe_scope, DumpStyle style,
|
||||
} else {
|
||||
if (fallback_style != DumpStyleInvalid)
|
||||
return Dump(s, exe_scope, fallback_style, DumpStyleInvalid, addr_size,
|
||||
false, pattern);
|
||||
false, settings);
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
@@ -728,7 +720,7 @@ bool Address::Dump(Stream *s, ExecutionContextScope *exe_scope, DumpStyle style,
|
||||
sc.symbol->GetAddressRef().GetSection() != GetSection())
|
||||
sc.symbol = nullptr;
|
||||
}
|
||||
sc.GetDescription(s, eDescriptionLevelBrief, target, pattern);
|
||||
sc.GetDescription(s, eDescriptionLevelBrief, target, settings);
|
||||
|
||||
if (sc.block) {
|
||||
bool can_create = true;
|
||||
@@ -777,7 +769,7 @@ bool Address::Dump(Stream *s, ExecutionContextScope *exe_scope, DumpStyle style,
|
||||
} else {
|
||||
if (fallback_style != DumpStyleInvalid)
|
||||
return Dump(s, exe_scope, fallback_style, DumpStyleInvalid, addr_size,
|
||||
false, pattern);
|
||||
false, settings);
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -226,8 +226,9 @@ bool Symbol::IsTrampoline() const { return m_type == eSymbolTypeTrampoline; }
|
||||
|
||||
bool Symbol::IsIndirect() const { return m_type == eSymbolTypeResolver; }
|
||||
|
||||
void Symbol::GetDescription(Stream *s, lldb::DescriptionLevel level,
|
||||
Target *target, llvm::StringRef pattern) const {
|
||||
void Symbol::GetDescription(
|
||||
Stream *s, lldb::DescriptionLevel level, Target *target,
|
||||
std::optional<Stream::HighlightSettings> settings) const {
|
||||
s->Printf("id = {0x%8.8x}", m_uid);
|
||||
|
||||
if (m_addr_range.GetBaseAddress().GetSection()) {
|
||||
@@ -254,22 +255,14 @@ void Symbol::GetDescription(Stream *s, lldb::DescriptionLevel level,
|
||||
s->Printf(", value = 0x%16.16" PRIx64,
|
||||
m_addr_range.GetBaseAddress().GetOffset());
|
||||
}
|
||||
llvm::StringRef ansi_prefix;
|
||||
llvm::StringRef ansi_suffix;
|
||||
if (target) {
|
||||
ansi_prefix = target->GetDebugger().GetRegexMatchAnsiPrefix();
|
||||
ansi_suffix = target->GetDebugger().GetRegexMatchAnsiSuffix();
|
||||
}
|
||||
if (ConstString demangled = m_mangled.GetDemangledName()) {
|
||||
s->PutCString(", name=\"");
|
||||
s->PutCStringColorHighlighted(demangled.GetStringRef(), pattern,
|
||||
ansi_prefix, ansi_suffix);
|
||||
s->PutCStringColorHighlighted(demangled.GetStringRef(), settings);
|
||||
s->PutCString("\"");
|
||||
}
|
||||
if (ConstString mangled_name = m_mangled.GetMangledName()) {
|
||||
s->PutCString(", mangled=\"");
|
||||
s->PutCStringColorHighlighted(mangled_name.GetStringRef(), pattern,
|
||||
ansi_prefix, ansi_suffix);
|
||||
s->PutCStringColorHighlighted(mangled_name.GetStringRef(), settings);
|
||||
s->PutCString("\"");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#include "lldb/Target/Target.h"
|
||||
#include "lldb/Utility/LLDBLog.h"
|
||||
#include "lldb/Utility/Log.h"
|
||||
#include "lldb/Utility/Stream.h"
|
||||
#include "lldb/Utility/StreamString.h"
|
||||
#include "lldb/lldb-enumerations.h"
|
||||
|
||||
@@ -68,12 +69,11 @@ void SymbolContext::Clear(bool clear_target) {
|
||||
variable = nullptr;
|
||||
}
|
||||
|
||||
bool SymbolContext::DumpStopContext(Stream *s, ExecutionContextScope *exe_scope,
|
||||
const Address &addr, bool show_fullpaths,
|
||||
bool show_module, bool show_inlined_frames,
|
||||
bool show_function_arguments,
|
||||
bool show_function_name,
|
||||
llvm::StringRef pattern) const {
|
||||
bool SymbolContext::DumpStopContext(
|
||||
Stream *s, ExecutionContextScope *exe_scope, const Address &addr,
|
||||
bool show_fullpaths, bool show_module, bool show_inlined_frames,
|
||||
bool show_function_arguments, bool show_function_name,
|
||||
std::optional<Stream::HighlightSettings> settings) const {
|
||||
bool dumped_something = false;
|
||||
if (show_module && module_sp) {
|
||||
if (show_fullpaths)
|
||||
@@ -95,16 +95,8 @@ bool SymbolContext::DumpStopContext(Stream *s, ExecutionContextScope *exe_scope,
|
||||
name = function->GetNameNoArguments();
|
||||
if (!name)
|
||||
name = function->GetName();
|
||||
if (name) {
|
||||
llvm::StringRef ansi_prefix;
|
||||
llvm::StringRef ansi_suffix;
|
||||
if (target_sp) {
|
||||
ansi_prefix = target_sp->GetDebugger().GetRegexMatchAnsiPrefix();
|
||||
ansi_suffix = target_sp->GetDebugger().GetRegexMatchAnsiSuffix();
|
||||
}
|
||||
s->PutCStringColorHighlighted(name.GetStringRef(), pattern, ansi_prefix,
|
||||
ansi_suffix);
|
||||
}
|
||||
if (name)
|
||||
s->PutCStringColorHighlighted(name.GetStringRef(), settings);
|
||||
}
|
||||
|
||||
if (addr.IsValid()) {
|
||||
@@ -172,14 +164,7 @@ bool SymbolContext::DumpStopContext(Stream *s, ExecutionContextScope *exe_scope,
|
||||
dumped_something = true;
|
||||
if (symbol->GetType() == eSymbolTypeTrampoline)
|
||||
s->PutCString("symbol stub for: ");
|
||||
llvm::StringRef ansi_prefix;
|
||||
llvm::StringRef ansi_suffix;
|
||||
if (target_sp) {
|
||||
ansi_prefix = target_sp->GetDebugger().GetRegexMatchAnsiPrefix();
|
||||
ansi_suffix = target_sp->GetDebugger().GetRegexMatchAnsiSuffix();
|
||||
}
|
||||
s->PutCStringColorHighlighted(symbol->GetName().GetStringRef(), pattern,
|
||||
ansi_prefix, ansi_suffix);
|
||||
s->PutCStringColorHighlighted(symbol->GetName().GetStringRef(), settings);
|
||||
}
|
||||
|
||||
if (addr.IsValid() && symbol->ValueIsAddress()) {
|
||||
@@ -201,9 +186,9 @@ bool SymbolContext::DumpStopContext(Stream *s, ExecutionContextScope *exe_scope,
|
||||
return dumped_something;
|
||||
}
|
||||
|
||||
void SymbolContext::GetDescription(Stream *s, lldb::DescriptionLevel level,
|
||||
Target *target,
|
||||
llvm::StringRef pattern) const {
|
||||
void SymbolContext::GetDescription(
|
||||
Stream *s, lldb::DescriptionLevel level, Target *target,
|
||||
std::optional<Stream::HighlightSettings> settings) const {
|
||||
if (module_sp) {
|
||||
s->Indent(" Module: file = \"");
|
||||
module_sp->GetFileSpec().Dump(s->AsRawOstream());
|
||||
@@ -263,7 +248,7 @@ void SymbolContext::GetDescription(Stream *s, lldb::DescriptionLevel level,
|
||||
|
||||
if (symbol != nullptr) {
|
||||
s->Indent(" Symbol: ");
|
||||
symbol->GetDescription(s, level, target, pattern);
|
||||
symbol->GetDescription(s, level, target, settings);
|
||||
s->EOL();
|
||||
}
|
||||
|
||||
|
||||
@@ -72,23 +72,20 @@ size_t Stream::PutCString(llvm::StringRef str) {
|
||||
return bytes_written;
|
||||
}
|
||||
|
||||
void Stream::PutCStringColorHighlighted(llvm::StringRef text,
|
||||
llvm::StringRef pattern,
|
||||
llvm::StringRef prefix,
|
||||
llvm::StringRef suffix) {
|
||||
// Only apply color formatting when a pattern is present and both prefix and
|
||||
// suffix are specified. In the absence of these conditions, output the text
|
||||
// without color formatting.
|
||||
if (pattern.empty() || (prefix.empty() && suffix.empty())) {
|
||||
void Stream::PutCStringColorHighlighted(
|
||||
llvm::StringRef text, std::optional<HighlightSettings> pattern_info) {
|
||||
// Only apply color formatting when a pattern information is specified.
|
||||
// Otherwise, output the text without color formatting.
|
||||
if (!pattern_info.has_value()) {
|
||||
PutCString(text);
|
||||
return;
|
||||
}
|
||||
|
||||
llvm::Regex reg_pattern(pattern);
|
||||
llvm::Regex reg_pattern(pattern_info->pattern);
|
||||
llvm::SmallVector<llvm::StringRef, 1> matches;
|
||||
llvm::StringRef remaining = text;
|
||||
std::string format_str = lldb_private::ansi::FormatAnsiTerminalCodes(
|
||||
prefix.str() + "%.*s" + suffix.str());
|
||||
pattern_info->prefix.str() + "%.*s" + pattern_info->suffix.str());
|
||||
while (reg_pattern.match(remaining, &matches)) {
|
||||
llvm::StringRef match = matches[0];
|
||||
size_t match_start_pos = match.data() - remaining.data();
|
||||
|
||||
Reference in New Issue
Block a user