aboutsummaryrefslogtreecommitdiff
path: root/gdb/pager.h
diff options
context:
space:
mode:
authorTom Tromey <tom@tromey.com>2022-01-01 13:18:17 -0700
committerTom Tromey <tom@tromey.com>2022-03-29 12:46:24 -0600
commit3cd5229387926dbd2fe842328e7d923bbb41322c (patch)
treee04670621d84e85614eef455a8ae5263482a405b /gdb/pager.h
parent0e37c0638c15f7ed9215029d9185498ce2741603 (diff)
downloadgdb-3cd5229387926dbd2fe842328e7d923bbb41322c.zip
gdb-3cd5229387926dbd2fe842328e7d923bbb41322c.tar.gz
gdb-3cd5229387926dbd2fe842328e7d923bbb41322c.tar.bz2
Change the pager to a ui_file
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
Diffstat (limited to 'gdb/pager.h')
-rw-r--r--gdb/pager.h109
1 files changed, 109 insertions, 0 deletions
diff --git a/gdb/pager.h b/gdb/pager.h
new file mode 100644
index 0000000..0151a28
--- /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 */