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

  void 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
