X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gdb%2Fui-file.h;h=10c7e18344e35e07a6ecddb8adfbd5ddb6f579a3;hb=refs%2Fheads%2Fconcurrent-displaced-stepping-2020-04-01;hp=c805335bc5f90e66c56d30fc8a490e30e5e197c4;hpb=72ec28b8afa357cdde70c612b4e0e9f37a34f8e4;p=deliverable%2Fbinutils-gdb.git
diff --git a/gdb/ui-file.h b/gdb/ui-file.h
index c805335bc5..10c7e18344 100644
--- a/gdb/ui-file.h
+++ b/gdb/ui-file.h
@@ -1,11 +1,11 @@
/* UI_FILE - a generic STDIO like output stream.
- Copyright (C) 1999, 2000 Free Software Foundation, Inc.
+ Copyright (C) 1999-2020 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 2 of the License, or
+ 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,
@@ -14,80 +14,281 @@
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, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA. */
+ along with this program. If not, see . */
#ifndef UI_FILE_H
#define UI_FILE_H
-struct ui_file;
+#include
+#include "ui-style.h"
-/* Create a generic ui_file object with null methods. */
+/* The abstract ui_file base class. */
-extern struct ui_file *ui_file_new (void);
+class ui_file
+{
+public:
+ ui_file ();
+ virtual ~ui_file () = 0;
-/* Override methods used by specific implementations of a UI_FILE
- object. */
+ /* Public non-virtual API. */
-typedef void (ui_file_flush_ftype) (struct ui_file * stream);
-extern void set_ui_file_flush (struct ui_file *stream, ui_file_flush_ftype * flush);
+ void printf (const char *, ...) ATTRIBUTE_PRINTF (2, 3);
-/* NOTE: Both fputs and write methods are available. Default
- implementations that mapping one onto the other are included. */
-typedef void (ui_file_write_ftype) (struct ui_file * stream, const char *buf, long length_buf);
-extern void set_ui_file_write (struct ui_file *stream, ui_file_write_ftype *fputs);
+ /* Print a string whose delimiter is QUOTER. Note that these
+ routines should only be called for printing things which are
+ independent of the language of the program being debugged. */
+ void putstr (const char *str, int quoter);
-typedef void (ui_file_fputs_ftype) (const char *, struct ui_file * stream);
-extern void set_ui_file_fputs (struct ui_file *stream, ui_file_fputs_ftype * fputs);
+ void putstrn (const char *str, int n, int quoter);
-typedef int (ui_file_isatty_ftype) (struct ui_file * stream);
-extern void set_ui_file_isatty (struct ui_file *stream, ui_file_isatty_ftype * isatty);
+ int putc (int c);
-typedef void (ui_file_rewind_ftype) (struct ui_file * stream);
-extern void set_ui_file_rewind (struct ui_file *stream, ui_file_rewind_ftype * rewind);
+ void vprintf (const char *, va_list) ATTRIBUTE_PRINTF (2, 0);
-typedef void (ui_file_put_method_ftype) (void *object, const char *buffer, long length_buffer);
-typedef void (ui_file_put_ftype) (struct ui_file *stream, ui_file_put_method_ftype * method, void *context);
-extern void set_ui_file_put (struct ui_file *stream, ui_file_put_ftype * put);
+ /* Methods below are both public, and overridable by ui_file
+ subclasses. */
-typedef void (ui_file_delete_ftype) (struct ui_file * stream);
-extern void set_ui_file_data (struct ui_file *stream, void *data, ui_file_delete_ftype * delete);
+ virtual void write (const char *buf, long length_buf) = 0;
-extern void *ui_file_data (struct ui_file *file);
+ /* This version of "write" is safe for use in signal handlers. It's
+ not guaranteed that all existing output will have been flushed
+ first. Implementations are also free to ignore some or all of
+ the request. puts_async is not provided as the async versions
+ are rarely used, no point in having both for a rarely used
+ interface. */
+ virtual void write_async_safe (const char *buf, long length_buf)
+ { gdb_assert_not_reached ("write_async_safe"); }
+ /* Some ui_files override this to provide a efficient implementation
+ that avoids a strlen. */
+ virtual void puts (const char *str)
+ { this->write (str, strlen (str)); }
-extern void gdb_flush (struct ui_file *);
+ virtual long read (char *buf, long length_buf)
+ { gdb_assert_not_reached ("can't read from this file type"); }
-extern void ui_file_delete (struct ui_file *stream);
+ virtual bool isatty ()
+ { return false; }
-extern void ui_file_rewind (struct ui_file *stream);
+ /* true indicates terminal output behaviour such as cli_styling.
+ This default implementation indicates to do terminal output
+ behaviour if the UI_FILE is a tty. A derived class can override
+ TERM_OUT to have cli_styling behaviour without being a tty. */
+ virtual bool term_out ()
+ { return isatty (); }
-extern int ui_file_isatty (struct ui_file *);
+ /* true if ANSI escapes can be used on STREAM. */
+ virtual bool can_emit_style_escape ()
+ { return false; }
-extern void ui_file_write (struct ui_file *file, const char *buf, long length_buf);
+ virtual void flush ()
+ {}
+};
-/* NOTE: copies left to right */
-extern void ui_file_put (struct ui_file *src, ui_file_put_method_ftype *write, void *dest);
+typedef std::unique_ptr ui_file_up;
-/* Returns a freshly allocated buffer containing the entire contents
- of FILE (as determined by ui_file_put()) with a NUL character
- appended. LENGTH is set to the size of the buffer minus that
- appended NUL. */
-extern char *ui_file_xstrdup (struct ui_file *file, long *length);
+/* A ui_file that writes to nowhere. */
+class null_file : public ui_file
+{
+public:
+ void write (const char *buf, long length_buf) override;
+ void write_async_safe (const char *buf, long sizeof_buf) override;
+ void puts (const char *str) override;
+};
+/* A preallocated null_file stream. */
+extern null_file null_stream;
-/* Create/open a memory based file. Can be used as a scratch buffer
- for collecting output. */
-extern struct ui_file *mem_fileopen (void);
+extern int gdb_console_fputs (const char *, FILE *);
+/* A std::string-based ui_file. Can be used as a scratch buffer for
+ collecting output. */
+class string_file : public ui_file
+{
+public:
+ /* Construct a string_file to collect 'raw' output, i.e. without
+ 'terminal' behaviour such as cli_styling. */
+ string_file () : m_term_out (false) {};
+ /* If TERM_OUT, construct a string_file with terminal output behaviour
+ such as cli_styling)
+ else collect 'raw' output like the previous constructor. */
+ explicit string_file (bool term_out) : m_term_out (term_out) {};
+ ~string_file () override;
-/* Open/create a an STDIO based UI_FILE using the already open FILE. */
-extern struct ui_file *stdio_fileopen (FILE *file);
+ /* Override ui_file methods. */
-/* Open NAME returning an STDIO based UI_FILE. */
-extern struct ui_file *gdb_fopen (char *name, char *mode);
+ void write (const char *buf, long length_buf) override;
+
+ long read (char *buf, long length_buf) override
+ { gdb_assert_not_reached ("a string_file is not readable"); }
+
+ bool term_out () override;
+ bool can_emit_style_escape () override;
+
+ /* string_file-specific public API. */
+
+ /* Accesses the std::string containing the entire output collected
+ so far.
+
+ Returns a non-const reference so that it's easy to move the
+ string contents out of the string_file. E.g.:
+
+ string_file buf;
+ buf.printf (....);
+ buf.printf (....);
+ return std::move (buf.string ());
+ */
+ std::string &string () { return m_string; }
+
+ /* Provide a few convenience methods with the same API as the
+ underlying std::string. */
+ const char *data () const { return m_string.data (); }
+ const char *c_str () const { return m_string.c_str (); }
+ size_t size () const { return m_string.size (); }
+ bool empty () const { return m_string.empty (); }
+ void clear () { return m_string.clear (); }
+
+private:
+ /* The internal buffer. */
+ std::string m_string;
+
+ bool m_term_out;
+};
+
+/* A ui_file implementation that maps directly onto 's FILE.
+ A stdio_file can either own its underlying file, or not. If it
+ owns the file, then destroying the stdio_file closes the underlying
+ file, otherwise it is left open. */
+
+class stdio_file : public ui_file
+{
+public:
+ /* Create a ui_file from a previously opened FILE. CLOSE_P
+ indicates whether the underlying file should be closed when the
+ stdio_file is destroyed. */
+ explicit stdio_file (FILE *file, bool close_p = false);
+
+ /* Create an stdio_file that is not managing any file yet. Call
+ open to actually open something. */
+ stdio_file ();
+
+ ~stdio_file () override;
+
+ /* Open NAME in mode MODE, and own the resulting file. Returns true
+ on success, false otherwise. If the stdio_file previously owned
+ a file, it is closed. */
+ bool open (const char *name, const char *mode);
+
+ void flush () override;
+
+ void write (const char *buf, long length_buf) override;
+
+ void write_async_safe (const char *buf, long length_buf) override;
+
+ void puts (const char *) override;
+
+ long read (char *buf, long length_buf) override;
+
+ bool isatty () override;
+
+ bool can_emit_style_escape () override;
+
+private:
+ /* Sets the internal stream to FILE, and saves the FILE's file
+ descriptor in M_FD. */
+ void set_stream (FILE *file);
+
+ /* The file. */
+ FILE *m_file;
+
+ /* The associated file descriptor is extracted ahead of time for
+ stdio_file::write_async_safe's benefit, in case fileno isn't
+ async-safe. */
+ int m_fd;
+
+ /* If true, M_FILE is closed on destruction. */
+ bool m_close_p;
+};
+
+typedef std::unique_ptr stdio_file_up;
+
+/* Like stdio_file, but specifically for stderr.
+
+ This exists because there is no real line-buffering on Windows, see
+
+ so the stdout is either fully-buffered or non-buffered. We can't
+ make stdout non-buffered, because of two concerns:
+
+ 1. Non-buffering hurts performance.
+ 2. Non-buffering may change GDB's behavior when it is interacting
+ with a front-end, such as Emacs.
+
+ We leave stdout as fully buffered, but flush it first when
+ something is written to stderr.
+
+ Note that the 'write_async_safe' method is not overridden, because
+ there's no way to flush a stream in an async-safe manner.
+ Fortunately, it doesn't really matter, because:
+
+ 1. That method is only used for printing internal debug output
+ from signal handlers.
+
+ 2. Windows hosts don't have a concept of async-safeness. Signal
+ handlers run in a separate thread, so they can call the regular
+ non-async-safe output routines freely.
+*/
+class stderr_file : public stdio_file
+{
+public:
+ explicit stderr_file (FILE *stream);
+
+ /* Override the output routines to flush gdb_stdout before deferring
+ to stdio_file for the actual outputting. */
+ void write (const char *buf, long length_buf) override;
+ void puts (const char *linebuffer) override;
+};
+
+/* A ui_file implementation that maps onto two ui-file objects. */
+
+class tee_file : public ui_file
+{
+public:
+ /* Create a file which writes to both ONE and TWO. ONE will remain
+ open when this object is destroyed; but TWO will be closed. */
+ tee_file (ui_file *one, ui_file_up &&two);
+ ~tee_file () override;
+
+ void write (const char *buf, long length_buf) override;
+ void write_async_safe (const char *buf, long length_buf) override;
+ void puts (const char *) override;
+
+ bool isatty () override;
+ bool term_out () override;
+ bool can_emit_style_escape () override;
+ void flush () override;
+
+private:
+ /* The two underlying ui_files. */
+ ui_file *m_one;
+ ui_file_up m_two;
+};
+
+/* A ui_file implementation that filters out terminal escape
+ sequences. */
+
+class no_terminal_escape_file : public stdio_file
+{
+public:
+ no_terminal_escape_file ()
+ {
+ }
+
+ /* Like the stdio_file methods, but these filter out terminal escape
+ sequences. */
+ void write (const char *buf, long length_buf) override;
+ void puts (const char *linebuffer) override;
+};
#endif