diff --git a/lldb/include/lldb/Core/DebuggerEvents.h b/lldb/include/lldb/Core/DebuggerEvents.h --- a/lldb/include/lldb/Core/DebuggerEvents.h +++ b/lldb/include/lldb/Core/DebuggerEvents.h @@ -32,6 +32,7 @@ static const ProgressEventData *GetEventDataFromEvent(const Event *event_ptr); uint64_t GetID() const { return m_id; } + bool IsFinite() const { return m_total != UINT64_MAX; } uint64_t GetCompleted() const { return m_completed; } uint64_t GetTotal() const { return m_total; } const std::string &GetMessage() const { return m_message; } 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 @@ -1852,20 +1852,26 @@ return; } + // Trim the progress message if it exceeds the window's width and print it. + std::string message = data->GetMessage(); + if (data->IsFinite()) + message = llvm::formatv("[{0}/{1}] {2}", data->GetCompleted(), + data->GetTotal(), message) + .str(); + + // Trim the progress message if it exceeds the window's width and print it. + const uint32_t term_width = GetTerminalWidth(); + const uint32_t ellipsis = 3; + if (message.size() + ellipsis >= term_width) + message = message.substr(0, term_width - ellipsis); + const bool use_color = GetUseColor(); llvm::StringRef ansi_prefix = GetShowProgressAnsiPrefix(); if (!ansi_prefix.empty()) output->Printf( "%s", ansi::FormatAnsiTerminalCodes(ansi_prefix, use_color).c_str()); - // Print the progress message. - std::string message = data->GetMessage(); - if (data->GetTotal() != UINT64_MAX) { - output->Printf("[%" PRIu64 "/%" PRIu64 "] %s...", data->GetCompleted(), - data->GetTotal(), message.c_str()); - } else { - output->Printf("%s...", message.c_str()); - } + output->Printf("%s...", message.c_str()); llvm::StringRef ansi_suffix = GetShowProgressAnsiSuffix(); if (!ansi_suffix.empty()) diff --git a/lldb/test/API/functionalities/progress_reporting/TestTrimmedProgressReporting.py b/lldb/test/API/functionalities/progress_reporting/TestTrimmedProgressReporting.py new file mode 100644 --- /dev/null +++ b/lldb/test/API/functionalities/progress_reporting/TestTrimmedProgressReporting.py @@ -0,0 +1,50 @@ +""" +Test trimming long progress report in tiny terminal windows +""" + +import os +import pexpect +import tempfile +import re + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test.lldbpexpect import PExpectTest + +class TestTrimmedProgressReporting(PExpectTest): + + mydir = TestBase.compute_mydir(__file__) + + def do_test(self, term_width, pattern_list): + self.build() + # Start with a small window + self.launch(use_colors=True) + self.expect("set set show-progress true") + self.expect("set show show-progress", substrs=["show-progress (boolean) = true"]) + self.expect("set set term-width " + str(term_width)) + self.expect("set show term-width", substrs=["term-width (int) = " + str(term_width)]) + + self.child.send("file " + self.getBuildArtifact("a.out") + "\n") + self.child.expect(pattern_list) + + + # PExpect uses many timeouts internally and doesn't play well + # under ASAN on a loaded machine.. + @skipIfAsan + @skipUnlessDarwin + @skipIfEditlineSupportMissing + def test_trimmed_progress_message(self): + self.do_test(19, ['Locating externa...', + 'Loading Apple DW...', + 'Parsing symbol t...']) + + # PExpect uses many timeouts internally and doesn't play well + # under ASAN on a loaded machine.. + @skipIfAsan + @skipUnlessDarwin + @skipIfEditlineSupportMissing + def test_long_progress_message(self): + self.do_test(80, ['Locating external symbol file for a.out...', + 'Loading Apple DWARF index for a.out...', + 'Parsing symbol table for dyld...'])