public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
From: Tom Tromey <tom@tromey.com>
To: gdb-patches@sourceware.org
Cc: Tom Tromey <tom@tromey.com>
Subject: [PATCH 07/19] Change the pager to a ui_file
Date: Fri, 21 Jan 2022 18:37:49 -0700	[thread overview]
Message-ID: <20220122013801.666659-8-tom@tromey.com> (raw)
In-Reply-To: <20220122013801.666659-1-tom@tromey.com>

This rewrites the output pager as a ui_file implementation.

A new header is introduced to declare the pager class.  The
implementation remains in utils.c for the time being, because there
are some static globals there that must be used by this code.  (This
could be cleaned up at some future date.)

I went through all the text output in gdb to ensure that this change
should be ok.  There are a few cases:

* Any existing call to printf_unfiltered is required to be avoid the
  pager.  This is ensured directly in the implementation.

* All remaining calls to the f*_unfiltered functions -- the ones that
  take an explicit ui_file -- either send to an unfiltered stream
  (e.g., gdb_stderr), which is obviously ok; or conditionally send to
  gdb_stdout

  I investigated all such calls by searching for:

    grep -e '\bf[a-z0-9_]*_unfiltered' *.[chyl] */*.[ch] | grep -v gdb_stdlog | grep -v gdb_stderr

  This yields a number of candidates to check.

  * The breakpoint _print_recreate family, and
    save_trace_state_variables.  These are used for "save" commands
    and so are fine.

  * Things printing to a temporary stream.  Obviously ok.

  * Disassembly selftests.

  * print_gdb_help - this is non-obvious, but ok because paging isn't
    yet enabled at this point during startup.

  * serial.c - doens't use gdb_stdout

  * The code in compile/.  This is all printing to a file.

  * DWARF DIE dumping - doesn't reference gdb_stdout.

* Calls to the _filtered form -- these are all clearly ok, because if
  they are using gdb_stdout, then filtering will still apply; and if
  not, then filtering never applied and still will not.

Therefore, at this point, there is no longer any distinction between
all the other _filtered and _unfiltered calls, and they can be
unified.

In this patch, take special note of the vfprintf_maybe_filtered and
ui_file::vprintf change.  This is one instance of the above idea,
erasing the distinction between filtered and unfiltered -- in this
part of the change, the "unfiltered_output" flag is never passe to
cli_ui_out.  Subsequent patches will go much further in this
direction.

Also note the can_emit_style_escape changes in ui-file.c.  Checking
against gdb_stdout or gdb_stderr was always a bit of a hack; and now
it is no longer needed, because this is decision can be more fully
delegated to the particular ui_file implementation.

ui_file::can_page is removed, because this patch removed the only call
to it.

I think this is the main part of fixing PR cli/7234.

Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=7234
---
 gdb/cli/cli-cmds.c |   2 +-
 gdb/event-top.c    |   3 +-
 gdb/pager.h        | 109 +++++++++++++++++++++
 gdb/printcmd.c     |   2 +-
 gdb/top.c          |   3 +-
 gdb/tui/tui-io.c   |   3 +-
 gdb/ui-file.c      |  10 +-
 gdb/ui-file.h      |  26 ++---
 gdb/utils.c        | 239 ++++++++++++++++++---------------------------
 gdb/utils.h        |   4 -
 10 files changed, 227 insertions(+), 174 deletions(-)
 create mode 100644 gdb/pager.h

diff --git a/gdb/cli/cli-cmds.c b/gdb/cli/cli-cmds.c
index 2f5ce3e5fff..3cdc7cde9a5 100644
--- a/gdb/cli/cli-cmds.c
+++ b/gdb/cli/cli-cmds.c
@@ -838,7 +838,7 @@ echo_command (const char *text, int from_tty)
 	  printf_filtered ("%c", c);
       }
 
-  reset_terminal_style (gdb_stdout);
+  gdb_stdout->reset_style ();
 
   /* Force this output to appear now.  */
   gdb_stdout->wrap_here (0);
diff --git a/gdb/event-top.c b/gdb/event-top.c
index 039066a9d03..5db2a2acdd2 100644
--- a/gdb/event-top.c
+++ b/gdb/event-top.c
@@ -42,6 +42,7 @@
 #include "gdbsupport/gdb-sigmask.h"
 #include "async-event.h"
 #include "bt-utils.h"
+#include "pager.h"
 
 /* readline include files.  */
 #include "readline/readline.h"
@@ -1279,7 +1280,7 @@ gdb_setup_readline (int editing)
      mess it up here.  The sync stuff should really go away over
      time.  */
   if (!batch_silent)
-    gdb_stdout = new stdio_file (ui->outstream);
+    gdb_stdout = new pager_file (new stdio_file (ui->outstream));
   gdb_stderr = new stderr_file (ui->errstream);
   gdb_stdlog = new timestamped_file (gdb_stderr);
   gdb_stdtarg = gdb_stderr; /* for moment */
diff --git a/gdb/pager.h b/gdb/pager.h
new file mode 100644
index 00000000000..0151a283629
--- /dev/null
+++ b/gdb/pager.h
@@ -0,0 +1,109 @@
+/* Output pager for gdb
+   Copyright (C) 2021, 2022 Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#ifndef GDB_PAGER_H
+#define GDB_PAGER_H
+
+#include "ui-file.h"
+
+/* A ui_file that implements output paging and unfiltered output.  */
+
+class pager_file : public ui_file
+{
+public:
+  /* Create a new pager_file.  The new object takes ownership of
+     STREAM.  */
+  explicit pager_file (ui_file *stream)
+    : m_stream (stream)
+  {
+  }
+
+  DISABLE_COPY_AND_ASSIGN (pager_file);
+
+  void write (const char *buf, long length_buf) override;
+
+  void puts (const char *str) override;
+
+  void write_async_safe (const char *buf, long length_buf) override
+  {
+    m_stream->write_async_safe (buf, length_buf);
+  }
+
+  bool term_out () override
+  {
+    return m_stream->term_out ();
+  }
+
+  bool isatty () override
+  {
+    return m_stream->isatty ();
+  }
+
+  bool can_emit_style_escape () override
+  {
+    return m_stream->can_emit_style_escape ();
+  }
+
+  void emit_style_escape (const ui_file_style &style) override;
+  void reset_style () override;
+
+  void flush () override;
+
+  int fd () const override
+  {
+    return m_stream->fd ();
+  }
+
+  void wrap_here (int indent) override;
+
+  void puts_unfiltered (const char *str) override
+  {
+    flush_wrap_buffer ();
+    m_stream->puts_unfiltered (str);
+  }
+
+private:
+
+  void prompt_for_continue ();
+
+  /* Flush the wrap buffer to STREAM, if necessary.  */
+  void flush_wrap_buffer ();
+
+  /* Contains characters which are waiting to be output (they have
+     already been counted in chars_printed).  */
+  std::string m_wrap_buffer;
+
+  /* Amount to indent by if the wrap occurs.  */
+  int m_wrap_indent = 0;
+
+  /* Column number on the screen where wrap_buffer begins, or 0 if
+     wrapping is not in effect.  */
+  int m_wrap_column = 0;
+
+  /* The style applied at the time that wrap_here was called.  */
+  ui_file_style m_wrap_style;
+
+  /* The unfiltered output stream.  */
+  ui_file_up m_stream;
+
+  /* This is temporarily set when paging.  This will cause some
+     methods to change their behavior to ignore the wrap buffer.  */
+  bool m_paging = false;
+};
+
+#endif /* GDB_PAGER_H */
diff --git a/gdb/printcmd.c b/gdb/printcmd.c
index ab87310965d..f5ce0404d48 100644
--- a/gdb/printcmd.c
+++ b/gdb/printcmd.c
@@ -2894,7 +2894,7 @@ static void
 printf_command (const char *arg, int from_tty)
 {
   ui_printf (arg, gdb_stdout);
-  reset_terminal_style (gdb_stdout);
+  gdb_stdout->reset_style ();
   gdb_stdout->wrap_here (0);
   gdb_stdout->flush ();
 }
diff --git a/gdb/top.c b/gdb/top.c
index 5d90ebbdf19..f0ee9920847 100644
--- a/gdb/top.c
+++ b/gdb/top.c
@@ -56,6 +56,7 @@
 #include "gdbarch.h"
 #include "gdbsupport/pathstuff.h"
 #include "cli/cli-style.h"
+#include "pager.h"
 
 /* readline include files.  */
 #include "readline/readline.h"
@@ -285,7 +286,7 @@ ui::ui (FILE *instream_, FILE *outstream_, FILE *errstream_)
     input_fd (fileno (instream)),
     input_interactive_p (ISATTY (instream)),
     prompt_state (PROMPT_NEEDED),
-    m_gdb_stdout (new stdio_file (outstream)),
+    m_gdb_stdout (new pager_file (new stdio_file (outstream))),
     m_gdb_stdin (new stdio_file (instream)),
     m_gdb_stderr (new stderr_file (errstream)),
     m_gdb_stdlog (m_gdb_stderr),
diff --git a/gdb/tui/tui-io.c b/gdb/tui/tui-io.c
index 718375f9cd4..7aed0248ee7 100644
--- a/gdb/tui/tui-io.c
+++ b/gdb/tui/tui-io.c
@@ -44,6 +44,7 @@
 #include "completer.h"
 #include "gdb_curses.h"
 #include <map>
+#include "pager.h"
 
 /* This redefines CTRL if it is not already defined, so it must come
    after terminal state releated include files like <term.h> and
@@ -903,7 +904,7 @@ tui_initialize_io (void)
 #endif
 
   /* Create tui output streams.  */
-  tui_stdout = new tui_file (stdout);
+  tui_stdout = new pager_file (new tui_file (stdout));
   tui_stderr = new tui_file (stderr);
   tui_stdlog = new timestamped_file (tui_stderr);
   tui_out = tui_out_new (tui_stdout);
diff --git a/gdb/ui-file.c b/gdb/ui-file.c
index 2072fd81954..f6878f76cf1 100644
--- a/gdb/ui-file.c
+++ b/gdb/ui-file.c
@@ -24,6 +24,7 @@
 #include "gdbsupport/gdb_obstack.h"
 #include "gdbsupport/gdb_select.h"
 #include "gdbsupport/filestuff.h"
+#include "cli-out.h"
 #include "cli/cli-style.h"
 #include <chrono>
 
@@ -68,7 +69,8 @@ ui_file::putc (int c)
 void
 ui_file::vprintf (const char *format, va_list args)
 {
-  vfprintf_unfiltered (this, format, args);
+  ui_out_flags flags = disallow_ui_out_field;
+  cli_ui_out (this, flags).vmessage (m_applied_style, format, args);
 }
 
 /* See ui-file.h.  */
@@ -349,8 +351,7 @@ stdio_file::isatty ()
 bool
 stdio_file::can_emit_style_escape ()
 {
-  return ((this == gdb_stdout || this == gdb_stderr)
-	  && this->isatty ()
+  return (this->isatty ()
 	  && term_cli_styling ());
 }
 
@@ -438,8 +439,7 @@ tee_file::term_out ()
 bool
 tee_file::can_emit_style_escape ()
 {
-  return ((this == gdb_stdout || this == gdb_stderr)
-	  && m_one->term_out ()
+  return (m_one->term_out ()
 	  && term_cli_styling ());
 }
 
diff --git a/gdb/ui-file.h b/gdb/ui-file.h
index 1ea2f60591c..7de30ed5584 100644
--- a/gdb/ui-file.h
+++ b/gdb/ui-file.h
@@ -99,16 +99,10 @@ class ui_file
   virtual int fd () const
   { return -1; }
 
-  /* Return true if this object supports paging, false otherwise.  */
-  virtual bool can_page () const
+  virtual void wrap_here (int indent)
   {
-    /* Almost no file supports paging, which is why this is the
-       default.  */
-    return false;
   }
 
-  void wrap_here (int indent);
-
   /* Emit an ANSI style escape for STYLE.  */
   virtual void emit_style_escape (const ui_file_style &style);
 
@@ -250,11 +244,6 @@ class stdio_file : public ui_file
   int fd () const override
   { return m_fd; }
 
-  virtual bool can_page () const override
-  {
-    return m_file == stdout;
-  }
-
 private:
   /* Sets the internal stream to FILE, and saves the FILE's file
      descriptor in M_FD.  */
@@ -329,11 +318,16 @@ class tee_file : public ui_file
   bool can_emit_style_escape () override;
   void flush () override;
 
-  virtual bool can_page () const override
+  void emit_style_escape (const ui_file_style &style) override
+  {
+    m_one->emit_style_escape (style);
+    m_two->emit_style_escape (style);
+  }
+
+  void reset_style () override
   {
-    /* If one of the underlying files can page, then we allow it
-       here.  */
-    return m_one->can_page () || m_two->can_page ();
+    m_one->reset_style ();
+    m_two->reset_style ();
   }
 
   void puts_unfiltered (const char *str) override
diff --git a/gdb/utils.c b/gdb/utils.c
index 6dbb46f9719..fff914e92b0 100644
--- a/gdb/utils.c
+++ b/gdb/utils.c
@@ -77,6 +77,7 @@
 #include "gdbsupport/gdb-safe-ctype.h"
 #include "bt-utils.h"
 #include "gdbsupport/buildargv.h"
+#include "pager.h"
 
 void (*deprecated_error_begin_hook) (void);
 
@@ -86,10 +87,6 @@ static void vfprintf_maybe_filtered (struct ui_file *, const char *,
 				     va_list, bool)
   ATTRIBUTE_PRINTF (2, 0);
 
-static void fputs_maybe_filtered (const char *, struct ui_file *, int);
-
-static void prompt_for_continue (void);
-
 static void set_screen_size (void);
 static void set_width (void);
 
@@ -1171,19 +1168,6 @@ static bool pagination_disabled_for_command;
 
 static bool filter_initialized = false;
 
-/* Contains characters which are waiting to be output (they have
-   already been counted in chars_printed).  */
-static std::string wrap_buffer;
-
-/* String to indent by if the wrap occurs.  */
-static int wrap_indent;
-
-/* Column number on the screen where wrap_buffer begins, or 0 if wrapping
-   is not in effect.  */
-static int wrap_column;
-
-/* The style applied at the time that wrap_here was called.  */
-static ui_file_style wrap_style;
 \f
 
 /* Initialize the number of lines per page and chars per line.  */
@@ -1315,7 +1299,6 @@ set_width (void)
   if (chars_per_line == 0)
     init_page_info ();
 
-  wrap_buffer.clear ();
   filter_initialized = true;
 }
 
@@ -1344,55 +1327,28 @@ set_screen_width_and_height (int width, int height)
   set_width ();
 }
 
-/* The currently applied style.  */
-
-static ui_file_style applied_style;
-
-/* Emit an ANSI style escape for STYLE.  If STREAM is nullptr, emit to
-   the wrap buffer; otherwise emit to STREAM.  */
-
-static void
-emit_style_escape (const ui_file_style &style,
-		   struct ui_file *stream = nullptr)
+void
+pager_file::emit_style_escape (const ui_file_style &style)
 {
-  if (applied_style != style)
+  if (can_emit_style_escape () && style != m_applied_style)
     {
-      applied_style = style;
-
-      if (stream == nullptr)
-	wrap_buffer.append (style.to_ansi ());
+      m_applied_style = style;
+      if (m_paging)
+	m_stream->emit_style_escape (style);
       else
-	stream->puts (style.to_ansi ().c_str ());
+	m_wrap_buffer.append (style.to_ansi ());
     }
 }
 
-/* Set the current output style.  This will affect future uses of the
-   _filtered output functions.  */
-
-static void
-set_output_style (struct ui_file *stream, const ui_file_style &style)
-{
-  if (!stream->can_emit_style_escape ())
-    return;
-
-  /* Note that we may not pass STREAM here, when we want to emit to
-     the wrap buffer, not directly to STREAM.  */
-  if (stream == gdb_stdout)
-    stream = nullptr;
-  emit_style_escape (style, stream);
-}
-
-/* See utils.h.  */
+/* See pager.h.  */
 
 void
-reset_terminal_style (struct ui_file *stream)
+pager_file::reset_style ()
 {
-  if (stream->can_emit_style_escape ())
+  if (can_emit_style_escape ())
     {
-      /* Force the setting, regardless of what we think the setting
-	 might already be.  */
-      applied_style = ui_file_style ();
-      wrap_buffer.append (applied_style.to_ansi ());
+      m_applied_style = ui_file_style ();
+      m_wrap_buffer.append (m_applied_style.to_ansi ());
     }
 }
 
@@ -1401,8 +1357,8 @@ reset_terminal_style (struct ui_file *stream)
    telling users what to do in the prompt is more user-friendly than
    expecting them to think of Ctrl-C/SIGINT.  */
 
-static void
-prompt_for_continue (void)
+void
+pager_file::prompt_for_continue ()
 {
   char cont_prompt[120];
   /* Used to add duration we waited for user to respond to
@@ -1411,12 +1367,13 @@ prompt_for_continue (void)
   steady_clock::time_point prompt_started = steady_clock::now ();
   bool disable_pagination = pagination_disabled_for_command;
 
+  scoped_restore save_paging = make_scoped_restore (&m_paging, true);
+
   /* Clear the current styling.  */
-  if (gdb_stdout->can_emit_style_escape ())
-    emit_style_escape (ui_file_style (), gdb_stdout);
+  m_stream->emit_style_escape (ui_file_style ());
 
   if (annotation_level > 1)
-    printf_unfiltered (("\n\032\032pre-prompt-for-continue\n"));
+    m_stream->puts (("\n\032\032pre-prompt-for-continue\n"));
 
   strcpy (cont_prompt,
 	  "--Type <RET> for more, q to quit, "
@@ -1439,7 +1396,7 @@ prompt_for_continue (void)
   prompt_for_continue_wait_time += steady_clock::now () - prompt_started;
 
   if (annotation_level > 1)
-    printf_unfiltered (("\n\032\032post-prompt-for-continue\n"));
+    m_stream->puts (("\n\032\032post-prompt-for-continue\n"));
 
   if (ignore != NULL)
     {
@@ -1490,24 +1447,28 @@ reinitialize_more_filter (void)
   pagination_disabled_for_command = false;
 }
 
-/* Flush the wrap buffer to STREAM, if necessary.  */
-
-static void
-flush_wrap_buffer (struct ui_file *stream)
+void
+pager_file::flush_wrap_buffer ()
 {
-  if (stream == gdb_stdout && !wrap_buffer.empty ())
+  if (!m_paging && !m_wrap_buffer.empty ())
     {
-      stream->puts (wrap_buffer.c_str ());
-      wrap_buffer.clear ();
+      m_stream->puts (m_wrap_buffer.c_str ());
+      m_wrap_buffer.clear ();
     }
 }
 
+void
+pager_file::flush ()
+{
+  flush_wrap_buffer ();
+  m_stream->flush ();
+}
+
 /* See utils.h.  */
 
 void
 gdb_flush (struct ui_file *stream)
 {
-  flush_wrap_buffer (stream);
   stream->flush ();
 }
 
@@ -1522,28 +1483,28 @@ get_chars_per_line ()
 /* See ui-file.h.  */
 
 void
-ui_file::wrap_here (int indent)
+pager_file::wrap_here (int indent)
 {
   /* This should have been allocated, but be paranoid anyway.  */
   gdb_assert (filter_initialized);
 
-  flush_wrap_buffer (this);
+  flush_wrap_buffer ();
   if (chars_per_line == UINT_MAX)	/* No line overflow checking.  */
     {
-      wrap_column = 0;
+      m_wrap_column = 0;
     }
   else if (chars_printed >= chars_per_line)
     {
-      puts_filtered ("\n");
+      this->puts ("\n");
       if (indent != 0)
-	puts_filtered (n_spaces (indent));
-      wrap_column = 0;
+	this->puts (n_spaces (indent));
+      m_wrap_column = 0;
     }
   else
     {
-      wrap_column = chars_printed;
-      wrap_indent = indent;
-      wrap_style = applied_style;
+      m_wrap_column = chars_printed;
+      m_wrap_indent = indent;
+      m_wrap_style = m_applied_style;
     }
 }
 
@@ -1620,9 +1581,8 @@ begin_line (void)
    FILTER is true) (since prompt_for_continue may do so) so this
    routine should not be called when cleanups are not in place.  */
 
-static void
-fputs_maybe_filtered (const char *linebuffer, struct ui_file *stream,
-		      int filter)
+void
+pager_file::puts (const char *linebuffer)
 {
   const char *lineptr;
 
@@ -1630,26 +1590,24 @@ fputs_maybe_filtered (const char *linebuffer, struct ui_file *stream,
     return;
 
   /* Don't do any filtering if it is disabled.  */
-  if (!stream->can_page ()
-      || stream != gdb_stdout
-      || !pagination_enabled
+  if (!pagination_enabled
       || pagination_disabled_for_command
       || batch_flag
       || (lines_per_page == UINT_MAX && chars_per_line == UINT_MAX)
       || top_level_interpreter () == NULL
       || top_level_interpreter ()->interp_ui_out ()->is_mi_like_p ())
     {
-      flush_wrap_buffer (stream);
-      stream->puts (linebuffer);
+      flush_wrap_buffer ();
+      m_stream->puts (linebuffer);
       return;
     }
 
   auto buffer_clearer
     = make_scope_exit ([&] ()
 		       {
-			 wrap_buffer.clear ();
-			 wrap_column = 0;
-			 wrap_indent = 0;
+			 m_wrap_buffer.clear ();
+			 m_wrap_column = 0;
+			 m_wrap_indent = 0;
 		       });
 
   /* Go through and output each character.  Show line extension
@@ -1662,7 +1620,7 @@ fputs_maybe_filtered (const char *linebuffer, struct ui_file *stream,
       /* Possible new page.  Note that PAGINATION_DISABLED_FOR_COMMAND
 	 might be set during this loop, so we must continue to check
 	 it here.  */
-      if (filter && (lines_printed >= lines_per_page - 1)
+      if ((lines_printed >= lines_per_page - 1)
 	  && !pagination_disabled_for_command)
 	prompt_for_continue ();
 
@@ -1673,7 +1631,7 @@ fputs_maybe_filtered (const char *linebuffer, struct ui_file *stream,
 	  /* Print a single line.  */
 	  if (*lineptr == '\t')
 	    {
-	      wrap_buffer.push_back ('\t');
+	      m_wrap_buffer.push_back ('\t');
 	      /* Shifting right by 3 produces the number of tab stops
 		 we have already passed, and then adding one and
 		 shifting left 3 advances to the next tab stop.  */
@@ -1683,20 +1641,20 @@ fputs_maybe_filtered (const char *linebuffer, struct ui_file *stream,
 	  else if (*lineptr == '\033'
 		   && skip_ansi_escape (lineptr, &skip_bytes))
 	    {
-	      wrap_buffer.append (lineptr, skip_bytes);
+	      m_wrap_buffer.append (lineptr, skip_bytes);
 	      /* Note that we don't consider this a character, so we
 		 don't increment chars_printed here.  */
 	      lineptr += skip_bytes;
 	    }
 	  else if (*lineptr == '\r')
 	    {
-	      wrap_buffer.push_back (*lineptr);
+	      m_wrap_buffer.push_back (*lineptr);
 	      chars_printed = 0;
 	      lineptr++;
 	    }
 	  else
 	    {
-	      wrap_buffer.push_back (*lineptr);
+	      m_wrap_buffer.push_back (*lineptr);
 	      chars_printed++;
 	      lineptr++;
 	    }
@@ -1711,12 +1669,12 @@ fputs_maybe_filtered (const char *linebuffer, struct ui_file *stream,
 		 prompt is given; and to avoid emitting style
 		 sequences in the middle of a run of text, we track
 		 this as well.  */
-	      ui_file_style save_style = applied_style;
+	      ui_file_style save_style = m_applied_style;
 	      bool did_paginate = false;
 
 	      chars_printed = 0;
 	      lines_printed++;
-	      if (wrap_column)
+	      if (m_wrap_column)
 		{
 		  /* We are about to insert a newline at an historic
 		     location in the WRAP_BUFFER.  Before we do we want to
@@ -1724,22 +1682,16 @@ fputs_maybe_filtered (const char *linebuffer, struct ui_file *stream,
 		     need to insert an escape sequence we must restore the
 		     current applied style to how it was at the WRAP_COLUMN
 		     location.  */
-		  applied_style = wrap_style;
-		  if (stream->can_emit_style_escape ())
-		    emit_style_escape (ui_file_style (), stream);
+		  m_applied_style = m_wrap_style;
+		  m_stream->emit_style_escape (ui_file_style ());
 		  /* If we aren't actually wrapping, don't output
 		     newline -- if chars_per_line is right, we
 		     probably just overflowed anyway; if it's wrong,
 		     let us keep going.  */
-		  /* XXX: The ideal thing would be to call
-		     'stream->putc' here, but we can't because it
-		     currently calls 'fputc_unfiltered', which ends up
-		     calling us, which generates an infinite
-		     recursion.  */
-		  stream->puts ("\n");
+		  m_stream->puts ("\n");
 		}
 	      else
-		flush_wrap_buffer (stream);
+		this->flush_wrap_buffer ();
 
 	      /* Possible new page.  Note that
 		 PAGINATION_DISABLED_FOR_COMMAND might be set during
@@ -1752,44 +1704,37 @@ fputs_maybe_filtered (const char *linebuffer, struct ui_file *stream,
 		}
 
 	      /* Now output indentation and wrapped string.  */
-	      if (wrap_column)
+	      if (m_wrap_column)
 		{
-		  stream->puts (n_spaces (wrap_indent));
+		  m_stream->puts (n_spaces (m_wrap_indent));
 
 		  /* Having finished inserting the wrapping we should
 		     restore the style as it was at the WRAP_COLUMN.  */
-		  if (stream->can_emit_style_escape ())
-		    emit_style_escape (wrap_style, stream);
+		  m_stream->emit_style_escape (m_wrap_style);
 
 		  /* The WRAP_BUFFER will still contain content, and that
 		     content might set some alternative style.  Restore
 		     APPLIED_STYLE as it was before we started wrapping,
 		     this reflects the current style for the last character
 		     in WRAP_BUFFER.  */
-		  applied_style = save_style;
+		  m_applied_style = save_style;
 
 		  /* Note that this can set chars_printed > chars_per_line
 		     if we are printing a long string.  */
-		  chars_printed = wrap_indent + (save_chars - wrap_column);
-		  wrap_column = 0;	/* And disable fancy wrap */
+		  chars_printed = m_wrap_indent + (save_chars - m_wrap_column);
+		  m_wrap_column = 0;	/* And disable fancy wrap */
 		}
-	      else if (did_paginate && stream->can_emit_style_escape ())
-		emit_style_escape (save_style, stream);
+	      else if (did_paginate)
+		m_stream->emit_style_escape (save_style);
 	    }
 	}
 
       if (*lineptr == '\n')
 	{
 	  chars_printed = 0;
-	  stream->wrap_here (0); /* Spit out chars, cancel
-				    further wraps.  */
+	  wrap_here (0); /* Spit out chars, cancel further wraps.  */
 	  lines_printed++;
-	  /* XXX: The ideal thing would be to call
-	     'stream->putc' here, but we can't because it
-	     currently calls 'fputc_unfiltered', which ends up
-	     calling us, which generates an infinite
-	     recursion.  */
-	  stream->puts ("\n");
+	  m_stream->puts ("\n");
 	  lineptr++;
 	}
     }
@@ -1798,15 +1743,24 @@ fputs_maybe_filtered (const char *linebuffer, struct ui_file *stream,
 }
 
 void
-fputs_filtered (const char *linebuffer, struct ui_file *stream)
+pager_file::write (const char *buf, long length_buf)
 {
-  fputs_maybe_filtered (linebuffer, stream, 1);
+  /* We have to make a string here because the pager uses
+     skip_ansi_escape, which requires NUL-termination.  */
+  std::string str (buf, length_buf);
+  this->puts (str.c_str ());
 }
 
 void
 fputs_unfiltered (const char *linebuffer, struct ui_file *stream)
 {
-  fputs_maybe_filtered (linebuffer, stream, 0);
+  stream->puts_unfiltered (linebuffer);
+}
+
+void
+fputs_filtered (const char *linebuffer, struct ui_file *stream)
+{
+  stream->puts (linebuffer);
 }
 
 /* See utils.h.  */
@@ -1815,9 +1769,9 @@ void
 fputs_styled (const char *linebuffer, const ui_file_style &style,
 	      struct ui_file *stream)
 {
-  set_output_style (stream, style);
-  fputs_maybe_filtered (linebuffer, stream, 1);
-  set_output_style (stream, ui_file_style ());
+  stream->emit_style_escape (style);
+  fputs_filtered (linebuffer, stream);
+  stream->emit_style_escape (ui_file_style ());
 }
 
 /* See utils.h.  */
@@ -1826,9 +1780,9 @@ void
 fputs_styled_unfiltered (const char *linebuffer, const ui_file_style &style,
 			 struct ui_file *stream)
 {
-  set_output_style (stream, style);
-  fputs_maybe_filtered (linebuffer, stream, 0);
-  set_output_style (stream, ui_file_style ());
+  stream->emit_style_escape (style);
+  stream->puts_unfiltered (linebuffer);
+  stream->emit_style_escape (ui_file_style ());
 }
 
 /* See utils.h.  */
@@ -1852,14 +1806,14 @@ fputs_highlighted (const char *str, const compiled_regex &highlight,
 	}
 
       /* Output pmatch with the highlight style.  */
-      set_output_style (stream, highlight_style.style ());
+      stream->emit_style_escape (highlight_style.style ());
       while (n_highlight > 0)
 	{
 	  fputc_filtered (*str, stream);
 	  n_highlight--;
 	  str++;
 	}
-      set_output_style (stream, ui_file_style ());
+      stream->emit_style_escape (ui_file_style ());
     }
 
   /* Output the trailing part of STR not matching HIGHLIGHT.  */
@@ -1915,10 +1869,7 @@ static void
 vfprintf_maybe_filtered (struct ui_file *stream, const char *format,
 			 va_list args, bool filter)
 {
-  ui_out_flags flags = disallow_ui_out_field;
-  if (!filter)
-    flags |= unfiltered_output;
-  cli_ui_out (stream, flags).vmessage (applied_style, format, args);
+  stream->vprintf (format, args);
 }
 
 
@@ -1974,11 +1925,11 @@ fprintf_styled (struct ui_file *stream, const ui_file_style &style,
 {
   va_list args;
 
-  set_output_style (stream, style);
+  stream->emit_style_escape (style);
   va_start (args, format);
   vfprintf_filtered (stream, format, args);
   va_end (args);
-  set_output_style (stream, ui_file_style ());
+  stream->emit_style_escape (ui_file_style ());
 }
 
 /* See utils.h.  */
@@ -1987,9 +1938,9 @@ void
 vfprintf_styled (struct ui_file *stream, const ui_file_style &style,
 		 const char *format, va_list args)
 {
-  set_output_style (stream, style);
+  stream->emit_style_escape (style);
   vfprintf_filtered (stream, format, args);
-  set_output_style (stream, ui_file_style ());
+  stream->emit_style_escape (ui_file_style ());
 }
 
 void
diff --git a/gdb/utils.h b/gdb/utils.h
index 5d8ed670e66..7ec8198b2ff 100644
--- a/gdb/utils.h
+++ b/gdb/utils.h
@@ -305,10 +305,6 @@ extern void fputs_styled_unfiltered (const char *linebuffer,
 extern void fputs_highlighted (const char *str, const compiled_regex &highlight,
 			       struct ui_file *stream);
 
-/* Reset the terminal style to the default, if needed.  */
-
-extern void reset_terminal_style (struct ui_file *stream);
-
 /* Return the address only having significant bits.  */
 extern CORE_ADDR address_significant (gdbarch *gdbarch, CORE_ADDR addr);
 
-- 
2.31.1


  parent reply	other threads:[~2022-01-22  1:38 UTC|newest]

Thread overview: 25+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-01-22  1:37 [PATCH 00/19] Simplify GDB output functions Tom Tromey
2022-01-22  1:37 ` [PATCH 01/19] Use unfiltered output in annotate.c Tom Tromey
2022-01-22  1:37 ` [PATCH 02/19] Remove some uses of printf_unfiltered Tom Tromey
2022-01-22  1:37 ` [PATCH 03/19] Only have one API for unfiltered output Tom Tromey
2022-01-22  1:37 ` [PATCH 04/19] Add puts_unfiltered method to ui_file Tom Tromey
2022-01-22  1:37 ` [PATCH 05/19] Add style-escape methods " Tom Tromey
2022-01-22  1:37 ` [PATCH 06/19] Remove vfprintf_styled_no_gdbfmt Tom Tromey
2022-01-22  1:37 ` Tom Tromey [this message]
2022-01-22  1:37 ` [PATCH 08/19] Remove fputs_styled_unfiltered Tom Tromey
2022-01-22  1:37 ` [PATCH 09/19] Unify vprintf functions Tom Tromey
2022-01-22  1:37 ` [PATCH 10/19] Unify gdb puts functions Tom Tromey
2022-01-22  1:37 ` [PATCH 11/19] Unify gdb putc functions Tom Tromey
2022-01-22  1:37 ` [PATCH 13/19] Rename print_spaces_filtered Tom Tromey
2022-01-22  1:37 ` [PATCH 14/19] Rename puts_filtered_tabular Tom Tromey
2022-01-22  1:37 ` [PATCH 15/19] Rename fprintf_symbol_filtered Tom Tromey
2022-01-22  1:37 ` [PATCH 16/19] Remove ui_out_flag::unfiltered_output Tom Tromey
2022-01-22  1:37 ` [PATCH 17/19] Remove vfprintf_styled Tom Tromey
2022-01-22  1:38 ` [PATCH 18/19] Minor comment updates in utils.h Tom Tromey
2022-03-24 18:05   ` Pedro Alves
2022-03-28 20:29     ` Tom Tromey
2022-01-22  1:38 ` [PATCH 19/19] Remove unnecessary calls to wrap_here and gdb_flush Tom Tromey
2022-01-22 17:40 ` [PATCH 00/19] Simplify GDB output functions John Baldwin
2022-03-24 16:25 ` Tom Tromey
2022-03-24 18:08 ` Pedro Alves
2022-03-29 19:38   ` Tom Tromey

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=20220122013801.666659-8-tom@tromey.com \
    --to=tom@tromey.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).