diff --git a/lldb/include/lldb/Core/Debugger.h b/lldb/include/lldb/Core/Debugger.h --- a/lldb/include/lldb/Core/Debugger.h +++ b/lldb/include/lldb/Core/Debugger.h @@ -287,6 +287,10 @@ uint32_t GetDisassemblyLineCount() const; + llvm::StringRef GetStopShowLineMarkerAnsiPrefix() const; + + llvm::StringRef GetStopShowLineMarkerAnsiSuffix() const; + bool GetAutoOneLineSummaries() const; bool GetAutoIndent() const; diff --git a/lldb/source/Core/CoreProperties.td b/lldb/source/Core/CoreProperties.td --- a/lldb/source/Core/CoreProperties.td +++ b/lldb/source/Core/CoreProperties.td @@ -75,6 +75,14 @@ Global, DefaultStringValue<"${ansi.normal}">, Desc<"When displaying the column marker in a color-enabled (i.e. ANSI) terminal, use the ANSI terminal code specified in this format immediately after the column to be marked.">; + def StopShowLineMarkerAnsiPrefix: Property<"stop-show-line-ansi-prefix", "String">, + Global, + DefaultStringValue<"${ansi.fg.yellow}">, + Desc<"When displaying the line marker in a color-enabled (i.e. ANSI) terminal, use the ANSI terminal code specified in this format at the immediately before the line to be marked.">; + def StopShowLineMarkerAnsiSuffix: Property<"stop-show-line-ansi-suffix", "String">, + Global, + DefaultStringValue<"${ansi.normal}">, + Desc<"When displaying the line marker in a color-enabled (i.e. ANSI) terminal, use the ANSI terminal code specified in this format immediately after the line to be marked.">; def TerminalWidth: Property<"term-width", "SInt64">, Global, DefaultUnsignedValue<80>, diff --git a/lldb/source/Core/Debugger.cpp b/lldb/source/Core/Debugger.cpp --- a/lldb/source/Core/Debugger.cpp +++ b/lldb/source/Core/Debugger.cpp @@ -360,6 +360,16 @@ return m_collection_sp->GetPropertyAtIndexAsString(nullptr, idx, ""); } +llvm::StringRef Debugger::GetStopShowLineMarkerAnsiPrefix() const { + const uint32_t idx = ePropertyStopShowLineMarkerAnsiPrefix; + return m_collection_sp->GetPropertyAtIndexAsString(nullptr, idx, ""); +} + +llvm::StringRef Debugger::GetStopShowLineMarkerAnsiSuffix() const { + const uint32_t idx = ePropertyStopShowLineMarkerAnsiSuffix; + return m_collection_sp->GetPropertyAtIndexAsString(nullptr, idx, ""); +} + uint32_t Debugger::GetStopSourceLineCount(bool before) const { const uint32_t idx = before ? ePropertyStopLineCountBefore : ePropertyStopLineCountAfter; diff --git a/lldb/source/Core/SourceManager.cpp b/lldb/source/Core/SourceManager.cpp --- a/lldb/source/Core/SourceManager.cpp +++ b/lldb/source/Core/SourceManager.cpp @@ -22,6 +22,7 @@ #include "lldb/Symbol/SymbolContext.h" #include "lldb/Target/PathMappingList.h" #include "lldb/Target/Target.h" +#include "lldb/Utility/AnsiTerminal.h" #include "lldb/Utility/ConstString.h" #include "lldb/Utility/DataBuffer.h" #include "lldb/Utility/DataBufferLLVM.h" @@ -148,6 +149,10 @@ return value == eStopShowColumnCaret; } +static bool should_show_stop_line_with_ansi(DebuggerSP debugger_sp) { + return debugger_sp && debugger_sp->GetUseColor(); +} + size_t SourceManager::DisplaySourceLinesWithLineNumbersUsingLastFile( uint32_t start_line, uint32_t count, uint32_t curr_line, uint32_t column, const char *current_line_cstr, Stream *s, @@ -191,8 +196,20 @@ ::snprintf(prefix, sizeof(prefix), " "); } - s->Printf("%s%2.2s %-4u\t", prefix, - line == curr_line ? current_line_cstr : "", line); + char buffer[3]; + sprintf(buffer, "%2.2s", (line == curr_line) ? current_line_cstr : ""); + std::string current_line_highlight(buffer); + + auto debugger_sp = m_debugger_wp.lock(); + if (should_show_stop_line_with_ansi(debugger_sp)) { + current_line_highlight = ansi::FormatAnsiTerminalCodes( + (debugger_sp->GetStopShowLineMarkerAnsiPrefix() + + current_line_highlight + + debugger_sp->GetStopShowLineMarkerAnsiSuffix()) + .str()); + } + + s->Printf("%s%s %-4u\t", prefix, current_line_highlight.c_str(), line); // So far we treated column 0 as a special 'no column value', but // DisplaySourceLines starts counting columns from 0 (and no column is @@ -204,7 +221,7 @@ size_t this_line_size = m_last_file_sp->DisplaySourceLines(line, columnToHighlight, 0, 0, s); if (column != 0 && line == curr_line && - should_show_stop_column_with_caret(m_debugger_wp.lock())) { + should_show_stop_column_with_caret(debugger_sp)) { // Display caret cursor. std::string src_line; m_last_file_sp->GetLine(line, src_line); diff --git a/lldb/test/API/source-manager/TestSourceManager.py b/lldb/test/API/source-manager/TestSourceManager.py --- a/lldb/test/API/source-manager/TestSourceManager.py +++ b/lldb/test/API/source-manager/TestSourceManager.py @@ -93,7 +93,7 @@ # 6 } self.expect(stream.GetData(), "Source code displayed correctly:\n" + stream.GetData(), exe=False, - patterns=['=> %d.*Hello world' % self.line, + patterns=['=>', '%d.*Hello world' % self.line, needle_regex]) # Boundary condition testings for SBStream(). LLDB should not crash! diff --git a/lldb/test/Shell/Settings/TestLineMarkerColor.test b/lldb/test/Shell/Settings/TestLineMarkerColor.test new file mode 100644 --- /dev/null +++ b/lldb/test/Shell/Settings/TestLineMarkerColor.test @@ -0,0 +1,17 @@ +# RUN: %clang_host -g -O0 %S/Inputs/main.c -o %t.out +# RUN: %lldb -x -b -s %s %t.out | FileCheck %s +settings set use-color true +settings set stop-show-line-ansi-prefix "prefix" +settings set stop-show-line-ansi-suffix "suffix" +b foo +run +c +settings set stop-show-line-ansi-prefix ${ansi.fg.green} +settings set stop-show-line-ansi-suffix ${ansi.normal} +run +q + +# Check the ASCII escape code +# CHECK-NOT: prefix->suffix +# CHECK: -> +# CHECK: {{.*}}->{{.*}}