/* UI_FILE - a generic STDIO like output stream.
   Copyright (C) 1999-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 UI_FILE_H
#define UI_FILE_H

#include <string>
#include "ui-style.h"

/* The abstract ui_file base class.  */

class ui_file
{
public:
  ui_file ();
  virtual ~ui_file () = 0;

  /* Public non-virtual API.  */

  void printf (const char *, ...) ATTRIBUTE_PRINTF (2, 3);

  /* Print a NUL-terminated 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.

     This will normally escape backslashes and instances of QUOTER.
     If QUOTER is 0, it won't escape backslashes or any quoting
     character.  As a side effect, if you pass the backslash character
     as the QUOTER, this will escape backslashes as usual, but not any
     other quoting character.  */
  void putstr (const char *str, int quoter);

  /* Like putstr, but only print the first N characters of STR.  If
     ASYNC_SAFE is true, then the output is done via the
     write_async_safe method.  */
  void putstrn (const char *str, int n, int quoter, bool async_safe = false);

  int putc (int c);

  void vprintf (const char *, va_list) ATTRIBUTE_PRINTF (2, 0);

  /* Methods below are both public, and overridable by ui_file
     subclasses.  */

  virtual void write (const char *buf, long length_buf) = 0;

  /* 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)); }

  virtual long read (char *buf, long length_buf)
  { gdb_assert_not_reached ("can't read from this file type"); }

  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 (); }

  /* true if ANSI escapes can be used on STREAM.  */
  virtual bool can_emit_style_escape ()
  { return false; }

  virtual void flush ()
  {}

  /* If this object has an underlying file descriptor, then return it.
     Otherwise, return -1.  */
  virtual int fd () const
  { return -1; }

  /* Indicate that if the next sequence of characters overflows the
     line, a newline should be inserted here rather than when it hits
     the end.  If INDENT is non-zero, it is a number of spaces to be
     printed to indent the wrapped part on the next line.

     If the line is already overfull, we immediately print a newline and
     the indentation, and disable further wrapping.

     If we don't know the width of lines, but we know the page height,
     we must not wrap words, but should still keep track of newlines
     that were explicitly printed.

     This routine is guaranteed to force out any output which has been
     squirreled away in the wrap_buffer, so wrap_here (0) can be
     used to force out output from the wrap_buffer.  */
  virtual void wrap_here (int indent)
  {
  }

  /* Emit an ANSI style escape for STYLE.  */
  virtual void emit_style_escape (const ui_file_style &style);

  /* Rest the current output style to the empty style.  */
  virtual void reset_style ();

  /* Print STR, bypassing any paging that might be done by this
     ui_file.  Note that nearly no code should call this -- it's
     intended for use by gdb_printf, but nothing else.  */
  virtual void puts_unfiltered (const char *str)
  {
    this->puts (str);
  }

protected:

  /* The currently applied style.  */
  ui_file_style m_applied_style;

private:

  /* Helper function for putstr and putstrn.  Print the character C on
     this stream as part of the contents of a literal string whose
     delimiter is QUOTER.  */
  void printchar (int c, int quoter, bool async_safe);
};

typedef std::unique_ptr<ui_file> ui_file_up;

/* 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;

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;

  /* Override ui_file methods.  */

  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.  */
  const std::string &string () { return m_string; }

  /* Return an std::string containing the entire output collected so far.

     The internal buffer is cleared, such that it's ready to build a new
     string.  */
  std::string release ()
  {
    std::string ret = std::move (m_string);
    m_string.clear ();
    return ret;
  }

  /* Set the internal buffer contents to STR.  Any existing contents are
     discarded.  */
  string_file &operator= (std::string &&str)
  {
    m_string = std::move (str);
    return *this;
  }

  /* 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;

  /* Return the underlying file descriptor.  */
  int fd () const override
  { return m_fd; }

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;

  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
  {
    m_one->reset_style ();
    m_two->reset_style ();
  }

  void puts_unfiltered (const char *str) override
  {
    m_one->puts_unfiltered (str);
    m_two->puts_unfiltered (str);
  }

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;

  void emit_style_escape (const ui_file_style &style) override
  {
  }

  void reset_style () override
  {
  }
};

/* A base class for ui_file types that wrap another ui_file.  */

class wrapped_file : public ui_file
{
public:

  bool isatty () override
  { return m_stream->isatty (); }

  bool term_out () override
  { return m_stream->term_out (); }

  bool can_emit_style_escape () override
  { return m_stream->can_emit_style_escape (); }

  void flush () override
  { m_stream->flush (); }

  void wrap_here (int indent) override
  { m_stream->wrap_here (indent); }

  void emit_style_escape (const ui_file_style &style) override
  { m_stream->emit_style_escape (style); }

  /* Rest the current output style to the empty style.  */
  void reset_style () override
  { m_stream->reset_style (); }

  int fd () const override
  { return m_stream->fd (); }

  void puts_unfiltered (const char *str) override
  { m_stream->puts_unfiltered (str); }

  void write_async_safe (const char *buf, long length_buf) override
  { return m_stream->write_async_safe (buf, length_buf); }

protected:

  /* Note that this class does not assume ownership of the stream.
     However, a subclass may choose to, by adding a 'delete' to its
     destructor.  */
  explicit wrapped_file (ui_file *stream)
    : m_stream (stream)
  {
  }

  /* The underlying stream.  */
  ui_file *m_stream;
};

/* A ui_file that optionally puts a timestamp at the start of each
   line of output.  */

class timestamped_file : public wrapped_file
{
public:
  explicit timestamped_file (ui_file *stream)
    : wrapped_file (stream)
  {
  }

  DISABLE_COPY_AND_ASSIGN (timestamped_file);

  void write (const char *buf, long len) override;

private:

  /* True if the next output should be timestamped.  */
  bool m_needs_timestamp = true;
};

#endif
