public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
From: Aaron Merey <amerey@redhat.com>
To: gdb-patches@sourceware.org
Cc: Aaron Merey <amerey@redhat.com>
Subject: [PATCH 4/7] gdb/ui-file: Add newline tracking
Date: Mon, 27 Feb 2023 14:42:09 -0500	[thread overview]
Message-ID: <20230227194212.348003-4-amerey@redhat.com> (raw)
In-Reply-To: <20230227194212.348003-1-amerey@redhat.com>

Add a new field line_state to ui_file's that indicates whether
the character most recently written to the ui_file's stream is
a newline.

The purpose of this is to help debuginfod progress messages
always print on their own line.  Until now they have always
done so without any special intervention.  But with the addition
of deferred debuginfo downloading it is possible for progress
messages to occur during the printing of frame information.

Without any newline tracking in this case, we can end up with
poorly formatted output:

    (gdb) backtrace
    [...]
    #8  0x00007fbe8af7d7cf in pygi_invoke_c_callable (Downloading separate debug info for /lib64/libpython3.11.so.1.0
    function_cache=0x561221b224d0, state=<optimized out>...

With newline tracking, the progress message writer can detect
whether the message should start with a newline.  This ensures
that all progress messages print on their own line:

    (gdb) backtrace
    [...]
    #8  0x00007fbe8af7d7cf in pygi_invoke_c_callable (
    Downloading separate debug info for /lib64/libpython3.11.so.1.0
    function_cache=0x561221b224d0, state=<optimized out>...
---
 gdb/cli-out.c       | 18 +++++++++++++++---
 gdb/mi/mi-console.c |  4 ++++
 gdb/tui/tui-file.c  |  4 ++++
 gdb/ui-file.c       | 31 +++++++++++++++++++++++++++++++
 gdb/ui-file.h       | 44 ++++++++++++++++++++++++++++++++++++++++++++
 5 files changed, 98 insertions(+), 3 deletions(-)

diff --git a/gdb/cli-out.c b/gdb/cli-out.c
index fdfd0f7f0cf..1639f885cb9 100644
--- a/gdb/cli-out.c
+++ b/gdb/cli-out.c
@@ -307,6 +307,10 @@ cli_ui_out::do_progress_notify (const std::string &msg,
 
   if (info.state == progress_update::START)
     {
+      /* MSG should print on its own line.  */
+      if (stream->get_line_state () == ui_file::LINE_NOT_AT_START)
+	gdb_printf (stream, "\n");
+
       if (stream->isatty ()
 	  && current_ui->input_interactive_p ()
 	  && chars_per_line >= MIN_CHARS_PER_LINE)
@@ -410,10 +414,18 @@ void
 cli_ui_out::do_progress_end ()
 {
   struct ui_file *stream = m_streams.back ();
-  m_progress_info.pop_back ();
 
-  if (stream->isatty ())
-    clear_current_line ();
+  cli_progress_info &info (m_progress_info.back ());
+
+  if (info.state != progress_update::START && stream->isatty ())
+    {
+      clear_current_line ();
+
+      if (stream->get_line_state () != ui_file::LINE_UNDEFINED)
+	stream->set_line_state (ui_file::LINE_AT_START);
+    }
+
+  m_progress_info.pop_back ();
 }
 
 /* local functions */
diff --git a/gdb/mi/mi-console.c b/gdb/mi/mi-console.c
index e0b5648c2df..60f2a823b47 100644
--- a/gdb/mi/mi-console.c
+++ b/gdb/mi/mi-console.c
@@ -46,6 +46,8 @@ mi_console_file::write (const char *buf, long length_buf)
      buffer.  */
   if (strchr (m_buffer.c_str () + prev_size, '\n') != NULL)
     this->flush ();
+
+  set_line_state_from_buf (m_buffer.c_str () + prev_size, length_buf);
 }
 
 void
@@ -63,6 +65,8 @@ mi_console_file::write_async_safe (const char *buf, long length_buf)
 
   char nl = '\n';
   m_raw->write_async_safe (&nl, 1);
+
+  set_line_state (LINE_AT_START);
 }
 
 void
diff --git a/gdb/tui/tui-file.c b/gdb/tui/tui-file.c
index c1619d5ace6..c36ce739497 100644
--- a/gdb/tui/tui-file.c
+++ b/gdb/tui/tui-file.c
@@ -28,6 +28,8 @@ tui_file::puts (const char *linebuffer)
   tui_puts (linebuffer);
   if (!m_buffered)
     tui_refresh_cmd_win ();
+
+  set_line_state_from_buf (linebuffer);
 }
 
 void
@@ -36,6 +38,8 @@ tui_file::write (const char *buf, long length_buf)
   tui_write (buf, length_buf);
   if (!m_buffered)
     tui_refresh_cmd_win ();
+
+  set_line_state_from_buf (buf, length_buf);
 }
 
 void
diff --git a/gdb/ui-file.c b/gdb/ui-file.c
index e0814fe2b2d..3f7a55ed252 100644
--- a/gdb/ui-file.c
+++ b/gdb/ui-file.c
@@ -31,6 +31,7 @@
 null_file null_stream;
 
 ui_file::ui_file ()
+  : m_line_state (LINE_UNDEFINED)
 {}
 
 ui_file::~ui_file ()
@@ -159,6 +160,30 @@ ui_file::printchar (int c, int quoter, bool async_safe)
     this->write (buf, out);
 }
 
+/* See ui-file.h.  */
+
+void
+ui_file::set_line_state_from_buf (const char *buf)
+{
+  const char *last_nl = strrchr (buf, '\n');
+
+  if (last_nl != nullptr && *++last_nl == '\0')
+    m_line_state = LINE_AT_START;
+  else
+    m_line_state = LINE_NOT_AT_START;
+}
+
+/* See ui-file.h.  */
+
+void
+ui_file::set_line_state_from_buf (const char *buf, long length_buf)
+{
+  if (buf[length_buf - 1] == '\n')
+    m_line_state = LINE_AT_START;
+  else
+    m_line_state = LINE_NOT_AT_START;
+}
+
 \f
 
 void
@@ -311,6 +336,8 @@ stdio_file::write (const char *buf, long length_buf)
     {
       /* Nothing.  */
     }
+
+  set_line_state_from_buf (buf, length_buf);
 }
 
 void
@@ -323,6 +350,8 @@ stdio_file::write_async_safe (const char *buf, long length_buf)
     {
       /* Nothing.  */
     }
+
+  set_line_state_from_buf (buf, length_buf);
 }
 
 void
@@ -339,6 +368,8 @@ stdio_file::puts (const char *linebuffer)
     {
       /* Nothing.  */
     }
+
+  set_line_state_from_buf (linebuffer);
 }
 
 bool
diff --git a/gdb/ui-file.h b/gdb/ui-file.h
index de24620e247..b85c37d81c7 100644
--- a/gdb/ui-file.h
+++ b/gdb/ui-file.h
@@ -132,11 +132,40 @@ class ui_file
     this->puts (str);
   }
 
+  enum line_state
+  {
+    /* Line state is not being tracked.  */
+    LINE_UNDEFINED,
+
+    /* The last character written to this ui_file is not a newline.  */
+    LINE_NOT_AT_START,
+
+    /* The last character written to this ui_file is a newline.  */
+    LINE_AT_START
+  };
+
+  /* Set this ui_file's line_state to STATE.  */
+  virtual void set_line_state (line_state state)
+  { m_line_state = state; }
+
+  /* Return this ui_file's line_state.  */
+  virtual line_state get_line_state ()
+  { return m_line_state; }
+
 protected:
 
   /* The currently applied style.  */
   ui_file_style m_applied_style;
 
+  /* The current line_state.  */
+  line_state m_line_state;
+
+  /* Set line_state based on whether BUF ends in a newline.  */
+  void set_line_state_from_buf (const char *buf);
+
+  /* Set line_state based on whether BUF ends in a newline.  */
+  void set_line_state_from_buf (const char *buf, long length_buf);
+
 private:
 
   /* Helper function for putstr and putstrn.  Print the character C on
@@ -428,6 +457,21 @@ class wrapped_file : public ui_file
   void write_async_safe (const char *buf, long length_buf) override
   { return m_stream->write_async_safe (buf, length_buf); }
 
+  /* Return the line_state of the underlying stream.  */
+  line_state get_line_state () override
+  {
+    if (m_stream == nullptr)
+      return ui_file::LINE_UNDEFINED;
+    return m_stream->get_line_state ();
+  }
+
+  /* Set the line_state of the underlying stream.  */
+  void set_line_state (line_state state) override
+  {
+    if (m_stream != nullptr)
+      m_stream->set_line_state (state);
+  }
+
 protected:
 
   /* Note that this class does not assume ownership of the stream.
-- 
2.39.2


  parent reply	other threads:[~2023-02-27 19:42 UTC|newest]

Thread overview: 25+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-02-27 19:42 [PATCH 1/7] gdb/debuginfod: Add debuginfod_section_query Aaron Merey
2023-02-27 19:42 ` [PATCH 2/7] gdb: add 'lazy' setting for command 'set debuginfod enabled' Aaron Merey
2023-02-27 19:54   ` Eli Zaretskii
2023-05-24  9:31   ` Andrew Burgess
2023-02-27 19:42 ` [PATCH 3/7] gdb/debuginfod: disable pagination during downloads Aaron Merey
2023-03-03 21:33   ` Tom Tromey
2023-03-06 23:07     ` Aaron Merey
2023-05-24  9:38   ` Andrew Burgess
2023-05-24 18:57     ` Aaron Merey
2023-02-27 19:42 ` Aaron Merey [this message]
2023-03-07 19:33   ` [PATCH 4/7] gdb/ui-file: Add newline tracking Tom Tromey
2023-03-07 20:30     ` Aaron Merey
2023-03-07 20:47       ` Tom Tromey
2023-02-27 19:42 ` [PATCH 5/7] gdb/debuginfod: Support on-demand debuginfo downloading Aaron Merey
2023-03-07 20:20   ` Tom Tromey
2023-03-09  0:22     ` Aaron Merey
2023-02-27 19:42 ` [PATCH 6/7] gdb/testsuite/gdb.debuginfod: Add lazy downloading tests Aaron Merey
2023-05-02 15:48   ` Andrew Burgess
2023-05-02 16:24     ` Aaron Merey
2023-05-24 10:12   ` Andrew Burgess
2023-02-27 19:42 ` [PATCH 7/7] gdb/debuginfod: Add .debug_line downloading Aaron Merey
2023-03-07 20:36   ` Tom Tromey
2023-03-09  0:26     ` Aaron Merey
2023-02-28 11:11 ` [PATCH 1/7] gdb/debuginfod: Add debuginfod_section_query Alexandra Petlanova Hajkova
2023-05-24  9:01 ` Andrew Burgess

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20230227194212.348003-4-amerey@redhat.com \
    --to=amerey@redhat.com \
    --cc=gdb-patches@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).