gdb: add target_ops::supports_displaced_step
[deliverable/binutils-gdb.git] / gdb / ui-file.h
index 4196524de0602ccef9ef0aa2b74aa4d22c5e40d3..10c7e18344e35e07a6ecddb8adfbd5ddb6f579a3 100644 (file)
@@ -1,5 +1,5 @@
 /* UI_FILE - a generic STDIO like output stream.
-   Copyright (C) 1999-2013 Free Software Foundation, Inc.
+   Copyright (C) 1999-2020 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
 #ifndef UI_FILE_H
 #define UI_FILE_H
 
-struct obstack;
-struct ui_file;
+#include <string>
+#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);
 
-/* 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.
-   fputs_async is not provided as the async versions are rarely used,
-   no point in having both for a rarely used interface.  */
-typedef void (ui_file_write_async_safe_ftype)
-  (struct ui_file *stream, const char *buf, long length_buf);
-extern void set_ui_file_write_async_safe
-  (struct ui_file *stream, ui_file_write_async_safe_ftype *write_async_safe);
+  int putc (int c);
 
-typedef long (ui_file_read_ftype) (struct ui_file *stream,
-                                  char *buf, long length_buf);
-extern void set_ui_file_read (struct ui_file *stream,
-                             ui_file_read_ftype *fread);
+  void vprintf (const char *, va_list) ATTRIBUTE_PRINTF (2, 0);
 
-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);
+  /* Methods below are both public, and overridable by ui_file
+     subclasses.  */
 
-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);
+  virtual void write (const char *buf, long length_buf) = 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);
+  /* 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"); }
 
-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);
+  /* 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)); }
 
-typedef int (ui_file_fseek_ftype) (struct ui_file *stream, long offset,
-                                  int whence);
-extern void set_ui_file_fseek (struct ui_file *stream,
-                              ui_file_fseek_ftype *fseek_ptr);
+  virtual long read (char *buf, long length_buf)
+  { gdb_assert_not_reached ("can't read from this file type"); }
 
-extern void *ui_file_data (struct ui_file *file);
+  virtual bool isatty ()
+  { return false; }
 
+  /* 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 void gdb_flush (struct ui_file *);
+  /* true if ANSI escapes can be used on STREAM.  */
+  virtual bool can_emit_style_escape ()
+  { return false; }
 
-extern void ui_file_delete (struct ui_file *stream);
+  virtual void flush ()
+  {}
+};
 
-extern void ui_file_rewind (struct ui_file *stream);
+typedef std::unique_ptr<ui_file> ui_file_up;
 
-extern int ui_file_isatty (struct ui_file *);
+/* A ui_file that writes to nowhere.  */
 
-extern void ui_file_write (struct ui_file *file, const char *buf,
-                          long length_buf);
+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;
+};
 
-extern void ui_file_write_async_safe (struct ui_file *file, const char *buf,
-                                     long length_buf);
+/* A preallocated null_file stream.  */
+extern null_file null_stream;
 
-/* NOTE: copies left to right.  */
-extern void ui_file_put (struct ui_file *src,
-                        ui_file_put_method_ftype *write, void *dest);
+extern int gdb_console_fputs (const char *, FILE *);
 
-/* Returns a freshly allocated buffer containing the entire contents
-   of FILE (as determined by ui_file_put()) with a NUL character
-   appended.  LENGTH, if not NULL, is set to the size of the buffer
-   minus that appended NUL.  */
-extern char *ui_file_xstrdup (struct ui_file *file, long *length);
+/* A std::string-based ui_file.  Can be used as a scratch buffer for
+   collecting output.  */
 
-/* Similar to ui_file_xstrdup, but return a new string allocated on
-   OBSTACK.  */
-extern char *ui_file_obsavestring (struct ui_file *file,
-                                  struct obstack *obstack, long *length);
+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;
 
-extern long ui_file_read (struct ui_file *file, char *buf, long length_buf);
+  /* Override ui_file methods.  */
 
-extern int ui_file_fseek (struct ui_file *file, long offset, int whence);
+  void write (const char *buf, long length_buf) override;
 
-/* Create/open a memory based file.  Can be used as a scratch buffer
-   for collecting output.  */
-extern struct ui_file *mem_fileopen (void);
+  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.  */
 
-/* Open/create a STDIO based UI_FILE using the already open FILE.  */
-extern struct ui_file *stdio_fileopen (FILE *file);
+  /* Accesses the std::string containing the entire output collected
+     so far.
 
-/* Open NAME returning an STDIO based UI_FILE.  */
-extern struct ui_file *gdb_fopen (char *name, char *mode);
+     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 <stdio.h>'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> stdio_file_up;
+
+/* Like stdio_file, but specifically for stderr.
+
+   This exists because there is no real line-buffering on Windows, see
+   <http://msdn.microsoft.com/en-us/library/86cebhfs%28v=vs.71%29.aspx>
+   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;
+};
 
-/* Create a file which writes to both ONE and TWO.  CLOSE_ONE
-   and CLOSE_TWO indicate whether the original files should be
-   closed when the new file is closed.  */
-extern struct ui_file *tee_file_new (struct ui_file *one,
-                                    int close_one,
-                                    struct ui_file *two,
-                                    int close_two);
 #endif
This page took 0.027942 seconds and 4 git commands to generate.